use EVP_DigestVerify/EVP_DigestSign for ECDSA and DSA signatures if openssl 3

This commit is contained in:
orignal 2025-06-12 13:35:47 -04:00
parent 5bef987529
commit 5974d2b5ac

View file

@ -42,22 +42,19 @@ namespace crypto
bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {
// calculate SHA1 digest
uint8_t digest[20], sign[48];
SHA1 (buf, len, digest);
// signature // signature
DSA_SIG * sig = DSA_SIG_new(); DSA_SIG * sig = DSA_SIG_new();
DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL)); DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL));
// to DER format // to DER format
uint8_t sign[DSA_SIGNATURE_LENGTH + 8];
uint8_t * s = sign; uint8_t * s = sign;
auto l = i2d_DSA_SIG (sig, &s); auto l = i2d_DSA_SIG (sig, &s);
DSA_SIG_free(sig); DSA_SIG_free(sig);
// verify // verify
auto ctx = EVP_PKEY_CTX_new (m_PublicKey, NULL); EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_PKEY_verify_init(ctx); EVP_DigestVerifyInit (ctx, NULL, EVP_sha1(), NULL, m_PublicKey);
EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()); auto ret = EVP_DigestVerify (ctx, sign, l, buf, len);
bool ret = EVP_PKEY_verify(ctx, sign, l, digest, 20); EVP_MD_CTX_destroy (ctx);
EVP_PKEY_CTX_free(ctx);
return ret; return ret;
} }
@ -76,13 +73,13 @@ namespace crypto
void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{ {
uint8_t digest[20], sign[48]; uint8_t sign[DSA_SIGNATURE_LENGTH + 8];
SHA1 (buf, len, digest); size_t l = DSA_SIGNATURE_LENGTH + 8;
auto ctx = EVP_PKEY_CTX_new (m_PrivateKey, NULL); EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_PKEY_sign_init(ctx); EVP_DigestSignInit (ctx, NULL, EVP_sha1(), NULL, m_PrivateKey);
EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()); EVP_DigestSign (ctx, sign, &l, buf, len);
size_t l = 48; EVP_MD_CTX_destroy (ctx);
EVP_PKEY_sign(ctx, sign, &l, digest, 20); // decode r and s
const uint8_t * s1 = sign; const uint8_t * s1 = sign;
DSA_SIG * sig = d2i_DSA_SIG (NULL, &s1, l); DSA_SIG * sig = d2i_DSA_SIG (NULL, &s1, l);
const BIGNUM * r, * s; const BIGNUM * r, * s;
@ -90,7 +87,6 @@ namespace crypto
bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2); bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2);
bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2); bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2);
DSA_SIG_free(sig); DSA_SIG_free(sig);
EVP_PKEY_CTX_free(ctx);
} }
void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
@ -221,40 +217,20 @@ namespace crypto
bool ECDSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const bool ECDSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {
bool ret = false;
EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new (m_PublicKey, NULL);
if (!ctx)
{
LogPrint (eLogError, "ECDSA can't create verification context");
return false;
}
// digest
unsigned int digestLen = EVP_MD_size(m_Hash);
std::vector<uint8_t> digest(digestLen), sign(GetSignatureLen () + 8);
EVP_MD_CTX * mdCtx = EVP_MD_CTX_create ();
EVP_DigestInit (mdCtx, m_Hash);
EVP_DigestUpdate (mdCtx, buf, len);
EVP_DigestFinal (mdCtx, digest.data (), &digestLen);
EVP_MD_CTX_destroy (mdCtx);
// signature // signature
ECDSA_SIG * sig = ECDSA_SIG_new(); ECDSA_SIG * sig = ECDSA_SIG_new();
ECDSA_SIG_set0 (sig, BN_bin2bn (signature, GetSignatureLen ()/2, NULL), ECDSA_SIG_set0 (sig, BN_bin2bn (signature, GetSignatureLen ()/2, NULL),
BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL)); BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL));
// to DER format // to DER format
std::vector<uint8_t> sign(GetSignatureLen () + 8);
uint8_t * s = sign.data (); uint8_t * s = sign.data ();
auto l = i2d_ECDSA_SIG (sig, &s); auto l = i2d_ECDSA_SIG (sig, &s);
ECDSA_SIG_free(sig); ECDSA_SIG_free(sig);
//verify // verify
if (EVP_PKEY_verify_init (ctx) > 0 && EVP_PKEY_public_check (ctx) > 0) EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
{ EVP_DigestVerifyInit (ctx, NULL, m_Hash, NULL, m_PublicKey);
if (EVP_PKEY_CTX_set_signature_md (ctx, m_Hash) > 0) auto ret = EVP_DigestVerify (ctx, sign.data (), l, buf, len);
ret = EVP_PKEY_verify (ctx, sign.data (), l, digest.data (), digestLen); EVP_MD_CTX_destroy (ctx);
else
LogPrint (eLogError, "ECDSA can't set signature md");
}
else
LogPrint (eLogError, "ECDSA invalid public key");
EVP_PKEY_CTX_free (ctx);
return ret; return ret;
} }
@ -291,26 +267,13 @@ namespace crypto
void ECDSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const void ECDSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{ {
unsigned int digestLen = EVP_MD_size(m_Hash); std::vector<uint8_t> sign(m_KeyLen + 8);
std::vector<uint8_t> digest(digestLen), sign(m_KeyLen + 8);
EVP_MD_CTX * mdCtx = EVP_MD_CTX_create ();
EVP_DigestInit (mdCtx, m_Hash);
EVP_DigestUpdate (mdCtx, buf, len);
EVP_DigestFinal (mdCtx, digest.data (), &digestLen);
EVP_MD_CTX_destroy (mdCtx);
EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new (m_PrivateKey, NULL);
if (!ctx)
{
LogPrint (eLogError, "ECDSA can't create signing context");
return;
}
if (EVP_PKEY_sign_init (ctx) > 0 && EVP_PKEY_private_check (ctx) > 0)
{
if (EVP_PKEY_CTX_set_signature_md (ctx, m_Hash) > 0)
{
size_t l = sign.size (); size_t l = sign.size ();
EVP_PKEY_sign (ctx, sign.data (), &l, digest.data (), digest.size ()); EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_DigestSignInit (ctx, NULL, m_Hash, NULL, m_PrivateKey);
EVP_DigestSign (ctx, sign.data(), &l, buf, len);
EVP_MD_CTX_destroy (ctx);
// decode r and s
const uint8_t * s1 = sign.data (); const uint8_t * s1 = sign.data ();
ECDSA_SIG * sig = d2i_ECDSA_SIG (NULL, &s1, l); ECDSA_SIG * sig = d2i_ECDSA_SIG (NULL, &s1, l);
const BIGNUM * r, * s; const BIGNUM * r, * s;
@ -319,13 +282,6 @@ namespace crypto
bn2buf (s, signature + m_KeyLen/2, m_KeyLen/2); bn2buf (s, signature + m_KeyLen/2, m_KeyLen/2);
ECDSA_SIG_free(sig); ECDSA_SIG_free(sig);
} }
else
LogPrint (eLogError, "ECDSA can't set signature md");
}
else
LogPrint (eLogError, "ECDSA invalid private key");
EVP_PKEY_CTX_free (ctx);
}
void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{ {