On Tue, Aug 6, 2019 at 11:16 AM Matt Caswell <matt@xxxxxxxxxxx> wrote: > > > > On 06/08/2019 17:00, William Roberts wrote: > > On Tue, Aug 6, 2019 at 10:56 AM Matt Caswell <matt@xxxxxxxxxxx> 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! > > Matt > > > > > >