Signature.cpp
1 /* 2 * Copyright (c) 2013-2025, The PurpleI2P Project 3 * 4 * This file is part of Purple i2pd project and licensed under BSD3 5 * 6 * See full license text in LICENSE file at top of project tree 7 */ 8 9 #include <memory> 10 #include <openssl/evp.h> 11 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 12 #include <openssl/core_names.h> 13 #include <openssl/param_build.h> 14 #endif 15 #include "Log.h" 16 #include "Signature.h" 17 18 namespace i2p 19 { 20 namespace crypto 21 { 22 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 23 DSAVerifier::DSAVerifier (): 24 m_PublicKey (nullptr) 25 { 26 } 27 28 DSAVerifier::~DSAVerifier () 29 { 30 if (m_PublicKey) 31 EVP_PKEY_free (m_PublicKey); 32 } 33 34 void DSAVerifier::SetPublicKey (const uint8_t * signingKey) 35 { 36 if (m_PublicKey) 37 EVP_PKEY_free (m_PublicKey); 38 BIGNUM * pub = BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL); 39 m_PublicKey = CreateDSA (pub); 40 BN_free (pub); 41 } 42 43 bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 44 { 45 // signature 46 DSA_SIG * sig = DSA_SIG_new(); 47 DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); 48 // to DER format 49 uint8_t sign[DSA_SIGNATURE_LENGTH + 8]; 50 uint8_t * s = sign; 51 auto l = i2d_DSA_SIG (sig, &s); 52 DSA_SIG_free(sig); 53 // verify 54 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 55 EVP_DigestVerifyInit (ctx, NULL, EVP_sha1(), NULL, m_PublicKey); 56 auto ret = EVP_DigestVerify (ctx, sign, l, buf, len) == 1; 57 EVP_MD_CTX_destroy (ctx); 58 return ret; 59 } 60 61 DSASigner::DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) 62 { 63 BIGNUM * priv = BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL); 64 m_PrivateKey = CreateDSA (nullptr, priv); 65 BN_free (priv); 66 } 67 68 DSASigner::~DSASigner () 69 { 70 if (m_PrivateKey) 71 EVP_PKEY_free (m_PrivateKey); 72 } 73 74 void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const 75 { 76 uint8_t sign[DSA_SIGNATURE_LENGTH + 8]; 77 size_t l = DSA_SIGNATURE_LENGTH + 8; 78 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 79 EVP_DigestSignInit (ctx, NULL, EVP_sha1(), NULL, m_PrivateKey); 80 EVP_DigestSign (ctx, sign, &l, buf, len); 81 EVP_MD_CTX_destroy (ctx); 82 // decode r and s 83 const uint8_t * s1 = sign; 84 DSA_SIG * sig = d2i_DSA_SIG (NULL, &s1, l); 85 const BIGNUM * r, * s; 86 DSA_SIG_get0 (sig, &r, &s); 87 bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); 88 bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); 89 DSA_SIG_free(sig); 90 } 91 92 void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 93 { 94 EVP_PKEY * paramskey = CreateDSA(); 95 EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new_from_pkey(NULL, paramskey, NULL); 96 EVP_PKEY_keygen_init(ctx); 97 EVP_PKEY * pkey = nullptr; 98 EVP_PKEY_keygen(ctx, &pkey); 99 BIGNUM * pub = NULL, * priv = NULL; 100 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pub); 101 bn2buf (pub, signingPublicKey, DSA_PUBLIC_KEY_LENGTH); 102 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv); 103 bn2buf (priv, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH); 104 BN_free (pub); BN_free (priv); 105 EVP_PKEY_free (pkey); 106 EVP_PKEY_free (paramskey); 107 EVP_PKEY_CTX_free (ctx); 108 } 109 #else 110 111 DSAVerifier::DSAVerifier () 112 { 113 m_PublicKey = CreateDSA (); 114 } 115 116 DSAVerifier::~DSAVerifier () 117 { 118 DSA_free (m_PublicKey); 119 } 120 121 void DSAVerifier::SetPublicKey (const uint8_t * signingKey) 122 { 123 DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); 124 } 125 126 bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 127 { 128 // calculate SHA1 digest 129 uint8_t digest[20]; 130 SHA1 (buf, len, digest); 131 // signature 132 DSA_SIG * sig = DSA_SIG_new(); 133 DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); 134 // DSA verification 135 int ret = DSA_do_verify (digest, 20, sig, m_PublicKey) == 1; 136 DSA_SIG_free(sig); 137 return ret; 138 } 139 140 DSASigner::DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) 141 { 142 m_PrivateKey = CreateDSA (); 143 DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); 144 } 145 146 DSASigner::~DSASigner () 147 { 148 DSA_free (m_PrivateKey); 149 } 150 151 void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const 152 { 153 uint8_t digest[20]; 154 SHA1 (buf, len, digest); 155 DSA_SIG * sig = DSA_do_sign (digest, 20, m_PrivateKey); 156 const BIGNUM * r, * s; 157 DSA_SIG_get0 (sig, &r, &s); 158 bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); 159 bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); 160 DSA_SIG_free(sig); 161 } 162 163 void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 164 { 165 DSA * dsa = CreateDSA (); 166 DSA_generate_key (dsa); 167 const BIGNUM * pub_key, * priv_key; 168 DSA_get0_key(dsa, &pub_key, &priv_key); 169 bn2buf (priv_key, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH); 170 bn2buf (pub_key, signingPublicKey, DSA_PUBLIC_KEY_LENGTH); 171 DSA_free (dsa); 172 } 173 #endif 174 175 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 176 ECDSAVerifier::ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash): 177 m_Curve(curve), m_KeyLen (keyLen), m_Hash (hash), m_PublicKey (nullptr) 178 { 179 } 180 181 ECDSAVerifier::~ECDSAVerifier () 182 { 183 if (m_PublicKey) 184 EVP_PKEY_free (m_PublicKey); 185 } 186 187 void ECDSAVerifier::SetPublicKey (const uint8_t * signingKey) 188 { 189 if (m_PublicKey) 190 { 191 EVP_PKEY_free (m_PublicKey); 192 m_PublicKey = nullptr; 193 } 194 auto plen = GetPublicKeyLen (); 195 std::vector<uint8_t> pub(plen + 1); 196 pub[0] = POINT_CONVERSION_UNCOMPRESSED; 197 memcpy (pub.data() + 1, signingKey, plen); // 0x04|x|y 198 OSSL_PARAM_BLD * paramBld = OSSL_PARAM_BLD_new (); 199 OSSL_PARAM_BLD_push_utf8_string (paramBld, OSSL_PKEY_PARAM_GROUP_NAME, OBJ_nid2ln(m_Curve), 0); 200 OSSL_PARAM_BLD_push_octet_string (paramBld, OSSL_PKEY_PARAM_PUB_KEY, pub.data (), pub.size ()); 201 OSSL_PARAM * params = OSSL_PARAM_BLD_to_param(paramBld); 202 203 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL); 204 if (ctx) 205 { 206 if (EVP_PKEY_fromdata_init (ctx) <= 0 || 207 EVP_PKEY_fromdata (ctx, &m_PublicKey, EVP_PKEY_PUBLIC_KEY, params) <= 0) 208 LogPrint (eLogError, "ECDSA can't create PKEY from params"); 209 EVP_PKEY_CTX_free (ctx); 210 } 211 else 212 LogPrint (eLogError, "ECDSA can't create PKEY context"); 213 214 OSSL_PARAM_free (params); 215 OSSL_PARAM_BLD_free (paramBld); 216 } 217 218 bool ECDSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 219 { 220 // signature 221 ECDSA_SIG * sig = ECDSA_SIG_new(); 222 ECDSA_SIG_set0 (sig, BN_bin2bn (signature, GetSignatureLen ()/2, NULL), 223 BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL)); 224 // to DER format 225 std::vector<uint8_t> sign(GetSignatureLen () + 8); 226 uint8_t * s = sign.data (); 227 auto l = i2d_ECDSA_SIG (sig, &s); 228 ECDSA_SIG_free(sig); 229 // verify 230 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 231 EVP_DigestVerifyInit (ctx, NULL, m_Hash, NULL, m_PublicKey); 232 auto ret = EVP_DigestVerify (ctx, sign.data (), l, buf, len) == 1; 233 EVP_MD_CTX_destroy (ctx); 234 return ret; 235 } 236 237 ECDSASigner::ECDSASigner (int curve, size_t keyLen, const EVP_MD * hash, const uint8_t * signingPrivateKey): 238 m_KeyLen (keyLen), m_Hash(hash), m_PrivateKey (nullptr) 239 { 240 BIGNUM * priv = BN_bin2bn (signingPrivateKey, keyLen/2, NULL); 241 OSSL_PARAM_BLD * paramBld = OSSL_PARAM_BLD_new (); 242 OSSL_PARAM_BLD_push_utf8_string (paramBld, OSSL_PKEY_PARAM_GROUP_NAME, OBJ_nid2ln(curve), 0); 243 OSSL_PARAM_BLD_push_BN (paramBld, OSSL_PKEY_PARAM_PRIV_KEY, priv); 244 OSSL_PARAM * params = OSSL_PARAM_BLD_to_param(paramBld); 245 246 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL); 247 if (ctx) 248 { 249 if (EVP_PKEY_fromdata_init (ctx) <= 0 || 250 EVP_PKEY_fromdata (ctx, &m_PrivateKey, EVP_PKEY_KEYPAIR, params) <= 0) 251 LogPrint (eLogError, "ECDSA can't create PKEY from params"); 252 EVP_PKEY_CTX_free (ctx); 253 } 254 else 255 LogPrint (eLogError, "ECDSA can't create PKEY context"); 256 257 OSSL_PARAM_free (params); 258 OSSL_PARAM_BLD_free (paramBld); 259 BN_free (priv); 260 } 261 262 ECDSASigner::~ECDSASigner () 263 { 264 if (m_PrivateKey) 265 EVP_PKEY_free (m_PrivateKey); 266 } 267 268 void ECDSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const 269 { 270 std::vector<uint8_t> sign(m_KeyLen + 8); 271 size_t l = sign.size (); 272 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 273 EVP_DigestSignInit (ctx, NULL, m_Hash, NULL, m_PrivateKey); 274 EVP_DigestSign (ctx, sign.data(), &l, buf, len); 275 EVP_MD_CTX_destroy (ctx); 276 // decode r and s 277 const uint8_t * s1 = sign.data (); 278 ECDSA_SIG * sig = d2i_ECDSA_SIG (NULL, &s1, l); 279 const BIGNUM * r, * s; 280 ECDSA_SIG_get0 (sig, &r, &s); 281 bn2buf (r, signature, m_KeyLen/2); 282 bn2buf (s, signature + m_KeyLen/2, m_KeyLen/2); 283 ECDSA_SIG_free(sig); 284 } 285 286 void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) 287 { 288 EVP_PKEY * pkey = EVP_EC_gen (OBJ_nid2ln(curve)); 289 // private 290 BIGNUM * priv = BN_new (); 291 EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv); 292 bn2buf (priv, signingPrivateKey, keyLen/2); 293 BN_free (priv); 294 // public 295 BIGNUM * x = BN_new (), * y = BN_new (); 296 EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_EC_PUB_X, &x); 297 EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y); 298 bn2buf (x, signingPublicKey, keyLen/2); 299 bn2buf (y, signingPublicKey + keyLen/2, keyLen/2); 300 BN_free (x); BN_free (y); 301 EVP_PKEY_free (pkey); 302 } 303 304 #endif 305 306 EDDSA25519Verifier::EDDSA25519Verifier (): 307 m_Pkey (nullptr) 308 { 309 } 310 311 EDDSA25519Verifier::~EDDSA25519Verifier () 312 { 313 EVP_PKEY_free (m_Pkey); 314 } 315 316 void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) 317 { 318 if (m_Pkey) EVP_PKEY_free (m_Pkey); 319 m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); 320 } 321 322 bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 323 { 324 if (m_Pkey) 325 { 326 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 327 EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, m_Pkey); 328 auto ret = EVP_DigestVerify (ctx, signature, 64, buf, len) == 1; 329 EVP_MD_CTX_destroy (ctx); 330 return ret; 331 } 332 else 333 LogPrint (eLogError, "EdDSA verification key is not set"); 334 return false; 335 } 336 337 EDDSA25519SignerCompat::EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) 338 { 339 // expand key 340 Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey); 341 // generate and encode public key 342 BN_CTX * ctx = BN_CTX_new (); 343 auto publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx); 344 GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); 345 346 if (signingPublicKey && memcmp (m_PublicKeyEncoded, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) 347 { 348 // keys don't match, it means older key with 0x1F 349 LogPrint (eLogWarning, "Older EdDSA key detected"); 350 m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0xDF; // drop third bit 351 publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx); 352 GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); 353 } 354 BN_CTX_free (ctx); 355 } 356 357 EDDSA25519SignerCompat::~EDDSA25519SignerCompat () 358 { 359 } 360 361 void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const 362 { 363 GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); 364 } 365 366 EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): 367 m_Pkey (nullptr), m_Fallback (nullptr) 368 { 369 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); 370 uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; 371 size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; 372 EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); 373 if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) 374 { 375 LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); 376 m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); 377 EVP_PKEY_free (m_Pkey); 378 m_Pkey = nullptr; 379 } 380 } 381 382 EDDSA25519Signer::~EDDSA25519Signer () 383 { 384 if (m_Fallback) delete m_Fallback; 385 if (m_Pkey) EVP_PKEY_free (m_Pkey); 386 } 387 388 void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const 389 { 390 if (m_Fallback) 391 return m_Fallback->Sign (buf, len, signature); 392 else if (m_Pkey) 393 { 394 395 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 396 size_t l = 64; 397 uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 398 EVP_DigestSignInit (ctx, NULL, NULL, NULL, m_Pkey); 399 if (!EVP_DigestSign (ctx, sig, &l, buf, len)) 400 LogPrint (eLogError, "EdDSA signing failed"); 401 memcpy (signature, sig, 64); 402 EVP_MD_CTX_destroy (ctx); 403 } 404 else 405 LogPrint (eLogError, "EdDSA signing key is not set"); 406 } 407 408 #if (OPENSSL_VERSION_NUMBER >= 0x030000000) 409 static const OSSL_PARAM EDDSA25519phParams[] = 410 { 411 OSSL_PARAM_utf8_string ("instance", (char *)"Ed25519ph", 9), 412 OSSL_PARAM_END 413 }; 414 415 bool EDDSA25519phVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 416 { 417 auto pkey = GetPkey (); 418 if (pkey) 419 { 420 uint8_t digest[64]; 421 SHA512 (buf, len, digest); 422 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 423 EVP_DigestVerifyInit_ex (ctx, NULL, NULL, NULL, NULL, pkey, EDDSA25519phParams); 424 auto ret = EVP_DigestVerify (ctx, signature, 64, digest, 64); 425 EVP_MD_CTX_destroy (ctx); 426 return ret; 427 } 428 else 429 LogPrint (eLogError, "EdDSA verification key is not set"); 430 return false; 431 } 432 433 EDDSA25519phSigner::EDDSA25519phSigner (const uint8_t * signingPrivateKey): 434 EDDSA25519Signer (signingPrivateKey) 435 { 436 } 437 438 void EDDSA25519phSigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const 439 { 440 auto pkey = GetPkey (); 441 if (pkey) 442 { 443 uint8_t digest[64]; 444 SHA512 (buf, len, digest); 445 EVP_MD_CTX * ctx = EVP_MD_CTX_create (); 446 size_t l = 64; 447 uint8_t sig[64]; 448 EVP_DigestSignInit_ex (ctx, NULL, NULL, NULL, NULL, pkey, EDDSA25519phParams); 449 if (!EVP_DigestSign (ctx, sig, &l, digest, 64)) 450 LogPrint (eLogError, "EdDSA signing failed"); 451 memcpy (signature, sig, 64); 452 EVP_MD_CTX_destroy (ctx); 453 } 454 else 455 LogPrint (eLogError, "EdDSA signing key is not set"); 456 } 457 #endif 458 459 #if OPENSSL_PQ 460 461 MLDSA44Verifier::MLDSA44Verifier (): 462 m_Pkey (nullptr) 463 { 464 } 465 466 MLDSA44Verifier::~MLDSA44Verifier () 467 { 468 EVP_PKEY_free (m_Pkey); 469 } 470 471 void MLDSA44Verifier::SetPublicKey (const uint8_t * signingKey) 472 { 473 if (m_Pkey) 474 { 475 EVP_PKEY_free (m_Pkey); 476 m_Pkey = nullptr; 477 } 478 OSSL_PARAM params[] = 479 { 480 OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PUB_KEY, (uint8_t *)signingKey, GetPublicKeyLen ()), 481 OSSL_PARAM_END 482 }; 483 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "ML-DSA-44", NULL); 484 if (ctx) 485 { 486 EVP_PKEY_fromdata_init (ctx); 487 EVP_PKEY_fromdata (ctx, &m_Pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params); 488 EVP_PKEY_CTX_free (ctx); 489 } 490 else 491 LogPrint (eLogError, "MLDSA44 can't create PKEY context"); 492 } 493 494 bool MLDSA44Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 495 { 496 bool ret = false; 497 if (m_Pkey) 498 { 499 EVP_PKEY_CTX * vctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); 500 if (vctx) 501 { 502 EVP_SIGNATURE * sig = EVP_SIGNATURE_fetch (NULL, "ML-DSA-44", NULL); 503 if (sig) 504 { 505 int encode = 1; 506 OSSL_PARAM params[] = 507 { 508 OSSL_PARAM_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &encode), 509 OSSL_PARAM_END 510 }; 511 EVP_PKEY_verify_message_init (vctx, sig, params); 512 ret = EVP_PKEY_verify (vctx, signature, GetSignatureLen (), buf, len) == 1; 513 EVP_SIGNATURE_free (sig); 514 } 515 EVP_PKEY_CTX_free (vctx); 516 } 517 else 518 LogPrint (eLogError, "MLDSA44 can't obtain context from PKEY"); 519 } 520 else 521 LogPrint (eLogError, "MLDSA44 verification key is not set"); 522 return ret; 523 } 524 525 MLDSA44Signer::MLDSA44Signer (const uint8_t * signingPrivateKey): 526 m_Pkey (nullptr) 527 { 528 OSSL_PARAM params[] = 529 { 530 OSSL_PARAM_octet_string (OSSL_PKEY_PARAM_PRIV_KEY, (uint8_t *)signingPrivateKey, MLDSA44_PRIVATE_KEY_LENGTH), 531 OSSL_PARAM_END 532 }; 533 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "ML-DSA-44", NULL); 534 if (ctx) 535 { 536 EVP_PKEY_fromdata_init (ctx); 537 EVP_PKEY_fromdata (ctx, &m_Pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, params); 538 EVP_PKEY_CTX_free (ctx); 539 } 540 else 541 LogPrint (eLogError, "MLDSA44 can't create PKEY context"); 542 } 543 544 MLDSA44Signer::~MLDSA44Signer () 545 { 546 if (m_Pkey) EVP_PKEY_free (m_Pkey); 547 } 548 549 void MLDSA44Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const 550 { 551 if (m_Pkey) 552 { 553 EVP_PKEY_CTX * sctx = EVP_PKEY_CTX_new_from_pkey (NULL, m_Pkey, NULL); 554 if (sctx) 555 { 556 EVP_SIGNATURE * sig = EVP_SIGNATURE_fetch (NULL, "ML-DSA-44", NULL); 557 if (sig) 558 { 559 int encode = 1; 560 OSSL_PARAM params[] = 561 { 562 OSSL_PARAM_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &encode), 563 OSSL_PARAM_END 564 }; 565 EVP_PKEY_sign_message_init (sctx, sig, params); 566 size_t siglen = MLDSA44_SIGNATURE_LENGTH; 567 EVP_PKEY_sign (sctx, signature, &siglen, buf, len); 568 EVP_SIGNATURE_free (sig); 569 } 570 EVP_PKEY_CTX_free (sctx); 571 } 572 else 573 LogPrint (eLogError, "MLDSA44 can't obtain context from PKEY"); 574 } 575 else 576 LogPrint (eLogError, "MLDSA44 signing key is not set"); 577 } 578 579 #endif 580 } 581 }