Thanks Gilles. I have use mbedtls_ecdsa_sign and got the raw buffer output of R & S values.
On Sun, Nov 22, 2020, 9:26 PM Gilles Peskine via mbed-tls < email@example.com> wrote:
Mathematically, an ES256 (ECDSA over the curve P256R1) signature is a pair of numbers (r,s) between 1 and an upper bound which is very slightly less than 2^256. There are two common representations for this signature. JWA uses the “raw” representation: two big-endian numbers represented each with exactly 32 bytes, concatenated together. mbedtls_ecdsa_write_signature uses the ASN.1 DER representation, which as you noticed represents each number in a type+length+value format.
The DER format removes leading zeros from the number, then adds a leading 0 bit to each number which is a sign bit (the numbers in an ECDSA signature are always positive, but DER can also represent negative numbers). Therefore each number has a roughly 1/2 chance of using 33 value bytes with a leading 0 byte (1 sign bit + 7 value bits, all 0), a 63/128 chance of using 32 value bytes, and a 1/128 chance of using 31 value bytes or less because the 7 most significant bits of the number were 0. A shorter number in an ECDSA signature is not invalid, it's a 1/128 chance (independently for each of r and s).
To get the signature in raw format with Mbed TLS, the easiest way is to use the PSA API, where the output of psa_sign_hash() for ECDSA is the raw format. With the classic Mbed TLS API, the easiest way is to call mbedtls_ecdsa_sign() or mbedtls_ecdsa_sign_det_ext() to get r and s as bignums, then use mbedtls_mpi_write_binary() to write r and s with their exact size into the output buffer. You can find an example in the internal function psa_ecdsa_sign():
Hope this helps,
-- Gilles Peskine Mbed TLS developer
On 22/11/2020 10:12, ROSHINI DEVI via mbed-tls wrote:
I need to sign the message using ES256 algorithm. After doing necessary initializations, I called API
- mbedtls_ecdsa_write_signature() API and it gave me signature in ASN1
encoded form and there was no error generated by this API. After getting the signature, I need the r & s values to create JWT Token. So, I wrote my custom function to parse the signature buffer and get the R & S values of it. It was working fine. Sometimes, I am getting an invalid signature as shown below signature DER buffer -
30 43 02 1f 31 92 8d 22 10 41 86 25 68 7f 42 81 26 0f 37 bc 7f 38 b7 d5 1a 6b 69 31 07 34 11 a6 04 e5 90 02 20 23 26 f8 b9 80 cf 2c 25 c8 04 b4 ac 43 51 6a 04 a6 af 8f 94 36 f8 cf 35 c2 94 cc df de db 92 b2
The reason for invalid is - 1st byte represents ASN1 sequence, followed by length and 3rd byter indicates it is an integer. Ideally, 4th byte indicates length of r-value, it should have been 32 or 33 bytes ( in case of padding with 00 ). You can see in the above buffer it is 0x1F ( 31 bytes ). It is really weird how it is possible to get the signature length of 31 bytes.
It is blocking me for generation of JWT token, where in RFC 7518
- https://tools.ietf.org/html/rfc7518#page-9 , it says R & S must be
32 bytes long. And, the generation is failing.
It is of high priority for me. If anyone can provide your suggestions on this issue, it would be really great. Thanks in advance
-- mbed-tls mailing list firstname.lastname@example.org https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls