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