@@ -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 seed_len;
201+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
202+ NULL , 0 , &seed_len);
203+
204+ if (!rv) {
205+ fprintf (stderr, " ERROR: Could not get OSSL_PKEY_PARAM_ML_DSA_SEED size, rv: %d\n " , rv);
206+ EVP_PKEY_free (pkey);
207+ return NULL ;
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 {
@@ -409,7 +446,7 @@ EVP_PKEY* crypto_read_file(char* filePath, char* filePIN)
409446 if (!p8inf)
410447 {
411448 fprintf (stderr, " ERROR: Could not read the PKCS#8 file. "
412- " Maybe it is encypted (--file-pin <PIN>)\n " );
449+ " Maybe it is encypted (--file-pin <PIN>)\n Error code: % " );
413450 return NULL ;
414451 }
415452 }
@@ -1139,3 +1176,198 @@ 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 key pair has been imported.\n " );
1257+
1258+ return 0 ;
1259+ }
1260+
1261+ // Convert the OpenSSL key to binary
1262+ #define PUBPREFIXLEN 12
1263+ #define PRIVPREFIXLEN 16
1264+
1265+ mldsa_key_material_t * crypto_malloc_mldsa (EVP_PKEY* pkey)
1266+ {
1267+
1268+ if (pkey == NULL )
1269+ {
1270+ return NULL ;
1271+ }
1272+
1273+ mldsa_key_material_t * keyMat = (mldsa_key_material_t *)calloc (1 , sizeof (mldsa_key_material_t ));
1274+ if (keyMat == NULL )
1275+ {
1276+ return NULL ;
1277+ }
1278+
1279+ uint8_t seed[32 ];
1280+ size_t seed_len;
1281+ int rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
1282+ seed, sizeof (seed), &seed_len);
1283+
1284+ if (!rv) {
1285+ fprintf (stderr, " ERROR: Could not get ML-DSA seed, rv: %d" , rv);
1286+ memset (seed, 0 , sizeof (seed));
1287+ return NULL ;
1288+ }
1289+
1290+ // let's use max priv length
1291+ uint8_t priv[MLDSAParameters::ML_DSA_87_PRIV_LENGTH];
1292+ size_t priv_len;
1293+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY,
1294+ priv, sizeof (priv), &priv_len);
1295+ if (!rv) {
1296+ fprintf (stderr, " ERROR: Could not get ML-DSA private key, rv: %d" , rv);
1297+ memset (seed, 0 , sizeof (seed));
1298+ memset (priv, 0 , sizeof (priv));
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" , priv_len);
1307+ memset (seed, 0 , sizeof (seed));
1308+ memset (priv, 0 , sizeof (priv));
1309+ return NULL ;
1310+ }
1311+
1312+ uint8_t pub[MLDSAParameters::ML_DSA_87_PUB_LENGTH];
1313+ size_t pub_len;
1314+ rv = EVP_PKEY_get_octet_string_param (pkey, OSSL_PKEY_PARAM_PUB_KEY,
1315+ pub, sizeof (pub), &pub_len);
1316+
1317+ if (!rv) {
1318+ fprintf (stderr, " ERROR: Could not get ML-DSA public key, rv: %d" , rv);
1319+ memset (seed, 0 , sizeof (seed));
1320+ memset (priv, 0 , sizeof (priv));
1321+ return NULL ;
1322+ }
1323+
1324+ keyMat->sizeSeed = seed_len;
1325+ keyMat->sizePrivValue = priv_len;
1326+ keyMat->sizePubValue = pub_len;
1327+
1328+ keyMat->seed = (CK_VOID_PTR)malloc (keyMat->sizeSeed );
1329+ keyMat->privValue = (CK_VOID_PTR)malloc (keyMat->sizePrivValue );
1330+ keyMat->pubValue = (CK_VOID_PTR)malloc (keyMat->sizePubValue );
1331+
1332+ switch (keyMat->sizePrivValue )
1333+ {
1334+ case MLDSAParameters::ML_DSA_44_PRIV_LENGTH:
1335+ keyMat->parameterSet = MLDSAParameters::ML_DSA_44_PARAMETER_SET;
1336+ break ;
1337+
1338+ case MLDSAParameters::ML_DSA_65_PRIV_LENGTH:
1339+ keyMat->parameterSet = MLDSAParameters::ML_DSA_65_PARAMETER_SET;
1340+ break ;
1341+
1342+ case MLDSAParameters::ML_DSA_87_PRIV_LENGTH:
1343+ keyMat->parameterSet = MLDSAParameters::ML_DSA_87_PARAMETER_SET;
1344+ break ;
1345+
1346+ default :
1347+ break ;
1348+ }
1349+
1350+ memcpy (keyMat->seed , seed, keyMat->sizeSeed );
1351+ memcpy (keyMat->privValue , priv, keyMat->sizePrivValue );
1352+ memcpy (keyMat->pubValue , pub, keyMat->sizePubValue );
1353+
1354+ if (!keyMat->parameterSet || !keyMat->seed || !keyMat->privValue || !keyMat->pubValue )
1355+ {
1356+ crypto_free_mldsa (keyMat);
1357+ return NULL ;
1358+ }
1359+
1360+ return keyMat;
1361+ }
1362+
1363+ // Free the memory of the key
1364+ void crypto_free_mldsa (mldsa_key_material_t * keyMat)
1365+ {
1366+ if (keyMat == NULL ) return ;
1367+ if (keyMat->seed ) free (keyMat->seed );
1368+ if (keyMat->privValue ) free (keyMat->privValue );
1369+ if (keyMat->pubValue ) free (keyMat->pubValue );
1370+ free (keyMat);
1371+ }
1372+
1373+ #endif
0 commit comments