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!
mbed-tls@lists.trustedfirmware.org