@@ -152,35 +152,58 @@ 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+ int keyType = EVP_PKEY_get_id (pkey);
160+ if (keyType != EVP_PKEY_KEYMGMT)
157161 {
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 ;
169- #endif
170- #ifdef WITH_EDDSA
171- case NID_X25519:
172- case NID_ED25519:
173- case NID_X448:
174- case NID_ED448:
162+ switch (keyType)
163+ {
164+ case EVP_PKEY_RSA:
165+ case EVP_PKEY_RSA_PSS:
166+ rsa = EVP_PKEY_get1_RSA (pkey);
167+ break ;
168+ case EVP_PKEY_DSA:
169+ dsa = EVP_PKEY_get1_DSA (pkey);
170+ break ;
171+ #ifdef WITH_ECC
172+ case EVP_PKEY_EC:
173+ ecdsa = EVP_PKEY_get1_EC_KEY (pkey);
174+ break ;
175+ #endif
176+ #ifdef WITH_EDDSA
177+ case NID_X25519:
178+ case NID_ED25519:
179+ case NID_X448:
180+ case NID_ED448:
181+ EVP_PKEY_up_ref (pkey);
182+ eddsa = pkey;
183+ break ;
184+ #endif
185+ default :
186+ fprintf (stderr, " ERROR: Cannot handle this algorithm.\n " );
187+ EVP_PKEY_free (pkey);
188+ return 1 ;
189+ break ;
190+ }
191+ } else {
192+ // Provider Keys management
193+ #ifdef WITH_ML_DSA
194+ size_t seed_len;
195+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
196+ NULL , 0 , &seed_len);
197+
198+ if (!rv) {
199+ fprintf (stderr, " ERROR: Could not get OSSL_PKEY_PARAM_ML_DSA_SEED size, rv: %d\n " , rv);
200+ EVP_PKEY_free (pkey);
201+ return NULL ;
202+ }
175203 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 ;
204+ mldsa = pkey;
205+ #endif
206+
184207 }
185208 EVP_PKEY_free (pkey);
186209
@@ -209,6 +232,13 @@ int crypto_import_key_pair
209232 result = crypto_save_eddsa (hSession, label, objID, objIDLen, noPublicKey, eddsa);
210233 EVP_PKEY_free (eddsa);
211234 }
235+ #endif
236+ #ifdef WITH_ML_DSA
237+ else if (mldsa)
238+ {
239+ result = crypto_save_mldsa (hSession, label, objID, objIDLen, noPublicKey, mldsa);
240+ EVP_PKEY_free (mldsa);
241+ }
212242#endif
213243 else
214244 {
@@ -409,7 +439,7 @@ EVP_PKEY* crypto_read_file(char* filePath, char* filePIN)
409439 if (!p8inf)
410440 {
411441 fprintf (stderr, " ERROR: Could not read the PKCS#8 file. "
412- " Maybe it is encypted (--file-pin <PIN>)\n " );
442+ " Maybe it is encypted (--file-pin <PIN>)\n Error code: % " );
413443 return NULL ;
414444 }
415445 }
@@ -1139,3 +1169,198 @@ void crypto_free_eddsa(eddsa_key_material_t* keyMat)
11391169}
11401170
11411171#endif
1172+
1173+ #ifdef WITH_ML_DSA
1174+
1175+ // Save the key data in PKCS#11
1176+ int crypto_save_mldsa
1177+ (
1178+ CK_SESSION_HANDLE hSession,
1179+ char * label,
1180+ char * objID,
1181+ size_t objIDLen,
1182+ int noPublicKey,
1183+ EVP_PKEY* mldsa
1184+ )
1185+ {
1186+ mldsa_key_material_t * keyMat = crypto_malloc_mldsa (mldsa);
1187+ if (keyMat == NULL )
1188+ {
1189+ fprintf (stderr, " ERROR: Could not convert the key material to binary information.\n " );
1190+ return 1 ;
1191+ }
1192+
1193+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY, privClass = CKO_PRIVATE_KEY;
1194+ CK_KEY_TYPE keyType = CKK_ML_DSA;
1195+ CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE;
1196+ if (noPublicKey)
1197+ {
1198+ ckToken = CK_FALSE;
1199+ }
1200+ CK_ATTRIBUTE pubTemplate[] = {
1201+ { CKA_CLASS, &pubClass, sizeof (pubClass) },
1202+ { CKA_KEY_TYPE, &keyType, sizeof (keyType) },
1203+ { CKA_LABEL, label, strlen (label) },
1204+ { CKA_ID, objID, objIDLen },
1205+ { CKA_TOKEN, &ckToken, sizeof (ckToken) },
1206+ { CKA_VERIFY, &ckTrue, sizeof (ckTrue) },
1207+ { CKA_ENCRYPT, &ckFalse, sizeof (ckFalse) },
1208+ { CKA_WRAP, &ckFalse, sizeof (ckFalse) },
1209+ { CKA_PARAMETER_SET, &keyMat->parameterSet , sizeof (CK_ULONG) },
1210+ { CKA_VALUE, keyMat->pubValue , keyMat->sizePubValue },
1211+ };
1212+ CK_ATTRIBUTE privTemplate[] = {
1213+ { CKA_CLASS, &privClass, sizeof (privClass) },
1214+ { CKA_KEY_TYPE, &keyType, sizeof (keyType) },
1215+ { CKA_LABEL, label, strlen (label) },
1216+ { CKA_ID, objID, objIDLen },
1217+ { CKA_SIGN, &ckTrue, sizeof (ckTrue) },
1218+ { CKA_DECRYPT, &ckFalse, sizeof (ckFalse) },
1219+ { CKA_UNWRAP, &ckFalse, sizeof (ckFalse) },
1220+ { CKA_SENSITIVE, &ckTrue, sizeof (ckTrue) },
1221+ { CKA_TOKEN, &ckTrue, sizeof (ckTrue) },
1222+ { CKA_PRIVATE, &ckTrue, sizeof (ckTrue) },
1223+ { CKA_EXTRACTABLE, &ckFalse, sizeof (ckFalse) },
1224+ { CKA_PARAMETER_SET, &keyMat->parameterSet , sizeof (CK_ULONG) },
1225+ { CKA_SEED, keyMat->seed , keyMat->sizeSeed },
1226+ { CKA_VALUE, keyMat->privValue , keyMat->sizePrivValue },
1227+ };
1228+
1229+ CK_OBJECT_HANDLE hKey1, hKey2;
1230+ CK_RV rv = p11->C_CreateObject (hSession, privTemplate, 14 , &hKey1);
1231+ if (rv != CKR_OK)
1232+ {
1233+ fprintf (stderr, " ERROR: Could not save the private key in the token. "
1234+ " Maybe the algorithm is not supported.\n " );
1235+ crypto_free_mldsa (keyMat);
1236+ return 1 ;
1237+ }
1238+
1239+ rv = p11->C_CreateObject (hSession, pubTemplate, 10 , &hKey2);
1240+ crypto_free_mldsa (keyMat);
1241+
1242+ if (rv != CKR_OK)
1243+ {
1244+ p11->C_DestroyObject (hSession, hKey1);
1245+ fprintf (stderr, " ERROR: Could not save the public key in the token.\n " );
1246+ return 1 ;
1247+ }
1248+
1249+ printf (" The key pair has been imported.\n " );
1250+
1251+ return 0 ;
1252+ }
1253+
1254+ // Convert the OpenSSL key to binary
1255+ #define PUBPREFIXLEN 12
1256+ #define PRIVPREFIXLEN 16
1257+
1258+ mldsa_key_material_t * crypto_malloc_mldsa (EVP_PKEY* pkey)
1259+ {
1260+
1261+ if (pkey == NULL )
1262+ {
1263+ return NULL ;
1264+ }
1265+
1266+ mldsa_key_material_t * keyMat = (mldsa_key_material_t *)calloc (1 , sizeof (mldsa_key_material_t ));
1267+ if (keyMat == NULL )
1268+ {
1269+ return NULL ;
1270+ }
1271+
1272+ uint8_t seed[32 ];
1273+ size_t seed_len;
1274+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
1275+ seed, sizeof (seed), &seed_len);
1276+
1277+ if (!rv) {
1278+ fprintf (stderr, " ERROR: Could not get ML-DSA seed, rv: %d" , rv);
1279+ memset (seed, 0 , sizeof (seed));
1280+ return NULL ;
1281+ }
1282+
1283+ // let's use max priv length
1284+ uint8_t priv[MLDSAParameters::ML_DSA_87_PRIV_LENGTH];
1285+ size_t priv_len;
1286+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY,
1287+ priv, sizeof (priv), &priv_len);
1288+ if (!rv) {
1289+ fprintf (stderr, " ERROR: Could not get ML-DSA private key, rv: %d" , rv);
1290+ memset (seed, 0 , sizeof (seed));
1291+ memset (priv, 0 , sizeof (priv));
1292+ return NULL ;
1293+ }
1294+
1295+ if (priv_len != MLDSAParameters::ML_DSA_44_PRIV_LENGTH &&
1296+ priv_len != MLDSAParameters::ML_DSA_65_PRIV_LENGTH &&
1297+ priv_len != MLDSAParameters::ML_DSA_87_PRIV_LENGTH)
1298+ {
1299+ fprintf (stderr, " ERROR: Unsupported ML-DSA private key length: %zu" , priv_len);
1300+ memset (seed, 0 , sizeof (seed));
1301+ memset (priv, 0 , sizeof (priv));
1302+ return NULL ;
1303+ }
1304+
1305+ uint8_t pub[MLDSAParameters::ML_DSA_87_PUB_LENGTH];
1306+ size_t pub_len;
1307+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PUB_KEY,
1308+ pub, sizeof (pub), &pub_len);
1309+
1310+ if (!rv) {
1311+ fprintf (stderr, " ERROR: Could not get ML-DSA public key, rv: %d" , rv);
1312+ memset (seed, 0 , sizeof (seed));
1313+ memset (priv, 0 , sizeof (priv));
1314+ return NULL ;
1315+ }
1316+
1317+ keyMat->sizeSeed = seed_len;
1318+ keyMat->sizePrivValue = priv_len;
1319+ keyMat->sizePubValue = pub_len;
1320+
1321+ keyMat->seed = (CK_VOID_PTR)malloc (keyMat->sizeSeed );
1322+ keyMat->privValue = (CK_VOID_PTR)malloc (keyMat->sizePrivValue );
1323+ keyMat->pubValue = (CK_VOID_PTR)malloc (keyMat->sizePubValue );
1324+
1325+ switch (keyMat->sizePrivValue )
1326+ {
1327+ case MLDSAParameters::ML_DSA_44_PRIV_LENGTH:
1328+ keyMat->parameterSet = MLDSAParameters::ML_DSA_44_PARAMETER_SET;
1329+ break ;
1330+
1331+ case MLDSAParameters::ML_DSA_65_PRIV_LENGTH:
1332+ keyMat->parameterSet = MLDSAParameters::ML_DSA_65_PARAMETER_SET;
1333+ break ;
1334+
1335+ case MLDSAParameters::ML_DSA_87_PRIV_LENGTH:
1336+ keyMat->parameterSet = MLDSAParameters::ML_DSA_87_PARAMETER_SET;
1337+ break ;
1338+
1339+ default :
1340+ break ;
1341+ }
1342+
1343+ memcpy (keyMat->seed , seed, keyMat->sizeSeed );
1344+ memcpy (keyMat->privValue , priv, keyMat->sizePrivValue );
1345+ memcpy (keyMat->pubValue , pub, keyMat->sizePubValue );
1346+
1347+ if (!keyMat->parameterSet || !keyMat->seed || !keyMat->privValue || !keyMat->pubValue )
1348+ {
1349+ crypto_free_mldsa (keyMat);
1350+ return NULL ;
1351+ }
1352+
1353+ return keyMat;
1354+ }
1355+
1356+ // Free the memory of the key
1357+ void crypto_free_mldsa (mldsa_key_material_t * keyMat)
1358+ {
1359+ if (keyMat == NULL ) return ;
1360+ if (keyMat->seed ) free (keyMat->seed );
1361+ if (keyMat->privValue ) free (keyMat->privValue );
1362+ if (keyMat->pubValue ) free (keyMat->pubValue );
1363+ free (keyMat);
1364+ }
1365+
1366+ #endif
0 commit comments