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 <mbed-tls@lists.trustedfirmware.org> wrote:
Hi Roshini,

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():
https://github.com/ARMmbed/mbedtls/blob/mbedtls-2.24.0/library/psa_crypto.c#L3533

Hope this helps,

--
Gilles Peskine
Mbed TLS developer

On 22/11/2020 10:12, ROSHINI DEVI via mbed-tls wrote:
> Hello all,
>
> 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
>
> Thanks,
> Roshini
>


--
mbed-tls mailing list
mbed-tls@lists.trustedfirmware.org
https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls