diff --git a/src/ssl.c b/src/ssl.c index 7edcfdd13..d6f9d75a8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17035,8 +17035,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new() DYNAMIC_TYPE_PUBLIC_KEY); if (pkey != NULL) { XMEMSET(pkey, 0, sizeof(WOLFSSL_EVP_PKEY)); + pkey->type = WOLFSSL_EVP_PKEY_DEFAULT; } - pkey->type = WOLFSSL_EVP_PKEY_DEFAULT; return pkey; } @@ -19190,6 +19190,91 @@ int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom) return ret; } + +/* SSL_SUCCESS on ok + * code is same as wolfSSL_BN_rand except for how top and bottom is handled. + * top -1 then leave most sig bit alone + * top 0 then most sig is set to 1 + * top is 1 then first two most sig bits are 1 + * + * bottom is hot then odd number */ +int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom) +{ + int ret = 0; + int len = bits / 8; + int initTmpRng = 0; + WC_RNG* rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* tmpRNG = NULL; + byte* buff = NULL; +#else + WC_RNG tmpRNG[1]; + byte buff[1024]; +#endif + + WOLFSSL_MSG("wolfSSL_BN_rand"); + + if (bits % 8) + len++; + +#ifdef WOLFSSL_SMALL_STACK + buff = (byte*)XMALLOC(1024, NULL, DYNAMIC_TYPE_TMP_BUFFER); + tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (buff == NULL || tmpRNG == NULL) { + XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } +#endif + + if (bn == NULL || bn->internal == NULL) + WOLFSSL_MSG("Bad function arguments"); + else if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else if (initGlobalRNG) + rng = &globalRNG; + + if (rng) { + if (wc_RNG_GenerateBlock(rng, buff, len) != 0) + WOLFSSL_MSG("Bad wc_RNG_GenerateBlock"); + else { + switch (top) { + case -1: + break; + + case 0: + buff[0] |= 0x80; + break; + + case 1: + buff[0] |= 0x80 | 0x40; + break; + } + + if (bottom == 1) { + buff[len-1] |= 0x01; + } + + if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY) + WOLFSSL_MSG("mp read bin failed"); + else + ret = SSL_SUCCESS; + } + } + + if (initTmpRng) + wc_FreeRng(tmpRNG); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + /* return code compliant with OpenSSL : * 1 if bit set, 0 else */ diff --git a/tests/api.c b/tests/api.c index 9c28e6a9f..f89d3601a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -14759,6 +14759,40 @@ static void test_wolfSSL_BUF(void) } +static void test_wolfSSL_pseudo_rand(void) +{ + #if defined(OPENSSL_EXTRA) + BIGNUM* bn; + unsigned char bin[8]; + int i; + + printf(testingFmt, "wolfSSL_pseudo_rand()"); + + /* BN_pseudo_rand returns 1 on success 0 on failure + * int BN_pseudo_rand(BIGNUM* bn, int bits, int top, int bottom) */ + for (i = 0; i < 10; i++) { + AssertNotNull(bn = BN_new()); + XMEMSET(bn, 0, sizeof(bn)); + AssertIntEQ(BN_pseudo_rand(bn, 8, 0, 0), SSL_SUCCESS); + AssertIntGT(BN_bn2bin(bn, bin),0); + AssertIntEQ((bin[0] & 0x80), 0x80); /* top bit should be set */ + BN_free(bn); + } + + for (i = 0; i < 10; i++) { + AssertNotNull(bn = BN_new()); + XMEMSET(bn, 0, sizeof(bn)); + AssertIntEQ(BN_pseudo_rand(bn, 8, 1, 1), SSL_SUCCESS); + AssertIntGT(BN_bn2bin(bn, bin),0); + AssertIntEQ((bin[0] & 0xc1), 0xc1); /* top bit should be set */ + BN_free(bn); + } + + printf(resultFmt, passed); + #endif +} + + static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -15556,6 +15590,7 @@ void ApiTest(void) test_wolfSSL_CTX_add_client_CA(); test_wolfSSL_CTX_set_srp_username(); test_wolfSSL_CTX_set_srp_password(); + test_wolfSSL_pseudo_rand(); AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS); /* test the no op functions for compatibility */ diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index c9edd0d54..90fdba0a8 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -78,6 +78,8 @@ WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char*, int len, WOLFSSL_API int wolfSSL_mask_bits(WOLFSSL_BIGNUM*, int n); +WOLFSSL_API int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM*, int bits, int top, + int bottom); WOLFSSL_API int wolfSSL_BN_rand(WOLFSSL_BIGNUM*, int bits, int top, int bottom); WOLFSSL_API int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM*, int n); WOLFSSL_API int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM**, const char* str); @@ -141,9 +143,10 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_mask_bits wolfSSL_mask_bits -#define BN_rand wolfSSL_BN_rand -#define BN_is_bit_set wolfSSL_BN_is_bit_set -#define BN_hex2bn wolfSSL_BN_hex2bn +#define BN_pseudo_rand wolfSSL_BN_pseudo_rand +#define BN_rand wolfSSL_BN_rand +#define BN_is_bit_set wolfSSL_BN_is_bit_set +#define BN_hex2bn wolfSSL_BN_hex2bn #define BN_dup wolfSSL_BN_dup #define BN_copy wolfSSL_BN_copy