@@ -152,36 +152,70 @@ 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_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED ,
202+ NULL , 0 , &len);
203+
204+ if (!rv) {
205+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY ,
206+ NULL , 0 , &len);
207+ if (!rv) {
208+ fprintf (stderr, " ERROR: Cannot handle this algorithm, rv: %d\n " , rv);
209+ EVP_PKEY_free (pkey);
210+ return 1 ;
211+ }
212+ }
175213 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 ;
214+ mldsa = pkey;
215+ #endif
216+
184217 }
218+ #endif
185219 EVP_PKEY_free (pkey);
186220
187221 int result = 0 ;
@@ -209,6 +243,13 @@ int crypto_import_key_pair
209243 result = crypto_save_eddsa (hSession, label, objID, objIDLen, noPublicKey, eddsa);
210244 EVP_PKEY_free (eddsa);
211245 }
246+ #endif
247+ #ifdef WITH_ML_DSA
248+ else if (mldsa)
249+ {
250+ result = crypto_save_mldsa (hSession, label, objID, objIDLen, noPublicKey, mldsa);
251+ EVP_PKEY_free (mldsa);
252+ }
212253#endif
213254 else
214255 {
@@ -1139,3 +1180,206 @@ void crypto_free_eddsa(eddsa_key_material_t* keyMat)
11391180}
11401181
11411182#endif
1183+
1184+ #ifdef WITH_ML_DSA
1185+
1186+ // Save the key data in PKCS#11
1187+ int crypto_save_mldsa
1188+ (
1189+ CK_SESSION_HANDLE hSession,
1190+ char * label,
1191+ char * objID,
1192+ size_t objIDLen,
1193+ int noPublicKey,
1194+ EVP_PKEY * mldsa
1195+ )
1196+ {
1197+ mldsa_key_material_t * keyMat = crypto_malloc_mldsa (mldsa);
1198+ if (keyMat == NULL )
1199+ {
1200+ fprintf (stderr, " ERROR: Could not convert the key material to binary information.\n " );
1201+ return 1 ;
1202+ }
1203+
1204+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY , privClass = CKO_PRIVATE_KEY ;
1205+ CK_KEY_TYPE keyType = CKK_ML_DSA ;
1206+ CK_BBOOL ckTrue = CK_TRUE , ckFalse = CK_FALSE , ckToken = CK_TRUE ;
1207+ if (noPublicKey)
1208+ {
1209+ ckToken = CK_FALSE ;
1210+ }
1211+ CK_ATTRIBUTE pubTemplate[] = {
1212+ { CKA_CLASS , &pubClass, sizeof (pubClass) },
1213+ { CKA_KEY_TYPE , &keyType, sizeof (keyType) },
1214+ { CKA_LABEL , label, strlen (label) },
1215+ { CKA_ID , objID, objIDLen },
1216+ { CKA_TOKEN , &ckToken, sizeof (ckToken) },
1217+ { CKA_VERIFY , &ckTrue, sizeof (ckTrue) },
1218+ { CKA_ENCRYPT , &ckFalse, sizeof (ckFalse) },
1219+ { CKA_WRAP , &ckFalse, sizeof (ckFalse) },
1220+ { CKA_PARAMETER_SET , &keyMat->parameterSet , sizeof (CK_ULONG ) },
1221+ { CKA_VALUE , keyMat->pubValue , keyMat->sizePubValue },
1222+ };
1223+ CK_ATTRIBUTE privTemplate[] = {
1224+ { CKA_CLASS , &privClass, sizeof (privClass) },
1225+ { CKA_KEY_TYPE , &keyType, sizeof (keyType) },
1226+ { CKA_LABEL , label, strlen (label) },
1227+ { CKA_ID , objID, objIDLen },
1228+ { CKA_SIGN , &ckTrue, sizeof (ckTrue) },
1229+ { CKA_DECRYPT , &ckFalse, sizeof (ckFalse) },
1230+ { CKA_UNWRAP , &ckFalse, sizeof (ckFalse) },
1231+ { CKA_SENSITIVE , &ckTrue, sizeof (ckTrue) },
1232+ { CKA_TOKEN , &ckTrue, sizeof (ckTrue) },
1233+ { CKA_PRIVATE , &ckTrue, sizeof (ckTrue) },
1234+ { CKA_EXTRACTABLE , &ckFalse, sizeof (ckFalse) },
1235+ { CKA_PARAMETER_SET , &keyMat->parameterSet , sizeof (CK_ULONG ) },
1236+ { CKA_SEED , keyMat->seed , keyMat->sizeSeed },
1237+ { CKA_VALUE , keyMat->privValue , keyMat->sizePrivValue },
1238+ };
1239+
1240+ CK_OBJECT_HANDLE hKey1, hKey2;
1241+ CK_RV rv = p11->C_CreateObject (hSession, privTemplate, 14 , &hKey1);
1242+ if (rv != CKR_OK )
1243+ {
1244+ fprintf (stderr, " ERROR: Could not save the private key in the token. "
1245+ " Maybe the algorithm is not supported.\n " );
1246+ crypto_free_mldsa (keyMat);
1247+ return 1 ;
1248+ }
1249+
1250+ rv = p11->C_CreateObject (hSession, pubTemplate, 10 , &hKey2);
1251+ crypto_free_mldsa (keyMat);
1252+
1253+ if (rv != CKR_OK )
1254+ {
1255+ p11->C_DestroyObject (hSession, hKey1);
1256+ fprintf (stderr, " ERROR: Could not save the public key in the token.\n " );
1257+ return 1 ;
1258+ }
1259+
1260+ printf (" The key pair has been imported.\n " );
1261+
1262+ return 0 ;
1263+ }
1264+
1265+ // Convert the OpenSSL key to binary
1266+ #define PUBPREFIXLEN 12
1267+ #define PRIVPREFIXLEN 16
1268+
1269+ mldsa_key_material_t * crypto_malloc_mldsa (EVP_PKEY * pkey)
1270+ {
1271+
1272+ if (pkey == NULL )
1273+ {
1274+ return NULL ;
1275+ }
1276+
1277+ mldsa_key_material_t * keyMat = (mldsa_key_material_t *)calloc (1 , sizeof (mldsa_key_material_t ));
1278+ if (keyMat == NULL )
1279+ {
1280+ return NULL ;
1281+ }
1282+
1283+ uint8_t seed[32 ];
1284+ size_t seed_len;
1285+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED ,
1286+ seed, sizeof (seed), &seed_len);
1287+
1288+ if (!rv)
1289+ {
1290+ fprintf (stderr, " ERROR: Could not get ML-DSA seed, rv: %d" , rv);
1291+ memset (seed, 0 , sizeof (seed));
1292+ crypto_free_mldsa (keyMat);
1293+ return NULL ;
1294+ }
1295+
1296+ // let's use max priv length
1297+ uint8_t priv[MLDSAParameters::ML_DSA_87_PRIV_LENGTH ];
1298+ size_t priv_len;
1299+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY ,
1300+ priv, sizeof (priv), &priv_len);
1301+ if (!rv)
1302+ {
1303+ fprintf (stderr, " ERROR: Could not get ML-DSA private key, rv: %d" , rv);
1304+ memset (seed, 0 , sizeof (seed));
1305+ memset (priv, 0 , sizeof (priv));
1306+ crypto_free_mldsa (keyMat);
1307+ return NULL ;
1308+ }
1309+
1310+ if (priv_len != MLDSAParameters::ML_DSA_44_PRIV_LENGTH &&
1311+ priv_len != MLDSAParameters::ML_DSA_65_PRIV_LENGTH &&
1312+ priv_len != MLDSAParameters::ML_DSA_87_PRIV_LENGTH )
1313+ {
1314+ fprintf (stderr, " ERROR: Unsupported ML-DSA private key length: %zu" , priv_len);
1315+ memset (seed, 0 , sizeof (seed));
1316+ memset (priv, 0 , sizeof (priv));
1317+ crypto_free_mldsa (keyMat);
1318+ return NULL ;
1319+ }
1320+
1321+ uint8_t pub[MLDSAParameters::ML_DSA_87_PUB_LENGTH ];
1322+ size_t pub_len;
1323+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PUB_KEY ,
1324+ pub, sizeof (pub), &pub_len);
1325+
1326+ if (!rv)
1327+ {
1328+ fprintf (stderr, " ERROR: Could not get ML-DSA public key, rv: %d" , rv);
1329+ memset (seed, 0 , sizeof (seed));
1330+ memset (priv, 0 , sizeof (priv));
1331+ memset (pub, 0 , sizeof (pub));
1332+ crypto_free_mldsa (keyMat);
1333+ return NULL ;
1334+ }
1335+
1336+ keyMat->sizeSeed = seed_len;
1337+ keyMat->sizePrivValue = priv_len;
1338+ keyMat->sizePubValue = pub_len;
1339+
1340+ keyMat->seed = (CK_VOID_PTR )malloc (keyMat->sizeSeed );
1341+ keyMat->privValue = (CK_VOID_PTR )malloc (keyMat->sizePrivValue );
1342+ keyMat->pubValue = (CK_VOID_PTR )malloc (keyMat->sizePubValue );
1343+
1344+ if (!keyMat->seed || !keyMat->privValue || !keyMat->pubValue )
1345+ {
1346+ crypto_free_mldsa (keyMat);
1347+ return NULL ;
1348+ }
1349+
1350+ switch (keyMat->sizePrivValue )
1351+ {
1352+ case MLDSAParameters::ML_DSA_44_PRIV_LENGTH :
1353+ keyMat->parameterSet = MLDSAParameters::ML_DSA_44_PARAMETER_SET ;
1354+ break ;
1355+
1356+ case MLDSAParameters::ML_DSA_65_PRIV_LENGTH :
1357+ keyMat->parameterSet = MLDSAParameters::ML_DSA_65_PARAMETER_SET ;
1358+ break ;
1359+
1360+ case MLDSAParameters::ML_DSA_87_PRIV_LENGTH :
1361+ keyMat->parameterSet = MLDSAParameters::ML_DSA_87_PARAMETER_SET ;
1362+ break ;
1363+
1364+ default :
1365+ break ;
1366+ }
1367+
1368+ memcpy (keyMat->seed , seed, keyMat->sizeSeed );
1369+ memcpy (keyMat->privValue , priv, keyMat->sizePrivValue );
1370+ memcpy (keyMat->pubValue , pub, keyMat->sizePubValue );
1371+
1372+ return keyMat;
1373+ }
1374+
1375+ // Free the memory of the key
1376+ void crypto_free_mldsa (mldsa_key_material_t * keyMat)
1377+ {
1378+ if (keyMat == NULL ) return ;
1379+ if (keyMat->seed ) free (keyMat->seed );
1380+ if (keyMat->privValue ) free (keyMat->privValue );
1381+ if (keyMat->pubValue ) free (keyMat->pubValue );
1382+ free (keyMat);
1383+ }
1384+
1385+ #endif
0 commit comments