diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index c8a8f87e6..ef92b00ef 100755 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1661,7 +1661,7 @@ static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp) #ifdef WOLFSSL_SMALL_STACK byte* buf; #else - byte buf[ECC_MAXSIZE]; + byte buf[ECC_MAXSIZE_GEN]; #endif int keysize; int po_init = 0; /* prime order Init flag for clear */ @@ -1670,22 +1670,23 @@ static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp) return ECC_BAD_ARG_E; #ifdef WOLFSSL_SMALL_STACK - buf = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) return MEMORY_E; #endif key->idx = -1; key->dp = dp; - keysize = dp->size; + + /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ + /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ + keysize = dp->size + 8; /* allocate ram */ base = NULL; /* make up random string */ err = wc_RNG_GenerateBlock(rng, buf, keysize); - if (err == 0) - buf[0] |= 0x0c; /* setup the key variables */ if (err == 0) { @@ -1728,6 +1729,12 @@ static int wc_ecc_make_key_ex(WC_RNG* rng, ecc_key* key, const ecc_set_type* dp) if (err == MP_OKAY) err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); + /* quick sanity check to make sure we're not dealing with a 0 key */ + if (err == MP_OKAY) { + if (MP_YES == mp_iszero(&key->k)) + err = MP_ZERO_E; + } + /* the key should be smaller than the order of base point */ if (err == MP_OKAY) { if (mp_cmp(&key->k, &order) != MP_LT) diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 0075f0d14..6abbf38c7 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -34,19 +34,20 @@ #endif enum { - ECC_PUBLICKEY = 1, - ECC_PRIVATEKEY = 2, - ECC_MAXNAME = 16, /* MAX CURVE NAME LENGTH */ - SIG_HEADER_SZ = 6, /* ECC signature header size */ - ECC_BUFSIZE = 256, /* for exported keys temp buffer */ - ECC_MINSIZE = 20, /* MIN Private Key size */ - ECC_MAXSIZE = 66 /* MAX Private Key size */ + ECC_PUBLICKEY = 1, + ECC_PRIVATEKEY = 2, + ECC_MAXNAME = 16, /* MAX CURVE NAME LENGTH */ + SIG_HEADER_SZ = 6, /* ECC signature header size */ + ECC_BUFSIZE = 256, /* for exported keys temp buffer */ + ECC_MINSIZE = 20, /* MIN Private Key size */ + ECC_MAXSIZE = 66, /* MAX Private Key size */ + ECC_MAXSIZE_GEN = 74 /* MAX Buffer size required when generating ECC keys*/ }; /* ECC set type defined a NIST GF(p) curve */ typedef struct { - int size; /* The size of the curve in octets */ + int size; /* The size of the curve in octets */ int nid; /* id of this curve */ const char* name; /* name of this curve */ const char* prime; /* prime that defines the field, curve is in (hex) */