Merge pull request #9000 from kojiws/import_mldsa_seed_pkcs8

Import ML-DSA's seed from PKCS8 file
This commit is contained in:
JacobBarthelmeh
2025-07-29 16:02:36 -06:00
committed by GitHub
26 changed files with 441 additions and 169 deletions

View File

@@ -152,4 +152,5 @@ include certs/dilithium/include.am
include certs/sphincs/include.am include certs/sphincs/include.am
include certs/rpk/include.am include certs/rpk/include.am
include certs/acert/include.am include certs/acert/include.am
include certs/mldsa/include.am

23
certs/mldsa/include.am Normal file
View File

@@ -0,0 +1,23 @@
# vim:ft=automake
# All paths should be given relative to the root
#
EXTRA_DIST += \
certs/mldsa/mldsa44_seed-only.der \
certs/mldsa/mldsa44_priv-only.der \
certs/mldsa/mldsa44_seed-priv.der \
certs/mldsa/mldsa44_oqskeypair.der \
certs/mldsa/mldsa44_bare-seed.der \
certs/mldsa/mldsa44_bare-priv.der \
certs/mldsa/mldsa65_seed-only.der \
certs/mldsa/mldsa65_priv-only.der \
certs/mldsa/mldsa65_seed-priv.der \
certs/mldsa/mldsa65_oqskeypair.der \
certs/mldsa/mldsa65_bare-seed.der \
certs/mldsa/mldsa65_bare-priv.der \
certs/mldsa/mldsa87_seed-only.der \
certs/mldsa/mldsa87_priv-only.der \
certs/mldsa/mldsa87_seed-priv.der \
certs/mldsa/mldsa87_oqskeypair.der \
certs/mldsa/mldsa87_bare-seed.der \
certs/mldsa/mldsa87_bare-priv.der

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3004,8 +3004,13 @@ int test_wc_dilithium_der(void)
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL, ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL,
0 ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); 0 ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , NULL,
0 ), BAD_FUNC_ARG);
#else
ExpectIntGT(wc_Dilithium_PrivateKeyToDer(key , NULL, ExpectIntGT(wc_Dilithium_PrivateKeyToDer(key , NULL,
0 ), 0); 0 ), 0);
#endif
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, der , ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, der ,
0 ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); 0 ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL, ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(NULL, NULL,
@@ -3015,13 +3020,23 @@ int test_wc_dilithium_der(void)
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , der , ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , der ,
0 ), WC_NO_ERR_TRACE(BUFFER_E)); 0 ), WC_NO_ERR_TRACE(BUFFER_E));
/* Get length only. */ /* Get length only. */
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , NULL,
DILITHIUM_MAX_DER_SIZE), BAD_FUNC_ARG);
#else
ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , NULL, ExpectIntEQ(wc_Dilithium_PrivateKeyToDer(key , NULL,
DILITHIUM_MAX_DER_SIZE), privDerLen); DILITHIUM_MAX_DER_SIZE), privDerLen);
#endif
ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, 0 ), ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, 0 ),
WC_NO_ERR_TRACE(BAD_FUNC_ARG)); WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(wc_Dilithium_KeyToDer(key , NULL, 0 ),
BAD_FUNC_ARG);
#else
ExpectIntGT(wc_Dilithium_KeyToDer(key , NULL, 0 ), ExpectIntGT(wc_Dilithium_KeyToDer(key , NULL, 0 ),
0 ); 0 );
#endif
ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, der , 0 ), ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, der , 0 ),
WC_NO_ERR_TRACE(BAD_FUNC_ARG)); WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, DILITHIUM_MAX_DER_SIZE), ExpectIntEQ(wc_Dilithium_KeyToDer(NULL, NULL, DILITHIUM_MAX_DER_SIZE),
@@ -3031,8 +3046,13 @@ int test_wc_dilithium_der(void)
ExpectIntEQ(wc_Dilithium_KeyToDer(key , der , 0 ), ExpectIntEQ(wc_Dilithium_KeyToDer(key , der , 0 ),
WC_NO_ERR_TRACE(BUFFER_E)); WC_NO_ERR_TRACE(BUFFER_E));
/* Get length only. */ /* Get length only. */
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(wc_Dilithium_KeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE),
BAD_FUNC_ARG);
#else
ExpectIntEQ(wc_Dilithium_KeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE), ExpectIntEQ(wc_Dilithium_KeyToDer(key , NULL, DILITHIUM_MAX_DER_SIZE),
keyDerLen); keyDerLen);
#endif
ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, NULL, NULL, 0 ), ExpectIntEQ(wc_Dilithium_PublicKeyDecode(NULL, NULL, NULL, 0 ),
WC_NO_ERR_TRACE(BAD_FUNC_ARG)); WC_NO_ERR_TRACE(BAD_FUNC_ARG));
@@ -3081,15 +3101,25 @@ int test_wc_dilithium_der(void)
idx = 0; idx = 0;
ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der, &idx, key, len), 0); ExpectIntEQ(wc_Dilithium_PublicKeyDecode(der, &idx, key, len), 0);
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(len = wc_Dilithium_PrivateKeyToDer(key, der,
DILITHIUM_MAX_DER_SIZE), BAD_FUNC_ARG);
#else
ExpectIntEQ(len = wc_Dilithium_PrivateKeyToDer(key, der, ExpectIntEQ(len = wc_Dilithium_PrivateKeyToDer(key, der,
DILITHIUM_MAX_DER_SIZE), privDerLen); DILITHIUM_MAX_DER_SIZE), privDerLen);
idx = 0; idx = 0;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0); ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0);
#endif
#ifndef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(len = wc_Dilithium_KeyToDer(key, der, DILITHIUM_MAX_DER_SIZE),
BAD_FUNC_ARG);
#else
ExpectIntEQ(len = wc_Dilithium_KeyToDer(key, der, DILITHIUM_MAX_DER_SIZE), ExpectIntEQ(len = wc_Dilithium_KeyToDer(key, der, DILITHIUM_MAX_DER_SIZE),
keyDerLen); keyDerLen);
idx = 0; idx = 0;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0); ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0);
#endif
wc_dilithium_free(key); wc_dilithium_free(key);
@@ -3097,6 +3127,8 @@ int test_wc_dilithium_der(void)
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
(void)keyDerLen;
#endif #endif
return EXPECT_RESULT(); return EXPECT_RESULT();
} }
@@ -16658,7 +16690,219 @@ int test_wc_dilithium_verify_kats(void)
return EXPECT_RESULT(); return EXPECT_RESULT();
} }
int test_mldsa_pkcs8(void) #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
!defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
static struct {
const char* fileName;
byte level;
/* 0: Unsupported, 1: Supported*/
int p8_lv; /* Support PKCS8 format with specifying level */
int p8_nolv; /* Support PKCS8 format without specifying level */
int trad_lv; /* Support traditional format with specifying level */
int trad_nolv; /* Support traditional format without specifying level */
} ossl_form[] = {
/*
* Generated test files with the following commands:
* openssl genpkey -outform DER -algorithm ${ALGO} \
* -provparam ml-dsa.output_formats=${OUT_FORM} -out ${OUT_FILE}
*/
/* ALGO=ML-DSA-44, OUT_FORM=seed-only, OUT_FILE=mldsa44_seed-only.der */
{"certs/mldsa/mldsa44_seed-only.der", WC_ML_DSA_44, 1, 1, 1, 0},
/* ALGO=ML-DSA-44, OUT_FORM=priv-only, OUT_FILE=mldsa44_priv-only.der */
{"certs/mldsa/mldsa44_priv-only.der", WC_ML_DSA_44, 1, 1, 1, 0},
/* ALGO=ML-DSA-44, OUT_FORM=seed-priv, OUT_FILE=mldsa44_seed-priv.der */
{"certs/mldsa/mldsa44_seed-priv.der", WC_ML_DSA_44, 1, 1, 1, 0},
/* ALGO=ML-DSA-44, OUT_FORM=oqskeypair, OUT_FILE=mldsa44_oqskeypair.der */
{"certs/mldsa/mldsa44_oqskeypair.der", WC_ML_DSA_44, 1, 1, 1, 0},
/* ALGO=ML-DSA-44, OUT_FORM=bare-seed, OUT_FILE=mldsa44_bare-seed.der */
{"certs/mldsa/mldsa44_bare-seed.der", WC_ML_DSA_44, 0, 0, 0, 0},
/* ALGO=ML-DSA-44, OUT_FORM=bare-priv, OUT_FILE=mldsa44_bare-priv.der */
{"certs/mldsa/mldsa44_bare-priv.der", WC_ML_DSA_44, 0, 0, 0, 0},
/* ALGO=ML-DSA-65, OUT_FORM=seed-only, OUT_FILE=mldsa65_seed-only.der */
{"certs/mldsa/mldsa65_seed-only.der", WC_ML_DSA_65, 1, 1, 1, 0},
/* ALGO=ML-DSA-65, OUT_FORM=priv-only, OUT_FILE=mldsa65_priv-only.der */
{"certs/mldsa/mldsa65_priv-only.der", WC_ML_DSA_65, 1, 1, 1, 0},
/* ALGO=ML-DSA-65, OUT_FORM=seed-priv, OUT_FILE=mldsa65_seed-priv.der */
{"certs/mldsa/mldsa65_seed-priv.der", WC_ML_DSA_65, 1, 1, 1, 0},
/* ALGO=ML-DSA-65, OUT_FORM=oqskeypair, OUT_FILE=mldsa65_oqskeypair.der */
{"certs/mldsa/mldsa65_oqskeypair.der", WC_ML_DSA_65, 1, 1, 1, 0},
/* ALGO=ML-DSA-65, OUT_FORM=bare-seed, OUT_FILE=mldsa65_bare-seed.der */
{"certs/mldsa/mldsa65_bare-seed.der", WC_ML_DSA_65, 0, 0, 0, 0},
/* ALGO=ML-DSA-65, OUT_FORM=bare-priv, OUT_FILE=mldsa65_bare-priv.der */
{"certs/mldsa/mldsa65_bare-priv.der", WC_ML_DSA_65, 0, 0, 0, 0},
/* ALGO=ML-DSA-87, OUT_FORM=seed-only, OUT_FILE=mldsa87_seed-only.der */
{"certs/mldsa/mldsa87_seed-only.der", WC_ML_DSA_87, 1, 1, 1, 0},
/* ALGO=ML-DSA-87, OUT_FORM=priv-only, OUT_FILE=mldsa87_priv-only.der */
{"certs/mldsa/mldsa87_priv-only.der", WC_ML_DSA_87, 1, 1, 1, 0},
/* ALGO=ML-DSA-87, OUT_FORM=seed-priv, OUT_FILE=mldsa87_seed-priv.der */
{"certs/mldsa/mldsa87_seed-priv.der", WC_ML_DSA_87, 1, 1, 1, 0},
/* ALGO=ML-DSA-87, OUT_FORM=oqskeypair, OUT_FILE=mldsa87_oqskeypair.der */
{"certs/mldsa/mldsa87_oqskeypair.der", WC_ML_DSA_87, 1, 1, 1, 0},
/* ALGO=ML-DSA-87, OUT_FORM=bare-seed, OUT_FILE=mldsa87_bare-seed.der */
{"certs/mldsa/mldsa87_bare-seed.der", WC_ML_DSA_87, 0, 0, 0, 0},
/* ALGO=ML-DSA-87, OUT_FORM=bare-priv, OUT_FILE=mldsa87_bare-priv.der */
{"certs/mldsa/mldsa87_bare-priv.der", WC_ML_DSA_87, 0, 0, 0, 0}
};
#endif
int test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
!defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
byte* der = NULL;
size_t derMaxSz = ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE;
size_t derSz = 0;
FILE* fp = NULL;
word32 inOutIdx = 0;
word32 inOutIdx2 = 0;
dilithium_key key;
int expect = 0;
int pkeySz = 0;
byte level = 0;
ExpectNotNull(der = (byte*) XMALLOC(derMaxSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
for (size_t i = 0; i < sizeof(ossl_form) / sizeof(ossl_form[0]); ++i) {
ExpectNotNull(fp = XFOPEN(ossl_form[i].fileName, "rb"));
ExpectIntGT(derSz = XFREAD(der, 1, derMaxSz, fp), 0);
ExpectIntEQ(XFCLOSE(fp), 0);
/* Specify a level with PKCS8 format */
XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_dilithium_init(&key), 0);
ExpectIntEQ(wc_dilithium_set_level(&key, ossl_form[i].level), 0);
inOutIdx = 0;
expect = ossl_form[i].p8_lv ? 0 : ASN_PARSE_E;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &inOutIdx, &key,
(word32)derSz), expect);
if (expect == 0) {
ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
ExpectIntEQ(level, ossl_form[i].level);
}
wc_dilithium_free(&key);
/* Not specify a level with PKCS8 format */
XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_dilithium_init(&key), 0);
inOutIdx = 0;
expect = ossl_form[i].p8_nolv ? 0 : ASN_PARSE_E;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &inOutIdx, &key,
(word32)derSz), expect);
if (expect == 0) {
ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
ExpectIntEQ(level, ossl_form[i].level);
}
wc_dilithium_free(&key);
/* Specify a level with traditional format */
XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_dilithium_init(&key), 0);
ExpectIntEQ(wc_dilithium_set_level(&key, ossl_form[i].level), 0);
inOutIdx = 0;
expect = ossl_form[i].trad_lv ? 0 : ASN_PARSE_E;
ExpectIntGT(pkeySz = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
(word32)derSz), 0);
inOutIdx2 = 0;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der + inOutIdx, &inOutIdx2,
&key, (word32)pkeySz), expect);
if (expect == 0) {
ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
ExpectIntEQ(level, ossl_form[i].level);
}
wc_dilithium_free(&key);
/* Not specify a level with traditional format */
XMEMSET(&key, 0, sizeof(key));
ExpectIntEQ(wc_dilithium_init(&key), 0);
inOutIdx = 0;
expect = ossl_form[i].trad_nolv ? 0 : ASN_PARSE_E;
ExpectIntGT(pkeySz = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
(word32)derSz), 0);
inOutIdx2 = 0;
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der + inOutIdx, &inOutIdx2,
&key, (word32)pkeySz), expect);
if (expect == 0) {
ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
ExpectIntEQ(level, ossl_form[i].level);
}
wc_dilithium_free(&key);
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXPECT_RESULT();
}
int test_mldsa_pkcs8_import_OpenSSL_form(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
!defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
byte* der = NULL;
size_t derMaxSz = ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE;
size_t derSz = 0;
WOLFSSL_CTX* ctx = NULL;
FILE* fp = NULL;
#ifdef WOLFSSL_DER_TO_PEM
byte* pem = NULL;
size_t pemMaxSz = ML_DSA_LEVEL5_BOTH_KEY_PEM_SIZE;
size_t pemSz = 0;
#endif /* WOLFSSL_DER_TO_PEM */
int expect = 0;
ExpectNotNull(der = (byte*) XMALLOC(derMaxSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
#ifdef WOLFSSL_DER_TO_PEM
ExpectNotNull(pem = (byte*) XMALLOC(pemMaxSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
#endif /* WOLFSSL_DER_TO_PEM */
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif /* NO_WOLFSSL_SERVER */
for (size_t i = 0; i < sizeof(ossl_form) / sizeof(ossl_form[0]); ++i) {
ExpectNotNull(fp = XFOPEN(ossl_form[i].fileName, "rb"));
ExpectIntGT(derSz = XFREAD(der, 1, derMaxSz, fp), 0);
ExpectIntEQ(XFCLOSE(fp), 0);
/* DER */
expect = ossl_form[i].p8_nolv ? WOLFSSL_SUCCESS : WOLFSSL_BAD_FILE;
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1), expect);
#ifdef WOLFSSL_DER_TO_PEM
/* PEM */
ExpectIntGT(pemSz = wc_DerToPem(der, (word32)derSz, pem,
(word32)pemMaxSz, PKCS8_PRIVATEKEY_TYPE), 0);
expect = ossl_form[i].p8_nolv ? WOLFSSL_SUCCESS : ASN_PARSE_E;
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, pem, pemSz,
WOLFSSL_FILETYPE_PEM), expect);
#endif /* WOLFSSL_DER_TO_PEM */
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#ifdef WOLFSSL_DER_TO_PEM
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* WOLFSSL_DER_TO_PEM */
#endif
return EXPECT_RESULT();
}
int test_mldsa_pkcs8_export_import_wolfSSL_form(void)
{ {
EXPECT_DECLS; EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && \ #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
@@ -16666,7 +16910,7 @@ int test_mldsa_pkcs8(void)
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \ (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \ !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
!defined(WOLFSSL_DILITHIUM_NO_SIGN) && \ !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
!defined(WOLFSSL_DILITHIUM_NO_ASN1) !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
WOLFSSL_CTX* ctx = NULL; WOLFSSL_CTX* ctx = NULL;
size_t i; size_t i;
@@ -16676,10 +16920,8 @@ int test_mldsa_pkcs8(void)
byte* temp = NULL; /* Store PEM or intermediate key */ byte* temp = NULL; /* Store PEM or intermediate key */
word32 derSz = 0; word32 derSz = 0;
word32 pemSz = 0; word32 pemSz = 0;
word32 keySz = 0;
dilithium_key mldsa_key; dilithium_key mldsa_key;
WC_RNG rng; WC_RNG rng;
word32 size;
int ret; int ret;
struct { struct {
@@ -16746,43 +16988,6 @@ int test_mldsa_pkcs8(void)
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz, ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_DER_TO_PEM
ExpectIntGT(pemSz = wc_DerToPem(der, derSz, temp, tempMaxSz,
PKCS8_PRIVATEKEY_TYPE), 0);
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, temp, pemSz,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif /* WOLFSSL_DER_TO_PEM */
}
/* Test private + public key (integrated format) */
for (i = 0; i < sizeof(test_variant) / sizeof(test_variant[0]); ++i) {
ExpectIntEQ(wc_dilithium_set_level(&mldsa_key, test_variant[i].wcId),
0);
ExpectIntEQ(wc_dilithium_make_key(&mldsa_key, &rng), 0);
if (EXPECT_FAIL())
break;
keySz = 0;
temp[0] = 0x04; /* ASN.1 OCTET STRING */
temp[1] = 0x82; /* 2 bytes length field */
temp[2] = (test_variant[i].keySz >> 8) & 0xff; /* MSB of the length */
temp[3] = test_variant[i].keySz & 0xff; /* LSB of the length */
keySz += 4;
size = tempMaxSz - keySz;
ExpectIntEQ(wc_dilithium_export_private(&mldsa_key, temp + keySz,
&size), 0);
keySz += size;
size = tempMaxSz - keySz;
ExpectIntEQ(wc_dilithium_export_public(&mldsa_key, temp + keySz, &size),
0);
keySz += size;
derSz = derMaxSz;
ExpectIntGT(wc_CreatePKCS8Key(der, &derSz, temp, keySz,
test_variant[i].oidSum, NULL, 0), 0);
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_DER_TO_PEM #ifdef WOLFSSL_DER_TO_PEM
ExpectIntGT(pemSz = wc_DerToPem(der, derSz, temp, tempMaxSz, ExpectIntGT(pemSz = wc_DerToPem(der, derSz, temp, tempMaxSz,
PKCS8_PRIVATEKEY_TYPE), 0); PKCS8_PRIVATEKEY_TYPE), 0);

View File

@@ -35,7 +35,9 @@ int test_wc_dilithium_der(void);
int test_wc_dilithium_make_key_from_seed(void); int test_wc_dilithium_make_key_from_seed(void);
int test_wc_dilithium_sig_kats(void); int test_wc_dilithium_sig_kats(void);
int test_wc_dilithium_verify_kats(void); int test_wc_dilithium_verify_kats(void);
int test_mldsa_pkcs8(void); int test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form(void);
int test_mldsa_pkcs8_import_OpenSSL_form(void);
int test_mldsa_pkcs8_export_import_wolfSSL_form(void);
int test_mldsa_pkcs12(void); int test_mldsa_pkcs12(void);
#define TEST_MLDSA_DECLS \ #define TEST_MLDSA_DECLS \
@@ -50,7 +52,9 @@ int test_mldsa_pkcs12(void);
TEST_DECL_GROUP("mldsa", test_wc_dilithium_make_key_from_seed), \ TEST_DECL_GROUP("mldsa", test_wc_dilithium_make_key_from_seed), \
TEST_DECL_GROUP("mldsa", test_wc_dilithium_sig_kats), \ TEST_DECL_GROUP("mldsa", test_wc_dilithium_sig_kats), \
TEST_DECL_GROUP("mldsa", test_wc_dilithium_verify_kats), \ TEST_DECL_GROUP("mldsa", test_wc_dilithium_verify_kats), \
TEST_DECL_GROUP("mldsa", test_mldsa_pkcs8), \ TEST_DECL_GROUP("mldsa", test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form), \
TEST_DECL_GROUP("mldsa", test_mldsa_pkcs8_import_OpenSSL_form), \
TEST_DECL_GROUP("mldsa", test_mldsa_pkcs8_export_import_wolfSSL_form), \
TEST_DECL_GROUP("mldsa", test_mldsa_pkcs12) TEST_DECL_GROUP("mldsa", test_mldsa_pkcs12)
#endif /* WOLFCRYPT_TEST_MLDSA_H */ #endif /* WOLFCRYPT_TEST_MLDSA_H */

View File

@@ -36991,6 +36991,7 @@ int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
/* ASN.1 template for a general asymmetric private key: Ed25519, Ed448, /* ASN.1 template for a general asymmetric private key: Ed25519, Ed448,
* falcon, dilithium, etc. * falcon, dilithium, etc.
* RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING) * RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING)
* Check draft-ietf-lamps-dilithium-certificates of draft RFC also.
*/ */
static const ASNItem privateKeyASN[] = { static const ASNItem privateKeyASN[] = {
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
@@ -37003,7 +37004,11 @@ static const ASNItem privateKeyASN[] = {
/* PKEY */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, /* PKEY */ { 1, ASN_OCTET_STRING, 0, 1, 0 },
/* CurvePrivateKey */ /* CurvePrivateKey */
/* PKEY_CURVEPKEY */ { 2, ASN_OCTET_STRING, 0, 0, 2 }, /* PKEY_CURVEPKEY */ { 2, ASN_OCTET_STRING, 0, 0, 2 },
/* PKEY_MLDSASEQ */ { 2, ASN_SEQUENCE, 1, 0, 2 }, /* PKEY_SEED_ONLY */ { 2, ASN_CONTEXT_SPECIFIC | ASN_PKEY_SEED,
0, 0, 2 },
/* PKEY_BOTH_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 2 },
/* PKEY_BOTH_SEED */ { 3, ASN_OCTET_STRING, 0, 0, 0 },
/* PKEY_BOTH_KEY */ { 3, ASN_OCTET_STRING, 0, 0, 0 },
/* attributes */ /* attributes */
/* ATTRS */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 }, /* ATTRS */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 },
/* publicKey */ /* publicKey */
@@ -37016,7 +37021,10 @@ enum {
PRIVKEYASN_IDX_PKEYALGO_OID, PRIVKEYASN_IDX_PKEYALGO_OID,
PRIVKEYASN_IDX_PKEY, PRIVKEYASN_IDX_PKEY,
PRIVKEYASN_IDX_PKEY_CURVEPKEY, PRIVKEYASN_IDX_PKEY_CURVEPKEY,
PRIVKEYASN_IDX_PKEY_MLDSASEQ, PRIVKEYASN_IDX_PKEY_SEED_ONLY,
PRIVKEYASN_IDX_PKEY_BOTH_SEQ,
PRIVKEYASN_IDX_PKEY_BOTH_SEED,
PRIVKEYASN_IDX_PKEY_BOTH_KEY,
PRIVKEYASN_IDX_ATTRS, PRIVKEYASN_IDX_ATTRS,
PRIVKEYASN_IDX_PUBKEY PRIVKEYASN_IDX_PUBKEY
}; };
@@ -37033,9 +37041,11 @@ enum {
int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz, int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz,
const byte** seed, word32* seedLen,
const byte** privKey, word32* privKeyLen, const byte** privKey, word32* privKeyLen,
const byte** pubKey, word32* pubKeyLen, int* inOutKeyType) const byte** pubKey, word32* pubKeyLen, int* inOutKeyType)
{ {
int allowSeed = 0;
#ifndef WOLFSSL_ASN_TEMPLATE #ifndef WOLFSSL_ASN_TEMPLATE
word32 oid; word32 oid;
int version, length, endKeyIdx, privSz, pubSz; int version, length, endKeyIdx, privSz, pubSz;
@@ -37048,14 +37058,27 @@ int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz,
#endif #endif
if (input == NULL || inOutIdx == NULL || inSz == 0 || if (input == NULL || inOutIdx == NULL || inSz == 0 ||
privKey == NULL || privKeyLen == NULL || inOutKeyType == NULL) { privKey == NULL || privKeyLen == NULL ||
pubKey == NULL || pubKeyLen == NULL ||
inOutKeyType == NULL) {
#ifdef WOLFSSL_ASN_TEMPLATE #ifdef WOLFSSL_ASN_TEMPLATE
FREE_ASNGETDATA(dataASN, NULL); FREE_ASNGETDATA(dataASN, NULL);
#endif #endif
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if ((seed == NULL && seedLen != NULL) ||
(seed != NULL && seedLen == NULL)) {
return BAD_FUNC_ARG;
}
allowSeed = (seed != NULL && seedLen != NULL);
#ifndef WOLFSSL_ASN_TEMPLATE #ifndef WOLFSSL_ASN_TEMPLATE
/* The seed can't be parsed without WOLFSSL_ASN_TEMPLATE */
if (allowSeed) {
return ASN_PARSE_E;
}
if (GetSequence(input, inOutIdx, &length, inSz) >= 0) { if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
endKeyIdx = (int)*inOutIdx + length; endKeyIdx = (int)*inOutIdx + length;
@@ -37083,14 +37106,8 @@ int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz,
return ASN_PARSE_E; return ASN_PARSE_E;
if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) { if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) {
if (oid != ML_DSA_LEVEL2k && oid != ML_DSA_LEVEL3k &&
oid != ML_DSA_LEVEL5k) {
return ASN_PARSE_E; return ASN_PARSE_E;
} }
if (GetSequence(input, inOutIdx, &privSz, inSz) < 0) {
return ASN_PARSE_E;
}
}
priv = input + *inOutIdx; priv = input + *inOutIdx;
*inOutIdx += (word32)privSz; *inOutIdx += (word32)privSz;
@@ -37150,54 +37167,70 @@ int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz,
} }
/* Parse full private key. */ /* Parse full private key. */
ret = GetASN_Items(privateKeyASN, dataASN, privateKeyASN_Length, 1, input, ret = GetASN_Items(privateKeyASN, dataASN, privateKeyASN_Length, 1,
inOutIdx, inSz); input, inOutIdx, inSz);
if (ret != 0) { if (ret == 0) {
/* Parse just the OCTET_STRING. */
ret = GetASN_Items(&privateKeyASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY],
&dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY], 1, 0, input,
inOutIdx, inSz);
if (ret != 0) {
ret = ASN_PARSE_E;
}
}
/* Store detected OID if requested */ /* Store detected OID if requested */
if (ret == 0 && *inOutKeyType == ANONk) { if (ret == 0 && *inOutKeyType == ANONk) {
*inOutKeyType = *inOutKeyType =
(int)dataASN[PRIVKEYASN_IDX_PKEYALGO_OID].data.oid.sum; (int)dataASN[PRIVKEYASN_IDX_PKEYALGO_OID].data.oid.sum;
} }
} }
if (ret == 0 && dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length != 0) { /* Parse traditional format (a part of full private key). */
/* Import private value. */ else if (ret != 0) {
*privKeyLen = dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length; ret = GetASN_Items(&privateKeyASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY],
*privKey = dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data; &dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY],
} PRIVKEYASN_IDX_ATTRS - PRIVKEYASN_IDX_PKEY_CURVEPKEY, 0,
else if (ret == 0 && input, inOutIdx, inSz);
dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.length != 0) { if (ret != 0) {
if (*inOutKeyType != ML_DSA_LEVEL2k &&
*inOutKeyType != ML_DSA_LEVEL3k &&
*inOutKeyType != ML_DSA_LEVEL5k) {
ret = ASN_PARSE_E; ret = ASN_PARSE_E;
} }
}
}
if (ret == 0) {
/* priv-only */
if (dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length != 0) {
if (allowSeed) {
*seedLen = 0;
*seed = NULL;
}
*privKeyLen
= dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
*privKey = dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data;
}
/* seed-only */
else if (allowSeed &&
dataASN[PRIVKEYASN_IDX_PKEY_SEED_ONLY].data.ref.length != 0) {
*seedLen = dataASN[PRIVKEYASN_IDX_PKEY_SEED_ONLY].data.ref.length;
*seed = dataASN[PRIVKEYASN_IDX_PKEY_SEED_ONLY].data.ref.data;
*privKeyLen = 0;
*privKey = NULL;
}
/* seed-priv */
else if (allowSeed &&
dataASN[PRIVKEYASN_IDX_PKEY_BOTH_SEQ].data.ref.length != 0) {
*seedLen = dataASN[PRIVKEYASN_IDX_PKEY_BOTH_SEED].data.ref.length;
*seed = dataASN[PRIVKEYASN_IDX_PKEY_BOTH_SEED].data.ref.data;
*privKeyLen = dataASN[PRIVKEYASN_IDX_PKEY_BOTH_KEY].data.ref.length;
*privKey = dataASN[PRIVKEYASN_IDX_PKEY_BOTH_KEY].data.ref.data;
}
else { else {
/* Import private value. */ ret = ASN_PARSE_E;
*privKeyLen = dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.length;
*privKey = dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.data;
} }
} }
if ((ret == 0) && dataASN[PRIVKEYASN_IDX_PUBKEY].tag == 0) {
/* Set public length to 0 as not seen. */ if (ret == 0) {
if (pubKeyLen != NULL) if (dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.length != 0) {
*pubKeyLen = 0;
}
else if (ret == 0) {
/* Import public value. */ /* Import public value. */
if (pubKeyLen != NULL)
*pubKeyLen = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.length; *pubKeyLen = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.length;
if (pubKey != NULL && pubKeyLen != NULL)
*pubKey = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.data; *pubKey = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.data;
} }
else {
/* Set public length to 0 as not seen. */
*pubKeyLen = 0;
*pubKey = NULL;
}
}
FREE_ASNGETDATA(dataASN, NULL); FREE_ASNGETDATA(dataASN, NULL);
return ret; return ret;
@@ -37219,8 +37252,8 @@ int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
} }
if (ret == 0) { if (ret == 0) {
ret = DecodeAsymKey_Assign(input, inOutIdx, inSz, &privKeyPtr, ret = DecodeAsymKey_Assign(input, inOutIdx, inSz, NULL, NULL,
&privKeyPtrLen, &pubKeyPtr, &pubKeyPtrLen, &keyType); &privKeyPtr, &privKeyPtrLen, &pubKeyPtr, &pubKeyPtrLen, &keyType);
} }
if ((ret == 0) && (privKeyPtrLen > *privKeyLen)) { if ((ret == 0) && (privKeyPtrLen > *privKeyLen)) {
ret = BUFFER_E; ret = BUFFER_E;
@@ -37550,6 +37583,11 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
} }
#ifndef WOLFSSL_ASN_TEMPLATE #ifndef WOLFSSL_ASN_TEMPLATE
if (privKeyLen >= 128 || pubKeyLen >= 128) {
/* privKeyLen and pubKeyLen are assumed to be less than 128 */
return BAD_FUNC_ARG;
}
/* calculate size */ /* calculate size */
if (pubKey) { if (pubKey) {
pubSz = 2 + pubKeyLen; pubSz = 2 + pubKeyLen;
@@ -37606,10 +37644,11 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
oidKeyType); oidKeyType);
/* Leave space for private key. */ /* Leave space for private key. */
SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen); SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen);
/* Don't write ML-DSA specific things. */
SetASNItem_NoOut(dataASN, PRIVKEYASN_IDX_PKEY_SEED_ONLY,
PRIVKEYASN_IDX_ATTRS);
/* Don't write out attributes. */ /* Don't write out attributes. */
dataASN[PRIVKEYASN_IDX_ATTRS].noOut = 1; dataASN[PRIVKEYASN_IDX_ATTRS].noOut = 1;
/* Don't write sequence. */
dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].noOut = 1;
if (pubKey) { if (pubKey) {
/* Leave space for public key. */ /* Leave space for public key. */
SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PUBKEY], NULL, pubKeyLen); SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PUBKEY], NULL, pubKeyLen);

View File

@@ -9659,31 +9659,6 @@ int dilithium_get_oid_sum(dilithium_key* key, int* keyFormat) {
#if defined(WOLFSSL_DILITHIUM_PRIVATE_KEY) #if defined(WOLFSSL_DILITHIUM_PRIVATE_KEY)
/* OCT <seed of 32 bytes> OCT <private key data of more than 256 bytes> */
#define ALT_PRIV_DER_PREFIX (2 + 32 + 4)
/* SEQ [ OCT <seed of 32 bytes> OCT <private key data> ] */
#define ALT_PRIV_DER_PREFIX_SEQ (4 + 2 + 32 + 4)
/* Get the private only key size for the ML-DSA level/parameter id.
*
* @param [in] level Level of the ML-DSA key.
* @return Private key only encoding size for key level on success.
* @return 0 on failure.
*/
static word32 dilithium_get_priv_size(int level)
{
switch (level) {
case WC_ML_DSA_44:
return ML_DSA_LEVEL2_KEY_SIZE;
case WC_ML_DSA_65:
return ML_DSA_LEVEL3_KEY_SIZE;
case WC_ML_DSA_87:
return ML_DSA_LEVEL5_KEY_SIZE;
default:
return 0;
}
}
/* Decode the DER encoded Dilithium key. /* Decode the DER encoded Dilithium key.
* *
* @param [in] input Array holding DER encoded data. * @param [in] input Array holding DER encoded data.
@@ -9708,11 +9683,14 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx,
dilithium_key* key, word32 inSz) dilithium_key* key, word32 inSz)
{ {
int ret = 0; int ret = 0;
const byte* seed = NULL;
const byte* privKey = NULL; const byte* privKey = NULL;
const byte* pubKey = NULL; const byte* pubKey = NULL;
word32 seedLen = 0;
word32 privKeyLen = 0; word32 privKeyLen = 0;
word32 pubKeyLen = 0; word32 pubKeyLen = 0;
int keyType = 0; int keyType = 0;
int autoKeyType = ANONk;
/* Validate parameters. */ /* Validate parameters. */
if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) { if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
@@ -9756,34 +9734,45 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx,
if (ret == 0) { if (ret == 0) {
/* Decode the asymmetric key and get out private and public key data. */ /* Decode the asymmetric key and get out private and public key data. */
#ifndef WOLFSSL_ASN_TEMPLATE
ret = DecodeAsymKey_Assign(input, inOutIdx, inSz, ret = DecodeAsymKey_Assign(input, inOutIdx, inSz,
NULL, NULL,
&privKey, &privKeyLen, &privKey, &privKeyLen,
&pubKey, &pubKeyLen, &keyType); &pubKey, &pubKeyLen, &autoKeyType);
if (ret == 0 #else
#ifdef WOLFSSL_WC_DILITHIUM ret = DecodeAsymKey_Assign(input, inOutIdx, inSz,
&& key->params == NULL &seed, &seedLen,
#endif &privKey, &privKeyLen,
) { &pubKey, &pubKeyLen, &autoKeyType);
#endif /* WOLFSSL_ASN_TEMPLATE */
}
if (ret == 0) {
if (keyType == ANONk && autoKeyType != ANONk) {
/* Set the security level based on the decoded key. */ /* Set the security level based on the decoded key. */
ret = mapOidToSecLevel(keyType); ret = mapOidToSecLevel(autoKeyType);
if (ret > 0) { if (ret > 0) {
ret = wc_dilithium_set_level(key, (byte)ret); ret = wc_dilithium_set_level(key, (byte)ret);
} }
} }
/* If it failed to decode try alternative DER encoding. */ else if (keyType != ANONk && autoKeyType != ANONk) {
else if (ret != 0) { if (keyType == autoKeyType)
word32 levelSize = dilithium_get_priv_size(key->level); ret = 0;
privKey = input + *inOutIdx; else
privKeyLen = inSz - *inOutIdx; ret = ASN_PARSE_E;
}
/* Check for an alternative DER encoding. */ else if (keyType != ANONk && autoKeyType == ANONk) {
if (privKeyLen == ALT_PRIV_DER_PREFIX_SEQ + levelSize) {
privKey += ALT_PRIV_DER_PREFIX_SEQ;
privKeyLen -= ALT_PRIV_DER_PREFIX_SEQ;
ret = 0; ret = 0;
} }
else { /* keyType == ANONk && autoKeyType == ANONk */
/*
* When decoding traditional format with not specifying a level will
* cause this error.
*/
ret = ASN_PARSE_E;
} }
} }
if ((ret == 0) && (pubKey == NULL) && (pubKeyLen == 0)) { if ((ret == 0) && (pubKey == NULL) && (pubKeyLen == 0)) {
/* Check if the public key is included in the private key. */ /* Check if the public key is included in the private key. */
#if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT) #if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT)
@@ -9828,32 +9817,39 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx,
pubKeyLen = ML_DSA_LEVEL5_PUB_KEY_SIZE; pubKeyLen = ML_DSA_LEVEL5_PUB_KEY_SIZE;
privKeyLen -= ML_DSA_LEVEL5_PUB_KEY_SIZE; privKeyLen -= ML_DSA_LEVEL5_PUB_KEY_SIZE;
} }
else {
word32 levelSize = dilithium_get_priv_size(key->level);
if (privKeyLen == ALT_PRIV_DER_PREFIX + levelSize) {
privKey += ALT_PRIV_DER_PREFIX;
privKeyLen -= ALT_PRIV_DER_PREFIX;
}
}
} }
if (ret == 0) { if (ret == 0) {
/* Check whether public key data was found. */ /* Generate a key pair if seed exists and decoded key pair is ignored */
#if defined(WOLFSSL_DILITHIUM_PUBLIC_KEY) if (seedLen != 0) {
if (pubKeyLen == 0) #if defined(WOLFSSL_WC_DILITHIUM)
if (seedLen == DILITHIUM_SEED_SZ) {
ret = wc_dilithium_make_key_from_seed(key, seed);
}
else {
ret = ASN_PARSE_E;
}
#else
ret = NOT_COMPILED_IN;
#endif #endif
{
/* No public key data, only import private key data. */
ret = wc_dilithium_import_private(privKey, privKeyLen, key);
} }
#if defined(WOLFSSL_DILITHIUM_PUBLIC_KEY) #if defined(WOLFSSL_DILITHIUM_PUBLIC_KEY)
else { /* Check whether public key data was found. */
else if (pubKeyLen != 0 && privKeyLen != 0) {
/* Import private and public key data. */ /* Import private and public key data. */
ret = wc_dilithium_import_key(privKey, privKeyLen, pubKey, ret = wc_dilithium_import_key(privKey, privKeyLen, pubKey,
pubKeyLen, key); pubKeyLen, key);
} }
#endif #endif
else if (pubKeyLen == 0 && privKeyLen != 0)
{
/* No public key data, only import private key data. */
ret = wc_dilithium_import_private(privKey, privKeyLen, key);
}
else {
/* Not a problem of ASN.1 structure, but the contents is invalid */
ret = ASN_PARSE_E;
}
} }
(void)pubKey; (void)pubKey;

View File

@@ -46932,7 +46932,7 @@ static wc_test_ret_t test_dilithium_decode_level(const byte* rawKey,
int isPublicOnlyKey) int isPublicOnlyKey)
{ {
int ret = 0; int ret = 0;
#ifndef WOLFSSL_DILITHIUM_NO_ASN1 #if !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
/* Size the buffer to accommodate the largest encoded key size */ /* Size the buffer to accommodate the largest encoded key size */
const word32 maxDerSz = DILITHIUM_MAX_PRV_KEY_DER_SIZE; const word32 maxDerSz = DILITHIUM_MAX_PRV_KEY_DER_SIZE;
word32 derSz; word32 derSz;
@@ -46982,7 +46982,7 @@ static wc_test_ret_t test_dilithium_decode_level(const byte* rawKey,
#endif #endif
} }
#ifndef WOLFSSL_DILITHIUM_NO_ASN1 #if !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
/* Export raw key as DER */ /* Export raw key as DER */
if (ret == 0) { if (ret == 0) {
#ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY #ifdef WOLFSSL_DILITHIUM_PUBLIC_KEY
@@ -47056,7 +47056,7 @@ static wc_test_ret_t test_dilithium_decode_level(const byte* rawKey,
ret = WC_TEST_RET_ENC_NC; ret = WC_TEST_RET_ENC_NC;
} }
#endif /* !WOLFSSL_DILITHIUM_FIPS204_DRAFT */ #endif /* !WOLFSSL_DILITHIUM_FIPS204_DRAFT */
#endif /* WOLFSSL_DILITHIUM_NO_ASN1 */ #endif /* !WOLFSSL_DILITHIUM_NO_ASN1 && WOLFSSL_ASN_TEMPLATE */
/* Cleanup */ /* Cleanup */
wc_dilithium_free(key); wc_dilithium_free(key);

View File

@@ -204,7 +204,10 @@ enum ASN_Tags {
/* OneAsymmetricKey Fields */ /* OneAsymmetricKey Fields */
ASN_ASYMKEY_ATTRS = 0x00, ASN_ASYMKEY_ATTRS = 0x00,
ASN_ASYMKEY_PUBKEY = 0x01 ASN_ASYMKEY_PUBKEY = 0x01,
/* PKEY Fields */
ASN_PKEY_SEED = 0x00
}; };
/* NOTE: If ASN_UTC_TIME_SIZE or ASN_GENERALIZED_TIME_SIZE are ever modified /* NOTE: If ASN_UTC_TIME_SIZE or ASN_GENERALIZED_TIME_SIZE are ever modified
@@ -2727,8 +2730,9 @@ WOLFSSL_LOCAL int VerifyX509Acert(const byte* cert, word32 certSz,
|| (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \ || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
|| defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS)) || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS))
WOLFSSL_LOCAL int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, WOLFSSL_LOCAL int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx,
word32 inSz, const byte** privKey, word32* privKeyLen, const byte** pubKey, word32 inSz, const byte** seed, word32* seedLen, const byte** privKey,
word32* pubKeyLen, int* inOutKeyType); word32* privKeyLen, const byte** pubKey, word32* pubKeyLen,
int* inOutKeyType);
WOLFSSL_LOCAL int DecodeAsymKey(const byte* input, word32* inOutIdx, WOLFSSL_LOCAL int DecodeAsymKey(const byte* input, word32* inOutIdx,
word32 inSz, byte* privKey, word32* privKeyLen, byte* pubKey, word32 inSz, byte* privKey, word32* privKeyLen, byte* pubKey,