@@ -16658,219 +16658,7 @@ int test_wc_dilithium_verify_kats(void)
1665816658 return EXPECT_RESULT();
1665916659}
1666016660
16661- #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
16662- defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
16663- !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
16664- static struct {
16665- const char* fileName;
16666- byte level;
16667- /* 0: Unsupported, 1: Supported*/
16668- int p8_lv; /* Support PKCS8 format with specifying level */
16669- int p8_nolv; /* Support PKCS8 format without specifying level */
16670- int trad_lv; /* Support traditional format with specifying level */
16671- int trad_nolv; /* Support traditional format without specifying level */
16672- } ossl_form[] = {
16673- /*
16674- * Generated test files with the following commands:
16675- * openssl genpkey -outform DER -algorithm ${ALGO} \
16676- * -provparam ml-dsa.output_formats=${OUT_FORM} -out ${OUT_FILE}
16677- */
16678-
16679- /* ALGO=ML-DSA-44, OUT_FORM=seed-only, OUT_FILE=mldsa44_seed-only.der */
16680- {"certs/mldsa/mldsa44_seed-only.der", WC_ML_DSA_44, 1, 1, 1, 0},
16681- /* ALGO=ML-DSA-44, OUT_FORM=priv-only, OUT_FILE=mldsa44_priv-only.der */
16682- {"certs/mldsa/mldsa44_priv-only.der", WC_ML_DSA_44, 1, 1, 1, 0},
16683- /* ALGO=ML-DSA-44, OUT_FORM=seed-priv, OUT_FILE=mldsa44_seed-priv.der */
16684- {"certs/mldsa/mldsa44_seed-priv.der", WC_ML_DSA_44, 1, 1, 1, 0},
16685- /* ALGO=ML-DSA-44, OUT_FORM=oqskeypair, OUT_FILE=mldsa44_oqskeypair.der */
16686- {"certs/mldsa/mldsa44_oqskeypair.der", WC_ML_DSA_44, 1, 1, 1, 0},
16687- /* ALGO=ML-DSA-44, OUT_FORM=bare-seed, OUT_FILE=mldsa44_bare-seed.der */
16688- {"certs/mldsa/mldsa44_bare-seed.der", WC_ML_DSA_44, 0, 0, 0, 0},
16689- /* ALGO=ML-DSA-44, OUT_FORM=bare-priv, OUT_FILE=mldsa44_bare-priv.der */
16690- {"certs/mldsa/mldsa44_bare-priv.der", WC_ML_DSA_44, 0, 0, 0, 0},
16691- /* ALGO=ML-DSA-65, OUT_FORM=seed-only, OUT_FILE=mldsa65_seed-only.der */
16692- {"certs/mldsa/mldsa65_seed-only.der", WC_ML_DSA_65, 1, 1, 1, 0},
16693- /* ALGO=ML-DSA-65, OUT_FORM=priv-only, OUT_FILE=mldsa65_priv-only.der */
16694- {"certs/mldsa/mldsa65_priv-only.der", WC_ML_DSA_65, 1, 1, 1, 0},
16695- /* ALGO=ML-DSA-65, OUT_FORM=seed-priv, OUT_FILE=mldsa65_seed-priv.der */
16696- {"certs/mldsa/mldsa65_seed-priv.der", WC_ML_DSA_65, 1, 1, 1, 0},
16697- /* ALGO=ML-DSA-65, OUT_FORM=oqskeypair, OUT_FILE=mldsa65_oqskeypair.der */
16698- {"certs/mldsa/mldsa65_oqskeypair.der", WC_ML_DSA_65, 1, 1, 1, 0},
16699- /* ALGO=ML-DSA-65, OUT_FORM=bare-seed, OUT_FILE=mldsa65_bare-seed.der */
16700- {"certs/mldsa/mldsa65_bare-seed.der", WC_ML_DSA_65, 0, 0, 0, 0},
16701- /* ALGO=ML-DSA-65, OUT_FORM=bare-priv, OUT_FILE=mldsa65_bare-priv.der */
16702- {"certs/mldsa/mldsa65_bare-priv.der", WC_ML_DSA_65, 0, 0, 0, 0},
16703- /* ALGO=ML-DSA-87, OUT_FORM=seed-only, OUT_FILE=mldsa87_seed-only.der */
16704- {"certs/mldsa/mldsa87_seed-only.der", WC_ML_DSA_87, 1, 1, 1, 0},
16705- /* ALGO=ML-DSA-87, OUT_FORM=priv-only, OUT_FILE=mldsa87_priv-only.der */
16706- {"certs/mldsa/mldsa87_priv-only.der", WC_ML_DSA_87, 1, 1, 1, 0},
16707- /* ALGO=ML-DSA-87, OUT_FORM=seed-priv, OUT_FILE=mldsa87_seed-priv.der */
16708- {"certs/mldsa/mldsa87_seed-priv.der", WC_ML_DSA_87, 1, 1, 1, 0},
16709- /* ALGO=ML-DSA-87, OUT_FORM=oqskeypair, OUT_FILE=mldsa87_oqskeypair.der */
16710- {"certs/mldsa/mldsa87_oqskeypair.der", WC_ML_DSA_87, 1, 1, 1, 0},
16711- /* ALGO=ML-DSA-87, OUT_FORM=bare-seed, OUT_FILE=mldsa87_bare-seed.der */
16712- {"certs/mldsa/mldsa87_bare-seed.der", WC_ML_DSA_87, 0, 0, 0, 0},
16713- /* ALGO=ML-DSA-87, OUT_FORM=bare-priv, OUT_FILE=mldsa87_bare-priv.der */
16714- {"certs/mldsa/mldsa87_bare-priv.der", WC_ML_DSA_87, 0, 0, 0, 0}
16715- };
16716- #endif
16717-
16718- int test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form(void)
16719- {
16720- EXPECT_DECLS;
16721-
16722- #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
16723- defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
16724- !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE)
16725-
16726- byte* der = NULL;
16727- size_t derMaxSz = ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE;
16728- size_t derSz = 0;
16729- FILE* fp = NULL;
16730- word32 inOutIdx = 0;
16731- word32 inOutIdx2 = 0;
16732- dilithium_key key;
16733- int expect = 0;
16734- int pkeySz = 0;
16735- byte level = 0;
16736-
16737- ExpectNotNull(der = (byte*) XMALLOC(derMaxSz, NULL,
16738- DYNAMIC_TYPE_TMP_BUFFER));
16739-
16740- for (size_t i = 0; i < sizeof(ossl_form) / sizeof(ossl_form[0]); ++i) {
16741- ExpectNotNull(fp = XFOPEN(ossl_form[i].fileName, "rb"));
16742- ExpectIntGT(derSz = XFREAD(der, 1, derMaxSz, fp), 0);
16743- ExpectIntEQ(XFCLOSE(fp), 0);
16744-
16745- /* Specify a level with PKCS8 format */
16746- XMEMSET(&key, 0, sizeof(key));
16747- ExpectIntEQ(wc_dilithium_init(&key), 0);
16748- ExpectIntEQ(wc_dilithium_set_level(&key, ossl_form[i].level), 0);
16749- inOutIdx = 0;
16750- expect = ossl_form[i].p8_lv ? 0 : ASN_PARSE_E;
16751- ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &inOutIdx, &key,
16752- (word32)derSz), expect);
16753- if (expect == 0) {
16754- ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
16755- ExpectIntEQ(level, ossl_form[i].level);
16756- }
16757- wc_dilithium_free(&key);
16758-
16759- /* Not specify a level with PKCS8 format */
16760- XMEMSET(&key, 0, sizeof(key));
16761- ExpectIntEQ(wc_dilithium_init(&key), 0);
16762- inOutIdx = 0;
16763- expect = ossl_form[i].p8_nolv ? 0 : ASN_PARSE_E;
16764- ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &inOutIdx, &key,
16765- (word32)derSz), expect);
16766- if (expect == 0) {
16767- ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
16768- ExpectIntEQ(level, ossl_form[i].level);
16769- }
16770- wc_dilithium_free(&key);
16771-
16772- /* Specify a level with traditional format */
16773- XMEMSET(&key, 0, sizeof(key));
16774- ExpectIntEQ(wc_dilithium_init(&key), 0);
16775- ExpectIntEQ(wc_dilithium_set_level(&key, ossl_form[i].level), 0);
16776- inOutIdx = 0;
16777- expect = ossl_form[i].trad_lv ? 0 : ASN_PARSE_E;
16778- ExpectIntGT(pkeySz = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
16779- (word32)derSz), 0);
16780- inOutIdx2 = 0;
16781- ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der + inOutIdx, &inOutIdx2,
16782- &key, (word32)pkeySz), expect);
16783- if (expect == 0) {
16784- ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
16785- ExpectIntEQ(level, ossl_form[i].level);
16786- }
16787- wc_dilithium_free(&key);
16788-
16789- /* Not specify a level with traditional format */
16790- XMEMSET(&key, 0, sizeof(key));
16791- ExpectIntEQ(wc_dilithium_init(&key), 0);
16792- inOutIdx = 0;
16793- expect = ossl_form[i].trad_nolv ? 0 : ASN_PARSE_E;
16794- ExpectIntGT(pkeySz = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
16795- (word32)derSz), 0);
16796- inOutIdx2 = 0;
16797- ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der + inOutIdx, &inOutIdx2,
16798- &key, (word32)pkeySz), expect);
16799- if (expect == 0) {
16800- ExpectIntEQ(wc_dilithium_get_level(&key, &level), 0);
16801- ExpectIntEQ(level, ossl_form[i].level);
16802- }
16803- wc_dilithium_free(&key);
16804- }
16805-
16806- XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16807- #endif
16808- return EXPECT_RESULT();
16809- }
16810-
16811- int test_mldsa_pkcs8_import_OpenSSL_form(void)
16812- {
16813- EXPECT_DECLS;
16814- #if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
16815- defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
16816- !defined(WOLFSSL_DILITHIUM_NO_ASN1) && defined(WOLFSSL_ASN_TEMPLATE) && \
16817- !defined(NO_TLS) && \
16818- (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
16819-
16820- byte* der = NULL;
16821- size_t derMaxSz = ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE;
16822- size_t derSz = 0;
16823- WOLFSSL_CTX* ctx = NULL;
16824- FILE* fp = NULL;
16825- #ifdef WOLFSSL_DER_TO_PEM
16826- byte* pem = NULL;
16827- size_t pemMaxSz = ML_DSA_LEVEL5_BOTH_KEY_PEM_SIZE;
16828- size_t pemSz = 0;
16829- #endif /* WOLFSSL_DER_TO_PEM */
16830- int expect = 0;
16831-
16832- ExpectNotNull(der = (byte*) XMALLOC(derMaxSz, NULL,
16833- DYNAMIC_TYPE_TMP_BUFFER));
16834- #ifdef WOLFSSL_DER_TO_PEM
16835- ExpectNotNull(pem = (byte*) XMALLOC(pemMaxSz, NULL,
16836- DYNAMIC_TYPE_TMP_BUFFER));
16837- #endif /* WOLFSSL_DER_TO_PEM */
16838-
16839- #ifndef NO_WOLFSSL_SERVER
16840- ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
16841- #else
16842- ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
16843- #endif /* NO_WOLFSSL_SERVER */
16844-
16845- for (size_t i = 0; i < sizeof(ossl_form) / sizeof(ossl_form[0]); ++i) {
16846- ExpectNotNull(fp = XFOPEN(ossl_form[i].fileName, "rb"));
16847- ExpectIntGT(derSz = XFREAD(der, 1, derMaxSz, fp), 0);
16848- ExpectIntEQ(XFCLOSE(fp), 0);
16849-
16850- /* DER */
16851- expect = ossl_form[i].p8_nolv ? WOLFSSL_SUCCESS : WOLFSSL_BAD_FILE;
16852- ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
16853- WOLFSSL_FILETYPE_ASN1), expect);
16854-
16855- #ifdef WOLFSSL_DER_TO_PEM
16856- /* PEM */
16857- ExpectIntGT(pemSz = wc_DerToPem(der, (word32)derSz, pem,
16858- (word32)pemMaxSz, PKCS8_PRIVATEKEY_TYPE), 0);
16859- expect = ossl_form[i].p8_nolv ? WOLFSSL_SUCCESS : ASN_PARSE_E;
16860- ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, pem, pemSz,
16861- WOLFSSL_FILETYPE_PEM), expect);
16862- #endif /* WOLFSSL_DER_TO_PEM */
16863- }
16864-
16865- XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16866- #ifdef WOLFSSL_DER_TO_PEM
16867- XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16868- #endif /* WOLFSSL_DER_TO_PEM */
16869- #endif
16870- return EXPECT_RESULT();
16871- }
16872-
16873- int test_mldsa_pkcs8_export_import_wolfSSL_form(void)
16661+ int test_mldsa_pkcs8(void)
1687416662{
1687516663 EXPECT_DECLS;
1687616664#if !defined(NO_ASN) && defined(HAVE_PKCS8) && \
@@ -16888,8 +16676,10 @@ int test_mldsa_pkcs8_export_import_wolfSSL_form(void)
1688816676 byte* temp = NULL; /* Store PEM or intermediate key */
1688916677 word32 derSz = 0;
1689016678 word32 pemSz = 0;
16679+ word32 keySz = 0;
1689116680 dilithium_key mldsa_key;
1689216681 WC_RNG rng;
16682+ word32 size;
1689316683 int ret;
1689416684
1689516685 struct {
@@ -16956,6 +16746,43 @@ int test_mldsa_pkcs8_export_import_wolfSSL_form(void)
1695616746 ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
1695716747 WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
1695816748
16749+ #ifdef WOLFSSL_DER_TO_PEM
16750+ ExpectIntGT(pemSz = wc_DerToPem(der, derSz, temp, tempMaxSz,
16751+ PKCS8_PRIVATEKEY_TYPE), 0);
16752+ ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, temp, pemSz,
16753+ WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
16754+ #endif /* WOLFSSL_DER_TO_PEM */
16755+ }
16756+
16757+ /* Test private + public key (integrated format) */
16758+ for (i = 0; i < sizeof(test_variant) / sizeof(test_variant[0]); ++i) {
16759+ ExpectIntEQ(wc_dilithium_set_level(&mldsa_key, test_variant[i].wcId),
16760+ 0);
16761+ ExpectIntEQ(wc_dilithium_make_key(&mldsa_key, &rng), 0);
16762+
16763+ if (EXPECT_FAIL())
16764+ break;
16765+
16766+ keySz = 0;
16767+ temp[0] = 0x04; /* ASN.1 OCTET STRING */
16768+ temp[1] = 0x82; /* 2 bytes length field */
16769+ temp[2] = (test_variant[i].keySz >> 8) & 0xff; /* MSB of the length */
16770+ temp[3] = test_variant[i].keySz & 0xff; /* LSB of the length */
16771+ keySz += 4;
16772+ size = tempMaxSz - keySz;
16773+ ExpectIntEQ(wc_dilithium_export_private(&mldsa_key, temp + keySz,
16774+ &size), 0);
16775+ keySz += size;
16776+ size = tempMaxSz - keySz;
16777+ ExpectIntEQ(wc_dilithium_export_public(&mldsa_key, temp + keySz, &size),
16778+ 0);
16779+ keySz += size;
16780+ derSz = derMaxSz;
16781+ ExpectIntGT(wc_CreatePKCS8Key(der, &derSz, temp, keySz,
16782+ test_variant[i].oidSum, NULL, 0), 0);
16783+ ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
16784+ WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
16785+
1695916786#ifdef WOLFSSL_DER_TO_PEM
1696016787 ExpectIntGT(pemSz = wc_DerToPem(der, derSz, temp, tempMaxSz,
1696116788 PKCS8_PRIVATEKEY_TYPE), 0);
0 commit comments