diff --git a/src/ssl.c b/src/ssl.c index 766e0c203..16e7e9fd0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -86,6 +86,7 @@ #include #include #include + #include #include #include #include @@ -15639,6 +15640,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, return SSLEAY_VERSION_NUMBER; } + unsigned long OpenSSL_version_num(void) + { + return OPENSSL_VERSION_NUMBER; + } const char* wolfSSLeay_version(int type) { @@ -34308,11 +34313,9 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, return WOLFSSL_FAILURE; } - if (min_len > len) { - return WOLFSSL_FAILURE; - } - - if (wolfSSL_ECPoint_i2d(group, p, buf, &min_len) != WOLFSSL_SUCCESS) { + if (buf && + ((min_len > len) || + wolfSSL_ECPoint_i2d(group, p, buf, &min_len) != WOLFSSL_SUCCESS)) { return WOLFSSL_FAILURE; } @@ -34325,7 +34328,7 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p, const unsigned char *buf, size_t len, WOLFSSL_BN_CTX *ctx) { - WOLFSSL_ENTER("EC_POINT_point2oct"); + WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point"); if (!group || !p) { return WOLFSSL_FAILURE; @@ -34336,6 +34339,42 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, return wolfSSL_ECPoint_d2i((unsigned char*)buf, len, group, p); } +/* wolfSSL_EC_POINT_point2bn should return "in" if not null */ +WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx) +{ + size_t len; + byte *buf; + WOLFSSL_BIGNUM *ret = NULL; + + WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point"); + + if (!group || !p) { + return NULL; + } + + if ((len = wolfSSL_EC_POINT_point2oct(group, p, form, + NULL, 0, ctx)) == WOLFSSL_FAILURE) { + return NULL; + } + + if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc failed"); + return NULL; + } + + if (wolfSSL_EC_POINT_point2oct(group, p, form, + buf, len, ctx) == len) { + ret = wolfSSL_BN_bin2bn(buf, len, in); + } + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { WOLFSSL_EC_POINT *p; @@ -34399,6 +34438,47 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, return WOLFSSL_SUCCESS; } +int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *point, + const WOLFSSL_BIGNUM *x, + const WOLFSSL_BIGNUM *y, + WOLFSSL_BN_CTX *ctx) +{ + (void)ctx; + WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp"); + + if (group == NULL || point == NULL || point->internal == NULL || + x == NULL || y == NULL) { + WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error"); + return WOLFSSL_FAILURE; + } + + if (!point->X) { + point->X = wolfSSL_BN_new(); + } + if (!point->Y) { + point->Y = wolfSSL_BN_new(); + } + if (!point->Z) { + point->Z = wolfSSL_BN_new(); + } + if (!point->X || !point->Y || !point->Z) { + WOLFSSL_MSG("wolfSSL_BN_new failed"); + return WOLFSSL_FAILURE; + } + + BN_copy(point->X, x); + BN_copy(point->Y, y); + BN_copy(point->Z, wolfSSL_BN_value_one()); + + if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECPointInternal failed"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + #ifndef WOLFSSL_ATECC508A /* return code compliant with OpenSSL : * 1 if success, 0 if error @@ -42358,7 +42438,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out, /* stunnel compatibility functions*/ #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_HAPROXY))) + defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH))) void wolfSSL_ERR_remove_thread_state(void* pid) { (void) pid; @@ -46485,11 +46565,6 @@ int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n) return WOLFSSL_FAILURE; } - if (n > DIGIT_BIT) { - WOLFSSL_MSG("input bit count too large"); - return WOLFSSL_FAILURE; - } - return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n); } @@ -46504,7 +46579,7 @@ int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n) } if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) { - WOLFSSL_MSG("mp_set_int error"); + WOLFSSL_MSG("mp_set_bit error"); return WOLFSSL_FAILURE; } @@ -46512,6 +46587,60 @@ int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n) } +int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) +{ + int ret = WOLFSSL_FAILURE; +#ifndef WOLFSSL_SMALL_STACK + mp_int res[1]; + mp_int tmp[1]; +#else + mp_int* res = null; + mp_int* tmp = null; +#endif + + if (bn == NULL || bn->internal == NULL) { + WOLFSSL_MSG("bn NULL error"); + goto cleanup; + } + if (mp_is_bit_set((mp_int*)bn->internal, n)) { +#ifdef WOLFSSL_SMALL_STACK + res = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (res == NULL) { + goto cleanup; + } + tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (tmp == NULL) { + goto cleanup; + } +#endif + if (mp_init(tmp) != MP_OKAY) { + goto cleanup; + } + if (mp_init(res) != MP_OKAY) { + goto cleanup; + } + if (mp_set_bit(tmp, n) != MP_OKAY) { + goto cleanup; + } + if (mp_sub((mp_int*)bn->internal, tmp, res) != MP_OKAY) { + goto cleanup; + } + if (mp_copy(res, (mp_int*)bn->internal) != MP_OKAY) { + goto cleanup; + } + } + ret = WOLFSSL_SUCCESS; +cleanup: +#ifdef WOLFSSL_SMALL_STACK + if (res): + XFREE(res, NULL, DYNAMIC_TYPE_BIGINT); + if (tmp): + XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); +#endif + return ret; +} + + /* WOLFSSL_SUCCESS on ok */ /* Note on use: this function expects str to be an even length. It is * converting pairs of bytes into 8-bit values. As an example, the RSA @@ -47691,6 +47820,14 @@ void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn) wolfSSL_BN_free(bn); } } + +void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn) +{ + WOLFSSL_MSG("wolfSSL_BN_clear"); + if (bn && bn->internal) { + mp_forcezero((mp_int*)bn->internal); + } +} #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) @@ -47753,7 +47890,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) wolfSSL_BN_free(rsa->n); #ifdef WC_RSA_BLINDING - if (wc_FreeRng(rsa->rng) != 0) { + if (rsa->rng && wc_FreeRng(rsa->rng) != 0) { WOLFSSL_MSG("Issue freeing rng"); } XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG); diff --git a/tests/api.c b/tests/api.c index ac4cee6d9..c044f7a4f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1781,9 +1781,10 @@ static void test_wolfSSL_EC(void) #ifdef HAVE_ECC BN_CTX *ctx; EC_GROUP *group; - EC_POINT *Gxy, *new_point; + EC_POINT *Gxy, *new_point, *set_point; BIGNUM *k = NULL, *Gx = NULL, *Gy = NULL, *Gz = NULL; BIGNUM *X, *Y; + BIGNUM *set_point_bn; char* hexStr; int group_bits; @@ -1802,8 +1803,10 @@ static void test_wolfSSL_EC(void) AssertIntEQ((group_bits = EC_GROUP_order_bits(group)), 256); AssertNotNull(Gxy = EC_POINT_new(group)); AssertNotNull(new_point = EC_POINT_new(group)); + AssertNotNull(set_point = EC_POINT_new(group)); AssertNotNull(X = BN_new()); AssertNotNull(Y = BN_new()); + AssertNotNull(set_point_bn = BN_new()); /* load test values */ AssertIntEQ(BN_hex2bn(&k, kTest), WOLFSSL_SUCCESS); @@ -1828,6 +1831,15 @@ static void test_wolfSSL_EC(void) /* check if point X coordinate is zero */ AssertIntEQ(BN_is_zero(X), WOLFSSL_FAILURE); + /* set the same X and Y points in another object */ + AssertIntEQ(EC_POINT_set_affine_coordinates_GFp(group, set_point, X, Y, ctx), WOLFSSL_SUCCESS); + + /* compare points as they should be the same */ + AssertIntEQ(EC_POINT_cmp(group, new_point, set_point, ctx), 0); + + AssertPtrEq(EC_POINT_point2bn(group, set_point, POINT_CONVERSION_UNCOMPRESSED, + set_point_bn, ctx), set_point_bn); + /* check bn2hex */ hexStr = BN_bn2hex(k); AssertStrEQ(hexStr, kTest); @@ -1867,7 +1879,9 @@ static void test_wolfSSL_EC(void) BN_free(X); BN_free(Y); BN_free(k); + BN_free(set_point_bn); EC_POINT_free(new_point); + EC_POINT_free(set_point); EC_POINT_free(Gxy); EC_GROUP_free(group); BN_CTX_free(ctx); @@ -21519,6 +21533,15 @@ static void test_wolfSSL_BN(void) AssertIntLT(BN_cmp(a, c), 0); AssertIntGT(BN_cmp(c, b), 0); + AssertIntEQ(BN_set_word(a, 0), 1); + AssertIntEQ(BN_is_zero(a), 1); + AssertIntEQ(BN_set_bit(a, 0x45), 1); + AssertIntEQ(BN_is_zero(a), 0); + AssertIntEQ(BN_is_bit_set(a, 0x45), 1); + AssertIntEQ(BN_clear_bit(a, 0x45), 1); + AssertIntEQ(BN_is_bit_set(a, 0x45), 0); + AssertIntEQ(BN_is_zero(a), 1); + BN_free(a); BN_free(b); BN_free(c); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5f47ff767..028c0cf97 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2748,7 +2748,7 @@ struct WOLFSSL_CTX { #endif #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_HAPROXY))) + defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) )) CallbackSniRecv sniRecvCb; void* sniRecvCbArg; #endif diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 067d873d7..40f2ebe8b 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -64,6 +64,7 @@ WOLFSSL_API void wolfSSL_BN_init(WOLFSSL_BIGNUM *); #endif WOLFSSL_API void wolfSSL_BN_free(WOLFSSL_BIGNUM*); WOLFSSL_API void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM*); +WOLFSSL_API void wolfSSL_BN_clear(WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, @@ -110,6 +111,7 @@ WOLFSSL_API char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int); +WOLFSSL_API int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM*); @@ -141,6 +143,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_init wolfSSL_BN_init #define BN_free wolfSSL_BN_free #define BN_clear_free wolfSSL_BN_clear_free +#define BN_clear wolfSSL_BN_clear #define BN_num_bytes wolfSSL_BN_num_bytes #define BN_num_bits wolfSSL_BN_num_bits @@ -184,6 +187,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_add wolfSSL_BN_add #define BN_set_word wolfSSL_BN_set_word #define BN_set_bit wolfSSL_BN_set_bit +#define BN_clear_bit wolfSSL_BN_clear_bit #define BN_is_prime_ex wolfSSL_BN_is_prime_ex diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 241108397..a3eeb7bd7 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -35,6 +35,7 @@ WOLFSSL_API const char* wolfSSLeay_version(int type); WOLFSSL_API unsigned long wolfSSLeay(void); +WOLFSSL_API unsigned long OpenSSL_version_num(void); #ifdef OPENSSL_EXTRA WOLFSSL_API void wolfSSL_OPENSSL_free(void*); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 50175a6d1..a8ef9d0c2 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -140,6 +140,11 @@ WOLFSSL_API int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p, const unsigned char *buf, size_t len, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx); WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, @@ -203,6 +208,12 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, WOLFSSL_BIGNUM *y, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *point, + const WOLFSSL_BIGNUM *x, + const WOLFSSL_BIGNUM *y, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m, @@ -259,6 +270,8 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_free wolfSSL_EC_POINT_free #define EC_POINT_get_affine_coordinates_GFp \ wolfSSL_EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_set_affine_coordinates_GFp \ + wolfSSL_EC_POINT_set_affine_coordinates_GFp #define EC_POINT_mul wolfSSL_EC_POINT_mul #define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free #define EC_POINT_cmp wolfSSL_EC_POINT_cmp @@ -270,6 +283,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define ECPoint_d2i wolfSSL_ECPoint_d2i #define EC_POINT_point2oct wolfSSL_EC_POINT_point2oct #define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point +#define EC_POINT_point2bn wolfSSL_EC_POINT_point2bn #ifndef HAVE_SELFTEST #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex diff --git a/wolfssl/openssl/err.h b/wolfssl/openssl/err.h index ca59a0bb4..ae50458d5 100644 --- a/wolfssl/openssl/err.h +++ b/wolfssl/openssl/err.h @@ -26,6 +26,7 @@ /* err.h for openssl */ #define ERR_load_crypto_strings wolfSSL_ERR_load_crypto_strings +#define ERR_load_CRYPTO_strings wolfSSL_ERR_load_crypto_strings #define ERR_peek_last_error wolfSSL_ERR_peek_last_error /* fatal error */ diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index ad3f407e9..f15ba9746 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -327,7 +327,7 @@ typedef struct alt_fp_int { #endif -/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) => +/* A point on an ECC curve, stored in Jacobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpreted as affine */ typedef struct { #ifndef ALT_ECC_SIZE