Berry crypto.EC_P256 ECDSA signature ASN.1 (#17740)

This commit is contained in:
s-hadinger 2023-01-18 20:50:01 +01:00 committed by GitHub
parent bc1b35d2ff
commit 61be95841f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 0 deletions

View File

@ -29,6 +29,8 @@ extern int m_ec_p256_pubkey(bvm *vm);
extern int m_ec_p256_sharedkey(bvm *vm);
extern int m_ec_p256_ecdsa_sign_sha256(bvm *vm);
extern int m_ec_p256_ecdsa_verify_sha256(bvm *vm);
extern int m_ec_p256_ecdsa_sign_sha256_asn1(bvm *vm);
extern int m_ec_p256_ecdsa_verify_sha256_asn1(bvm *vm);
extern int m_ec_p256_mod(bvm *vm);
extern int m_ec_p256_neg(bvm *vm);
extern int m_ec_p256_muladd(bvm *vm);
@ -161,6 +163,8 @@ class be_class_ec_p256 (scope: global, name: EC_P256) {
shared_key, static_func(m_ec_p256_sharedkey)
ecdsa_sign_sha256, static_func(m_ec_p256_ecdsa_sign_sha256)
ecdsa_verify_sha256, static_func(m_ec_p256_ecdsa_verify_sha256)
ecdsa_sign_sha256_asn1, static_func(m_ec_p256_ecdsa_sign_sha256_asn1)
ecdsa_verify_sha256_asn1, static_func(m_ec_p256_ecdsa_verify_sha256_asn1)
mod, static_func(m_ec_p256_mod)
neg, static_func(m_ec_p256_neg)
muladd, static_func(m_ec_p256_muladd)

View File

@ -630,6 +630,71 @@ extern "C" {
}
be_raise(vm, kTypeError, nullptr);
}
// crypto.EC_P256().ecdsa_sign_sha256_asn1(my_private_key:bytes(32), message:bytes()) -> bytes()
// Sign with ECDSA SHA256, result in ASN.1 format for CSR and certificate
int32_t m_ec_p256_ecdsa_sign_sha256_asn1(bvm *vm);
int32_t m_ec_p256_ecdsa_sign_sha256_asn1(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isbytes(vm, 1) && be_isbytes(vm, 2)) {
size_t sk_len = 0;
uint8_t * sk = (uint8_t*) be_tobytes(vm, 1, &sk_len);
size_t msg_len = 0;
const uint8_t * msg = (const uint8_t*) be_tobytes(vm, 2, &msg_len);
if (sk_len != 32) {
be_raise(vm, "value_error", "Key size invalid");
}
// first compute SHA-256 hash on the message
uint8_t hash[32];
br_sha256_context ctx;
br_sha256_init(&ctx);
br_sha256_update(&ctx, msg, msg_len);
br_sha256_out(&ctx, hash);
// run ECDSA on hash
uint8_t sign[72]; // hard limit for ECDSA SHA256 ASN.1 as per bearssl documentation
br_ec_private_key br_sk = { BR_EC_secp256r1, sk, 32 };
size_t sign_len = br_ecdsa_i15_sign_asn1(&BR_EC_P256_IMPL, &br_sha256_vtable, hash, &br_sk, sign);
be_pushbytes(vm, sign, sign_len);
be_return(vm);
}
be_raise(vm, kTypeError, nullptr);
}
// `crypto.EC_P256().ecdsa_verify_sha256_asn1(public_key:bytes(65), message:bytes(), hash:bytes()) -> bool`
// Verify signature with ECDSA SHA256 with signature in ASN.1 format
int32_t m_ec_p256_ecdsa_verify_sha256_asn1(bvm *vm);
int32_t m_ec_p256_ecdsa_verify_sha256_asn1(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 3 && be_isbytes(vm, 1) && be_isbytes(vm, 2) && be_isbytes(vm, 3)) {
size_t pk_len = 0;
uint8_t * pk = (uint8_t*) be_tobytes(vm, 1, &pk_len);
size_t msg_len = 0;
const uint8_t * msg = (const uint8_t*) be_tobytes(vm, 2, &msg_len);
if (pk_len != 65) {
be_raise(vm, "value_error", "Key size invalid");
}
size_t sig_len = 0;
const uint8_t * sig = (const uint8_t*) be_tobytes(vm, 3, &sig_len);
// first compute SHA-256 hash on the message
uint8_t hash[32];
br_sha256_context ctx;
br_sha256_init(&ctx);
br_sha256_update(&ctx, msg, msg_len);
br_sha256_out(&ctx, hash);
// run ECDSA on hash
br_ec_public_key br_pk = { BR_EC_secp256r1, pk, pk_len };
uint32_t ret = br_ecdsa_i15_vrfy_asn1(&BR_EC_P256_IMPL, hash, sizeof(hash), &br_pk, sig, sig_len);
be_pushbool(vm, ret);
be_return(vm);
}
be_raise(vm, kTypeError, nullptr);
}
/* Test values
import crypto
var priv = bytes('D42A43989B67211031FF194FBA791B5C3E03F9EC10ED561A4DEB2AA7BADB4772')