@@ -152,36 +152,66 @@ int crypto_import_key_pair
152152#ifdef WITH_EDDSA
153153 EVP_PKEY* eddsa = NULL ;
154154#endif
155+ #ifdef WITH_ML_DSA
156+ EVP_PKEY* mldsa = NULL ;
157+ #endif
155158
156- switch (EVP_PKEY_type (EVP_PKEY_id (pkey)))
159+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
160+ int keyType = EVP_PKEY_get_id (pkey);
161+ if (keyType != EVP_PKEY_KEYMGMT)
157162 {
158- case EVP_PKEY_RSA:
159- case EVP_PKEY_RSA_PSS:
160- rsa = EVP_PKEY_get1_RSA (pkey);
161- break ;
162- case EVP_PKEY_DSA:
163- dsa = EVP_PKEY_get1_DSA (pkey);
164- break ;
165- #ifdef WITH_ECC
166- case EVP_PKEY_EC:
167- ecdsa = EVP_PKEY_get1_EC_KEY (pkey);
168- break ;
163+ switch (keyType)
164+ #else
165+ switch (EVP_PKEY_type (EVP_PKEY_id (pkey)))
169166#endif
170- #ifdef WITH_EDDSA
171- case NID_X25519:
172- case NID_ED25519:
173- case NID_X448:
174- case NID_ED448:
167+
168+ {
169+ case EVP_PKEY_RSA:
170+ case EVP_PKEY_RSA_PSS:
171+ rsa = EVP_PKEY_get1_RSA (pkey);
172+ break ;
173+ case EVP_PKEY_DSA:
174+ dsa = EVP_PKEY_get1_DSA (pkey);
175+ break ;
176+ #ifdef WITH_ECC
177+ case EVP_PKEY_EC:
178+ ecdsa = EVP_PKEY_get1_EC_KEY (pkey);
179+ break ;
180+ #endif
181+ #ifdef WITH_EDDSA
182+ case NID_X25519:
183+ case NID_ED25519:
184+ case NID_X448:
185+ case NID_ED448:
186+ EVP_PKEY_up_ref (pkey);
187+ eddsa = pkey;
188+ break ;
189+ #endif
190+ default :
191+ fprintf (stderr, " ERROR: Cannot handle this algorithm.\n " );
192+ EVP_PKEY_free (pkey);
193+ return 1 ;
194+ break ;
195+ }
196+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
197+ } else {
198+ // Provider Keys management
199+ #ifdef WITH_ML_DSA
200+ size_t len;
201+ int rv = (EVP_PKEY_is_a (pkey, " ML-DSA-44" ) ||
202+ EVP_PKEY_is_a (pkey, " ML-DSA-65" ) ||
203+ EVP_PKEY_is_a (pkey, " ML-DSA-87" ));
204+ if (!rv) {
205+ fprintf (stderr, " ERROR: Cannot handle this algorithm, rv: %d\n " , rv);
206+ EVP_PKEY_free (pkey);
207+ return 1 ;
208+ }
175209 EVP_PKEY_up_ref (pkey);
176- eddsa = pkey;
177- break ;
178- #endif
179- default :
180- fprintf (stderr, " ERROR: Cannot handle this algorithm.\n " );
181- EVP_PKEY_free (pkey);
182- return 1 ;
183- break ;
210+ mldsa = pkey;
211+ #endif
212+
184213 }
214+ #endif
185215 EVP_PKEY_free (pkey);
186216
187217 int result = 0 ;
@@ -209,6 +239,13 @@ int crypto_import_key_pair
209239 result = crypto_save_eddsa (hSession, label, objID, objIDLen, noPublicKey, eddsa);
210240 EVP_PKEY_free (eddsa);
211241 }
242+ #endif
243+ #ifdef WITH_ML_DSA
244+ else if (mldsa)
245+ {
246+ result = crypto_save_mldsa (hSession, label, objID, objIDLen, noPublicKey, mldsa);
247+ EVP_PKEY_free (mldsa);
248+ }
212249#endif
213250 else
214251 {
@@ -348,7 +385,7 @@ int crypto_import_certificate
348385 }
349386 }
350387
351- printf (" The certificate has been imported.\n " );
388+ printf (" The certificate with label=%s has been imported.\n " , label );
352389
353390 ret = 0 ;
354391
@@ -505,7 +542,7 @@ int crypto_save_rsa
505542 return 1 ;
506543 }
507544
508- printf (" The key pair has been imported.\n " );
545+ printf (" The RSA key pair with label=%s has been imported.\n " , label );
509546
510547 return 0 ;
511548}
@@ -674,7 +711,7 @@ int crypto_save_dsa
674711 return 1 ;
675712 }
676713
677- printf (" The key pair has been imported.\n " );
714+ printf (" The DSA key pair with label=%s has been imported.\n " , label );
678715
679716 return 0 ;
680717}
@@ -815,7 +852,7 @@ int crypto_save_ecdsa
815852 return 1 ;
816853 }
817854
818- printf (" The key pair has been imported.\n " );
855+ printf (" The ECDSA key pair with label=%s has been imported.\n " , label );
819856
820857 return 0 ;
821858}
@@ -1032,7 +1069,7 @@ int crypto_save_eddsa
10321069 return 1 ;
10331070 }
10341071
1035- printf (" The key pair has been imported.\n " );
1072+ printf (" The EDDSA key pair with label=%s has been imported.\n " , label );
10361073
10371074 return 0 ;
10381075}
@@ -1139,3 +1176,211 @@ void crypto_free_eddsa(eddsa_key_material_t* keyMat)
11391176}
11401177
11411178#endif
1179+
1180+ #ifdef WITH_ML_DSA
1181+
1182+ // Save the key data in PKCS#11
1183+ int crypto_save_mldsa
1184+ (
1185+ CK_SESSION_HANDLE hSession,
1186+ char * label,
1187+ char * objID,
1188+ size_t objIDLen,
1189+ int noPublicKey,
1190+ EVP_PKEY* mldsa
1191+ )
1192+ {
1193+ mldsa_key_material_t * keyMat = crypto_malloc_mldsa (mldsa);
1194+ if (keyMat == NULL )
1195+ {
1196+ fprintf (stderr, " ERROR: Could not convert the key material to binary information.\n " );
1197+ return 1 ;
1198+ }
1199+
1200+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY, privClass = CKO_PRIVATE_KEY;
1201+ CK_KEY_TYPE keyType = CKK_ML_DSA;
1202+ CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE;
1203+ if (noPublicKey)
1204+ {
1205+ ckToken = CK_FALSE;
1206+ }
1207+ CK_ATTRIBUTE pubTemplate[] = {
1208+ { CKA_CLASS, &pubClass, sizeof (pubClass) },
1209+ { CKA_KEY_TYPE, &keyType, sizeof (keyType) },
1210+ { CKA_LABEL, label, strlen (label) },
1211+ { CKA_ID, objID, objIDLen },
1212+ { CKA_TOKEN, &ckToken, sizeof (ckToken) },
1213+ { CKA_VERIFY, &ckTrue, sizeof (ckTrue) },
1214+ { CKA_ENCRYPT, &ckFalse, sizeof (ckFalse) },
1215+ { CKA_WRAP, &ckFalse, sizeof (ckFalse) },
1216+ { CKA_PARAMETER_SET, &keyMat->parameterSet , sizeof (CK_ULONG) },
1217+ { CKA_VALUE, keyMat->pubValue , keyMat->sizePubValue },
1218+ };
1219+ CK_ATTRIBUTE privTemplate[] = {
1220+ { CKA_CLASS, &privClass, sizeof (privClass) },
1221+ { CKA_KEY_TYPE, &keyType, sizeof (keyType) },
1222+ { CKA_LABEL, label, strlen (label) },
1223+ { CKA_ID, objID, objIDLen },
1224+ { CKA_SIGN, &ckTrue, sizeof (ckTrue) },
1225+ { CKA_DECRYPT, &ckFalse, sizeof (ckFalse) },
1226+ { CKA_UNWRAP, &ckFalse, sizeof (ckFalse) },
1227+ { CKA_SENSITIVE, &ckTrue, sizeof (ckTrue) },
1228+ { CKA_TOKEN, &ckTrue, sizeof (ckTrue) },
1229+ { CKA_PRIVATE, &ckTrue, sizeof (ckTrue) },
1230+ { CKA_EXTRACTABLE, &ckFalse, sizeof (ckFalse) },
1231+ { CKA_PARAMETER_SET, &keyMat->parameterSet , sizeof (CK_ULONG) },
1232+ { CKA_SEED, keyMat->seed , keyMat->sizeSeed },
1233+ { CKA_VALUE, keyMat->privValue , keyMat->sizePrivValue },
1234+ };
1235+
1236+ CK_OBJECT_HANDLE hKey1, hKey2;
1237+ CK_RV rv = p11->C_CreateObject (hSession, privTemplate, 14 , &hKey1);
1238+ if (rv != CKR_OK)
1239+ {
1240+ fprintf (stderr, " ERROR: Could not save the private key in the token. "
1241+ " Maybe the algorithm is not supported.\n " );
1242+ crypto_free_mldsa (keyMat);
1243+ return 1 ;
1244+ }
1245+
1246+ rv = p11->C_CreateObject (hSession, pubTemplate, 10 , &hKey2);
1247+ crypto_free_mldsa (keyMat);
1248+
1249+ if (rv != CKR_OK)
1250+ {
1251+ p11->C_DestroyObject (hSession, hKey1);
1252+ fprintf (stderr, " ERROR: Could not save the public key in the token.\n " );
1253+ return 1 ;
1254+ }
1255+
1256+ printf (" The MLDSA key pair with label=%s has been imported.\n " , label);
1257+
1258+ return 0 ;
1259+ }
1260+
1261+ mldsa_key_material_t * crypto_malloc_mldsa (EVP_PKEY* pkey)
1262+ {
1263+
1264+ if (pkey == NULL )
1265+ {
1266+ return NULL ;
1267+ }
1268+
1269+ mldsa_key_material_t * keyMat = (mldsa_key_material_t *)calloc (1 , sizeof (mldsa_key_material_t ));
1270+ if (keyMat == NULL )
1271+ {
1272+ return NULL ;
1273+ }
1274+
1275+ uint8_t seed[32 ];
1276+ size_t seed_len;
1277+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
1278+ seed, sizeof (seed), &seed_len);
1279+
1280+ if (!rv)
1281+ {
1282+ fprintf (stderr, " ERROR: Could not get ML-DSA seed, rv: %d\n " , rv);
1283+ memset (seed, 0 , sizeof (seed));
1284+ crypto_free_mldsa (keyMat);
1285+ return NULL ;
1286+ }
1287+
1288+ // let's use max priv length
1289+ uint8_t priv[MLDSAParameters::ML_DSA_87_PRIV_LENGTH];
1290+ size_t priv_len;
1291+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY,
1292+ priv, sizeof (priv), &priv_len);
1293+ if (!rv)
1294+ {
1295+ fprintf (stderr, " ERROR: Could not get ML-DSA private key, rv: %d\n " , rv);
1296+ memset (seed, 0 , sizeof (seed));
1297+ memset (priv, 0 , sizeof (priv));
1298+ crypto_free_mldsa (keyMat);
1299+ return NULL ;
1300+ }
1301+
1302+ if (priv_len != MLDSAParameters::ML_DSA_44_PRIV_LENGTH &&
1303+ priv_len != MLDSAParameters::ML_DSA_65_PRIV_LENGTH &&
1304+ priv_len != MLDSAParameters::ML_DSA_87_PRIV_LENGTH)
1305+ {
1306+ fprintf (stderr, " ERROR: Unsupported ML-DSA private key length: %zu\n " , priv_len);
1307+ memset (seed, 0 , sizeof (seed));
1308+ memset (priv, 0 , sizeof (priv));
1309+ crypto_free_mldsa (keyMat);
1310+ return NULL ;
1311+ }
1312+
1313+ uint8_t pub[MLDSAParameters::ML_DSA_87_PUB_LENGTH];
1314+ size_t pub_len;
1315+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PUB_KEY,
1316+ pub, sizeof (pub), &pub_len);
1317+
1318+ if (!rv)
1319+ {
1320+ fprintf (stderr, " ERROR: Could not get ML-DSA public key, rv: %d\n " , rv);
1321+ memset (seed, 0 , sizeof (seed));
1322+ memset (priv, 0 , sizeof (priv));
1323+ memset (pub, 0 , sizeof (pub));
1324+ crypto_free_mldsa (keyMat);
1325+ return NULL ;
1326+ }
1327+
1328+ keyMat->sizeSeed = seed_len;
1329+ keyMat->sizePrivValue = priv_len;
1330+ keyMat->sizePubValue = pub_len;
1331+
1332+ if (keyMat->sizeSeed > 0 ) {
1333+ keyMat->seed = (CK_VOID_PTR)malloc (keyMat->sizeSeed );
1334+ }
1335+ if (keyMat->sizePrivValue > 0 ) {
1336+ keyMat->privValue = (CK_VOID_PTR)malloc (keyMat->sizePrivValue );
1337+ }
1338+ keyMat->pubValue = (CK_VOID_PTR)malloc (keyMat->sizePubValue );
1339+
1340+ if (!keyMat->seed || !keyMat->privValue || !keyMat->pubValue )
1341+ {
1342+ crypto_free_mldsa (keyMat);
1343+ return NULL ;
1344+ }
1345+
1346+ switch (keyMat->sizePrivValue )
1347+ {
1348+ case MLDSAParameters::ML_DSA_44_PRIV_LENGTH:
1349+ keyMat->parameterSet = MLDSAParameters::ML_DSA_44_PARAMETER_SET;
1350+ break ;
1351+
1352+ case MLDSAParameters::ML_DSA_65_PRIV_LENGTH:
1353+ keyMat->parameterSet = MLDSAParameters::ML_DSA_65_PARAMETER_SET;
1354+ break ;
1355+
1356+ case MLDSAParameters::ML_DSA_87_PRIV_LENGTH:
1357+ keyMat->parameterSet = MLDSAParameters::ML_DSA_87_PARAMETER_SET;
1358+ break ;
1359+
1360+ default :
1361+ crypto_free_mldsa (keyMat);
1362+ return NULL ;
1363+ }
1364+
1365+ if (keyMat->seed ) {
1366+ memcpy (keyMat->seed , seed, keyMat->sizeSeed );
1367+ }
1368+ if (keyMat->privValue ) {
1369+ memcpy (keyMat->privValue , priv, keyMat->sizePrivValue );
1370+ }
1371+ memcpy (keyMat->pubValue , pub, keyMat->sizePubValue );
1372+
1373+ return keyMat;
1374+ }
1375+
1376+ // Free the memory of the key
1377+ void crypto_free_mldsa (mldsa_key_material_t * keyMat)
1378+ {
1379+ if (keyMat == NULL ) return ;
1380+ if (keyMat->seed ) free (keyMat->seed );
1381+ if (keyMat->privValue ) free (keyMat->privValue );
1382+ if (keyMat->pubValue ) free (keyMat->pubValue );
1383+ free (keyMat);
1384+ }
1385+
1386+ #endif
0 commit comments