Hello,
I have 3rd party custom ECC library, that can do ECDSA verification and uses secp256r1 compressed public key (33bytes) to do so - all works fine.
Now I want to migrate to mbedTLS, to also benefit of other crypto schemes, hence use of mbedtls ECDSA was a natural way to go. Here I need (as I understand) PEM parser or optionally public key in uncompressed format (0x04 | X | Y).
Problem is that loading of the key seems to work (func returns 0), but verification fails with -20450, indicating (if I well understood) invalid signature.
Test data. PRIVATE KEY: -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgKNqyWso/lMuTlTE6 ll47Jboqq/Iz7OYDrr7TuXN+s2ChRANCAARNgfaUcxLoWWG01ekJFiqB8ujMgnHz P320ZgiZErH6zKjlB9EovIHrchj0240+EIpFios+2uM609FgRvu3+NrT -----END PRIVATE KEY-----
PUBLIC KEY: -----BEGIN PUBLIC KEY----- MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADTYH2lHMS6FlhtNXpCRYqgfLozIJx 8z99tGYImRKx+sw= -----END PUBLIC KEY-----
PUBLIC KEY UNCOMPRESSED SEC1: 0x4,0x4d,0x81,0xf6,0x94,0x73,0x12,0xe8,0x59,0x61,0xb4,0xd5,0xe9,0x9,0x16,0x2a,0x81,0xf2,0xe8,0xcc,0x82,0x71,0xf3,0x3f,0x7d,0xb4,0x66,0x8,0x99,0x12,0xb1,0xfa,0xcc,0xa8,0xe5,0x7,0xd1,0x28,0xbc,0x81,0xeb,0x72,0x18,0xf4,0xdb,0x8d,0x3e,0x10,0x8a,0x45,0x8a,0x8b,0x3e,0xda,0xe3,0x3a,0xd3,0xd1,0x60,0x46,0xfb,0xb7,0xf8,0xda,0xd3
PUBLIC KEY COMPRESSED SEC1: 0x3,0x4d,0x81,0xf6,0x94,0x73,0x12,0xe8,0x59,0x61,0xb4,0xd5,0xe9,0x9,0x16,0x2a,0x81,0xf2,0xe8,0xcc,0x82,0x71,0xf3,0x3f,0x7d,0xb4,0x66,0x8,0x99,0x12,0xb1,0xfa,0xcc
INPUT STRING in TEXT format: "This is my input data" (remove quotes)
INPUT STRING in HEX format: 0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x6d,0x79,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x64,0x61,0x74,0x61
SHA256 of INPUT STRING: 0xa7,0x3f,0x26,0xf4,0xa1,0xe4,0x61,0x61,0x0,0x1a,0x29,0xdf,0xd2,0xaf,0x7d,0xa,0x25,0x91,0xbb,0xcc,0x1f,0xbc,0xfb,0xdb,0x43,0xdb,0x57,0xf9,0x8d,0x94,0xeb,0x81 (x-checked here: https://emn178.github.io/online-tools/sha256.html)
SIGNATURE of HASH signed with PRIVATE KEY: 0x80,0xe6,0xf5,0x97,0x6a,0x66,0xa2,0xe2,0x9a,0xd7,0x7f,0x9a,0x9b,0x3e,0x2b,0xde,0x1f,0x7c,0x3,0xb3,0x1,0xb8,0x6f,0xd8,0xf6,0xf,0x27,0x38,0x63,0x3,0x54,0x74,0x76,0x6d,0x1b,0x97,0xf0,0xbc,0xc5,0xd2,0x4b,0xae,0xf0,0x34,0xab,0x86,0xbd,0x55,0x0,0x8a,0x4c,0x9f,0x4e,0xa5,0x53,0x89,0xe8,0x0,0xb9,0x83,0x24,0x87,0x98,0x1
My custom library code looks like - this one works as expected: if (ecdsa_verify(public_key_compressed_33_bytes_array, hash_of_input_string, signature_signed_with_private_key)) { printf("Custom ECDSA lib verification is OK\r\n"); }
My mbedTLS code looks like: ``` /* mbedTLS */ printf("mbedTLS way start\r\n"); mbedtls_ecdsa_init(&ctx); mbedtls_ecp_group_load(&ctx.private_grp, MBEDTLS_ECP_DP_SECP256R1); res = mbedtls_ecp_point_read_binary(&ctx.private_grp, &ctx.private_Q, ecc_public_key_uncompressed_bin, sizeof(ecc_public_key_uncompressed_bin)); if (res != 0) { printf("ECP point read binary failed: %d\r\n", res); }
res = mbedtls_ecdsa_read_signature(&ctx, data_raw_hash_digest, sizeof(data_raw_hash_digest), signature, sizeof(signature)); if (res == 0) { printf("mbedTLS Verification is OK...\r\n"); } else { printf("mbedTLS Verification failed...: %d\r\n", res); } printf("mbedTLS way end\r\n"); ```
and it always fails with error code -20450. while loading keys function goes through well.
Am I wrongly loading the keys?
Hi Tilen,
There are two common formats for ECDSA signatures: “raw” and “ASN.1”. Mathematically, an ECDSA signature consists of two numbers, conventionally written (r, s). The raw format has r and s concatenated with a fixed size, 32 bytes each, so the signature is always 64 bytes. The ASN.1 format has extra metadata and strips leading zeros, which means the signature can be up to 72 bytes but sometimes a little shorter.
mbedtls_ecdsa_read_signature() and mbedtls_pk_verify() only support the ASN.1 format, which is the one used in X.509 and TLS. If you have a signature in the raw format, you can either use the PSA API (psa_import_key(), psa_verify_hash() on the raw-format signature, psa_destroy_key()), or convert r and s to bignum objects and call mbedtls_ecdsa_verify().
Hope this helps.
mbed-tls@lists.trustedfirmware.org