Hi,
I'm running into a signature verification issue with ECDSA.
I've generated test values with python and have a working signature verification:
--------- Python ---------
In [66]: sig_bytes.hex()
Out[66]: '30440220704fb7e4e51dc0f2f9bb0a3645d433bdd7ea23dff5e0e231449261f043c645db02203e648d4924c56b14004d984bcacf954e47ae6109db15597695664d06c0b782c2'
In [67]: statement
Out[67]: b'1:VALID_SESSION:2:xxxx'
In [68]: key = load_pem_public_key(b'-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWaBFEuO91YcVK6mJqDtjCvRT8cE7\nfjKNmOxU/wYzSPVHyyZ0IhxY9
...: UFwZKWO1iEWkeReHK/SNRk2rtvX4qX44g==\n-----END PUBLIC KEY-----\n')
In [69]: key.verify(sig_bytes, statement, primitives.asymmetric.ec.ECDSA(primitives.hashes.SHA256()))
Success
----------------------------
And have the following code on the mbedTLS C side which fails on mbedtls_ecdsa_read_signature():
--------- MbedTLS ---------
uint8_t sha256_digest_buff[SHA256_DIGEST_BYTES] = { 0 };
uint8_t* message = (uint8_t*)"1:VALID_SESSION:2:xxxx";
uint8_t* public_key_pem = (uint8_t*)"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc8uijCCOayvXQz5+2fjVjAbNraYf\nReDKcN8p5ttPedCXxr8A9rGcmA89pFcmpuDRvZgx+qiRC/pNcs0kqy1VVQ==\n-----END PUBLIC KEY-----\n";
uint8_t signature[70] = {0x30, 0x44, 0x02, 0x20, 0x70, 0x4f, 0xb7, 0xe4, 0xe5, 0x1d, 0xc0, 0xf2, 0xf9, 0xbb, 0x0a, 0x36, 0x45, 0xd4, 0x33, 0xbd, 0xd7, 0xea, 0x23, 0xdf, 0xf5, 0xe0, 0xe2, 0x31, 0x44, 0x92, 0x61, 0xf0, 0x43, 0xc6, 0x45, 0xdb, 0x02, 0x20, 0x3e, 0x64, 0x8d, 0x49, 0x24, 0xc5, 0x6b, 0x14, 0x00, 0x4d, 0x98, 0x4b, 0xca, 0xcf, 0x95, 0x4e, 0x47, 0xae, 0x61, 0x09, 0xdb, 0x15, 0x59, 0x76, 0x95, 0x66, 0x4d, 0x06, 0xc0, 0xb7, 0x82, 0xc2};
[...]
int mbedtls_status = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pk_context pubkey_ctx;
mbedtls_ecdsa_context ecdsa_ctx;
mbedtls_ecp_curve_info *curve_info = NULL;
/* Create public key context */
mbedtls_pk_init(&pubkey_ctx);
/* Create ecdsa context */
mbedtls_ecdsa_init(&ecdsa_ctx);
/* Parse public key */
if ((mbedtls_status = mbedtls_pk_parse_public_key(&pubkey_ctx,
pubkey_pem,
pubkey_pem_len)) != 0) {
ERRORF("Failure failure parsing PEM-encoded ecdsa-p256r1 public key, mbedTLS status: %d", mbedtls_status);
ret = E_INVAL_PUBKEY;
goto cleanup;
}
/* Hash the message with sha256 */
if ((mbedtls_status = mbedtls_sha256_ret(message,
message_len,
sha256_digest_buff,
0 /* Not 224 bits hashing */
)) != 0) {
ERRORF("Failure sha256-hashing message before ecdsa-p256r1 signature verification, mbedTLS status: %d", mbedtls_status);
ret = E_FAILED_HASH;
goto cleanup;
}
/* Set the public key as the ecdsa signature verification key */
if ((mbedtls_status = mbedtls_ecp_copy(&ecdsa_ctx.Q, &mbedtls_pk_ec(pubkey_ctx)->Q)) != 0 ) {
ERRORF("Failure copying ecdsa-p256r1 public key to ecdsa context, mbedTLS status: %d", mbedtls_status);
ret = E_UNKNOWN;
goto cleanup;
}
if ((mbedtls_status = mbedtls_ecp_group_copy(&ecdsa_ctx.grp, &mbedtls_pk_ec(pubkey_ctx)->grp)) != 0 ) {
ERRORF("Failure copying ecdsa-p256r1 public key group to ecdsa context, mbedTLS status: %d", mbedtls_status);
ret = E_UNKNOWN;
goto cleanup;
}
/* Verify ecdsa-p256r1 signature verification */
if ((mbedtls_status = mbedtls_ecdsa_read_signature(&ecdsa_ctx,
sha256_digest_buff,
sizeof(sha256_digest_buff),
signature,
signature_len)) != 0) {
ERRORF("Failure verifying ecdsa-p256r1 signature against message, mbedTLS status: %d", mbedtls_status);
ret = E_INVALID_SIG;
goto cleanup;
}
/* Success */
ret = E_SUCCESS;
----------------------------
Also, `mbedtls_ecp_curve_info_from_grp_id(
ecdsa_ctx.grp.id )->name` yields the right curve prior to the signature verification. I must be missing something in the process.
Would love to get some input, thanks a lot!
--
Nassim Eddequiouaq