i2d_ASN1_INTEGER zero pad

William Roberts bill.c.roberts at gmail.com
Tue Aug 6 20:26:30 UTC 2019


On Tue, Aug 6, 2019 at 11:18 AM William Roberts
<bill.c.roberts at gmail.com> wrote:
>
> On Tue, Aug 6, 2019 at 11:16 AM Matt Caswell <matt at openssl.org> wrote:
> >
> >
> >
> > On 06/08/2019 17:00, William Roberts wrote:
> > > On Tue, Aug 6, 2019 at 10:56 AM Matt Caswell <matt at openssl.org> wrote:
> > >>
> > >>
> > >>
> > >> On 06/08/2019 16:34, William Roberts wrote:
> > >>> Hi,
> > >>> I occasionally get spurious errors in my ECDSA signatures, and it
> > >>> appears that when the top byte is over 0x80 of either the R or S
> > >>> component, that I get a zero pad. I noticed all this when reading
> > >>> through the source, their was some comments (see below). I noticed a
> > >>> d2i_ASN1_UINTEGER, but I can't find a coresponding i2d_ version to
> > >>> create it. The zero pad seems to be the correct behavior, but it seems
> > >>> to be breaking things.
> > >>
> > >> As you note the zero pad is the correct behaviour.
> > >>
> > >>
> > >>> This is the link to the issue request I got filed for more details:
> > >>> https://github.com/tpm2-software/tpm2-pkcs11/issues/277
> > >>
> > >> This seems to be a problem in tmp2-pkcs11 and not OpenSSL. So its not clear to
> > >> me what your question to openssl-users is?
> > >
> > > The questions is their is a d2i_ASN1_UINTEGER exists for that zero pad
> > > issue, is their a i2d version, I couldn't find one.
> >
> > No, an i2d version does not exists. d2i_ASN1_UINTEGER exists only for
> > interoperability with broken software. From the code (crypto/asn1/a_int.c):
> >
> > /*
> >  * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
> >  * integers: some broken software can encode a positive INTEGER with its MSB
> >  * set as negative (it doesn't add a padding zero).
> >  */
> >
> > ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
> >                                 long length)
> >
> > Sine we don't want to *create* knowingly broken DER we don't provide the
> > equivalent function.
> >
>
> That's what I figured.
>
> >
> > >
> > > I guess a second question is, is their a better way to build an ECDSA
> > > signature from the R and S components, the code
> > > for ASNI sequence is something I never figured out, is their an
> > > example in ossl somewhere?
> >
> > If you have the r and s components in raw "binary" format then something like
> > this should create an OpenSSL ECDSA_SIG object (totally untested):
> >
> > ECDSA_SIG *create_ecdsa_sig(unsigned char *r, size_t rlen, unsigned char *s,
> > size_t slen)
> > {
> >     ECDSA_SIG *sig = ECDSA_SIG_new();
> >
> >     if (sig == NULL)
> >         return NULL;
> >
> >     sig->r = BN_bin2bn(r, rlen, NULL);
> >     sig->s = BN_bin2bn(s, slen, NULL);
> >
> >     if (sig->r == NULL || sig->s == NULL) {
> >         ECDSA_SIG_free(sig);
> >         return NULL;
> >     }
> >
> >     return sig;
> > }
> >
> > Once you have the ECDSA_SIG structure then encoding it as DER is simply a call
> > to i2d_ECDSA_SIG:
> >
> > https://www.openssl.org/docs/manmaster/man3/i2d_ECDSA_SIG.html
> >
>
> That's what I am looking for, thanks!
>

For completeness encase anyone else stumbles into this bit of lore, is
that pkcs11 doesn't use
the IETF ASN1 encoded scheme. While our code did occasionally suffer
from this "UNINTEGER" issue,
It actually uses a straight R + S concatenation.

However, this code will fix our tpm2-tools code.

> >
> > Matt
> >
> >
> >
> >
> >
> >


More information about the openssl-users mailing list