This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

CRYS_ECDSA signature conversion to DER format

Hello,

we are developing on the nRF52840DK, and are using directly using the CRYS API.

Is there any API in the SDK that would encode/decode the output format of CRYS_ECDSA_Sign to an ASN1 DER-encoding?

Thanks,

Damian

Parents Reply Children
  • Thanks for your reply Einar.

    I checked the functions you proposed, and they seem to do the the job. I just have one doubt:

    The signature output format of the CRYS_ECDSA_Sign function seems to be <fixed length big-endian encoding of R>||<fixed length big-endian encoding of S>, e.g. with secp256r1 the length would be 32 bytes (this is just my educated guess, as the exact output format of the signature is not precisely documented).

    However, as the function asn1_to_ecdsa_rs does not take any argument that would indicate the maximal length of R and S (32 bytes in our example), it cannot write back the format I sketched bellow. I tested this, and if a signature produced with ECDSA-SHA256 over secp256r1 has a value zero in 0th or 32nd byte (such signatures can be observed as output of CRYS_ECDSA_Sign ), then encoding -> decoding produces a different result.

  • Hi,

    You are right about the signature format, but the signature size is twice the length of the curve, 64 byte (2 * 256 bit / 8) for secp256r1 (since it is R+S).

    I did not understand what you mean by "asn1_to_ecdsa_rs does not take any argument that would indicate the maximal length of R and S"? The forth parameter, p_rs_len is in/out and is used to indicate the buffer size as input, and is set to the actual signature (RS) length. I expect it should be 64 in this case? If this is unresolved, can you upload the ASN.1 encoded buffer you are testing with so that I can test on my side?

  • Hello Einar,

    sorry for the radio silence, the project got busy, but I can finally answer.

    You are right about the buffer length parameter, it is indeed passed, and the length of the R and S encodings can be inferred from that.

    However, ecdsa_rs_to_asn1 and asn1_to_ecdsa_rs have some problems in their code.

    In ecdsa_rs_to_asn1, the whole "R" or "S" are copied into the value part of the ASN1 integer buffer. If the integer R has a value < 2^(31*8) (i.e., its representation fits in to 31 bytes or less, then the leading zeroes are copied as well. I am not sure whether this is inline with the DER rules.

    In asn1_to_ecdsa_rs, the constant width encoding of R and S in the ecdsa buffer does not seem to be handled properly. After the tag and length of R are parsed in the asn1 buffer, the whole value is copied at the beginning of the R-part of the ecdsa buffer. If the representation of R is shorter than 32 bytes, padding zero bytes should be inserted (but they are not). Same applies for S.

    As a result, if you start with an ecdsa buffer signature that fulfills the condition signature[0]==0,
    then applying ecdsa_rs_to_asn1 to signature and then asn1_to_ecdsa_rs to the asn1 buffer yields a different result.

    Let me know if the description is not clear enough.

  • Hi Damian,

    I see. Thank you for the feedback. I have informed the SDK team so that it can be improved in a future SDK release.

Related