How to extract ECC signature bytes from EVP_DigestSignFinal's signature

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to extract ECC signature bytes from EVP_DigestSignFinal's signature

axisofevil
I had been using the lower level ECDSA_do_sign for EC signing but had to migrate to EVP functions.

If I get signature from EVP_DigestSignFinal(), what format is the signature, and how can I extract the 'real' bytes? I'd expect 32 bytes each for r and s.  I need the 'real bytes' for compatibility.

Thanks, dB
Reply | Threaded
Open this post in threaded view
|

Re: How to extract ECC signature bytes from EVP_DigestSignFinal's signature

axisofevil
I dug into source - it's in DER format so a sleezy hacked function is this: ( I use curve NID_X9_62_prime256v1 )
ECDSA_SIG * sig
                BIGNUM * r;
                BIGNUM * s;

                /* A correct DER-encoded signature has the following form:

                    0x30: a header byte indicating a compound structure.
                    A 1-byte length descriptor for all what follows.
                    0x02: a header byte indicating an integer.
                    A 1-byte length descriptor for the R value
                    The R coordinate, as a big-endian integer.
                    0x02: a header byte indicating an integer.
                    A 1-byte length descriptor for the S value.
                    The S coordinate, as a big-endian integer.
                */

                r = BN_bin2bn( src+ 4, 32, NULL ); // create new bn here
                s = BN_bin2bn( src+ 4 +32 + 2, 32, NULL );

                if(!BN_copy(sig->r, r)) goto err;
                if(!BN_copy(sig->s, s)) goto err;

Reply | Threaded
Open this post in threaded view
|

Re: How to extract ECC signature bytes from EVP_DigestSignFinal's signature

Dr. Stephen Henson
On Tue, Mar 18, 2014, axisofevil wrote:

> I dug into source - it's in DER format so a sleezy hacked function is this: (
> I use curve NID_X9_62_prime256v1 )
> ECDSA_SIG * sig
>                 BIGNUM * r;
> BIGNUM * s;
>
> /* A correct DER-encoded signature has the following form:
>
>    0x30: a header byte indicating a compound structure.
>    A 1-byte length descriptor for all what follows.
>    0x02: a header byte indicating an integer.
>    A 1-byte length descriptor for the R value
>    The R coordinate, as a big-endian integer.
>    0x02: a header byte indicating an integer.
>    A 1-byte length descriptor for the S value.
>    The S coordinate, as a big-endian integer.
> */
>
> r = BN_bin2bn( src+ 4, 32, NULL ); // create new bn here
> s = BN_bin2bn( src+ 4 +32 + 2, 32, NULL );
>
> if(!BN_copy(sig->r, r)) goto err;
> if(!BN_copy(sig->s, s)) goto err;
>
>

That wont always work because the number of octets in the ASN1 Integer isn't
always the same. The ASN1 function d2i_ECDSA_SIG will corerectly parse the
output.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: How to extract ECC signature bytes from EVP_DigestSignFinal's signature

Jeffrey Walton-3
In reply to this post by axisofevil
On Tue, Mar 18, 2014 at 1:02 PM, axisofevil <[hidden email]> wrote:

> I dug into source - it's in DER format so a sleezy hacked function is this: (
> I use curve NID_X9_62_prime256v1 )
> ECDSA_SIG * sig
>                 BIGNUM * r;
>                 BIGNUM * s;
>
>                 /* A correct DER-encoded signature has the following form:
>
>                     0x30: a header byte indicating a compound structure.
>                     A 1-byte length descriptor for all what follows.
>                     0x02: a header byte indicating an integer.
>                     A 1-byte length descriptor for the R value
>                     The R coordinate, as a big-endian integer.
>                     0x02: a header byte indicating an integer.
>                     A 1-byte length descriptor for the S value.
>                     The S coordinate, as a big-endian integer.
>                 */
>
>                 r = BN_bin2bn( src+ 4, 32, NULL ); // create new bn here
>                 s = BN_bin2bn( src+ 4 +32 + 2, 32, NULL );
>
>                 if(!BN_copy(sig->r, r)) goto err;
>                 if(!BN_copy(sig->s, s)) goto err;
Be aware you can have one of two formats depending on your platform
and they dont interop on their own.

First is the signature format of IEEE P1363, which is a simple
concatenation of {r,s}. If the has is 20 bytes, then the signature is
40 bytes. Its used by OpenPGP, Crypto++, etc.

Second is the DER encoding:

    SEQUENCE ::= {
      r INTEGER,
      s INTEGER }

It is used by OpenSSL, Java, etc.

Jeff
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]