diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ef4f38f99..abb451c43 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15428,7 +15428,51 @@ int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) } -/* Der Decode ECC-DSA Signature, r & s stored as big ints */ +/* Der Decode ECC-DSA Signature with R/S as unsigned bin */ +int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen, + byte* s, word32* sLen) +{ + int ret; + word32 idx = 0; + int len = 0; + + if (GetSequence(sig, &idx, &len, sigLen) < 0) { + return ASN_ECC_KEY_E; + } + +#ifndef NO_STRICT_ECDSA_LEN + /* enable strict length checking for signature */ + if (sigLen != idx + (word32)len) { + return ASN_ECC_KEY_E; + } +#else + /* allow extra signature bytes at end */ + if ((word32)len > (sigLen - idx)) { + return ASN_ECC_KEY_E; + } +#endif + + ret = GetASNInt(sig, &idx, &len, sigLen); + if (ret != 0) + return ret; + if (rLen) + *rLen = len; + if (r) + XMEMCPY(r, (byte*)sig + idx, len); + idx += len; + + ret = GetASNInt(sig, &idx, &len, sigLen); + if (ret != 0) + return ret; + if (sLen) + *sLen = len; + if (s) + XMEMCPY(s, (byte*)sig + idx, len); + + return ret; +} + + int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) { word32 idx = 0; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index bcc77b89f..f97f32f5d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -8040,69 +8040,10 @@ int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz, int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, byte* s, word32* sLen) { - int err; - int tmp_valid = 0; - word32 x = 0; -#ifdef WOLFSSL_SMALL_STACK - mp_int* rtmp = NULL; - mp_int* stmp = NULL; -#else - mp_int rtmp[1]; - mp_int stmp[1]; -#endif - if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL) return ECC_BAD_ARG_E; -#ifdef WOLFSSL_SMALL_STACK - rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); - if (rtmp == NULL) - return MEMORY_E; - stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); - if (stmp == NULL) { - XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); - return MEMORY_E; - } -#endif - - err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp); - - /* rtmp and stmp are initialized */ - if (err == MP_OKAY) { - tmp_valid = 1; - - /* extract r */ - x = mp_unsigned_bin_size(rtmp); - if (*rLen < x) - err = BUFFER_E; - } - if (err == MP_OKAY) { - *rLen = x; - err = mp_to_unsigned_bin(rtmp, r); - } - - /* extract s */ - if (err == MP_OKAY) { - x = mp_unsigned_bin_size(stmp); - if (*sLen < x) - err = BUFFER_E; - - if (err == MP_OKAY) { - *sLen = x; - err = mp_to_unsigned_bin(stmp, s); - } - } - - if (tmp_valid) { - mp_clear(rtmp); - mp_clear(stmp); - } -#ifdef WOLFSSL_SMALL_STACK - XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); - XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); -#endif - - return err; + return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen); } #endif /* !NO_ASN */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index f02ef3af9..261d4b4cd 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1164,6 +1164,8 @@ WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); mp_int* s); WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s); + WOLFSSL_LOCAL int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, + byte* r, word32* rLen, byte* s, word32* sLen); #endif #if defined HAVE_ECC && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) WOLFSSL_API int EccEnumToNID(int n);