diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index ecee074ed..70421886f 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -600,6 +600,7 @@ WOLFSSL_CLANG_TIDY WOLFSSL_COMMERCIAL_LICENSE WOLFSSL_CONTIKI WOLFSSL_CRL_ALLOW_MISSING_CDP +WOLFSSL_CURVE25519_BLINDING WOLFSSL_CUSTOM_CONFIG WOLFSSL_DILITHIUM_ASSIGN_KEY WOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM diff --git a/src/internal.c b/src/internal.c index f143e6839..3082c757a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6052,8 +6052,14 @@ static int X25519SharedSecret(WOLFSSL* ssl, curve25519_key* priv_key, else #endif { - ret = wc_curve25519_shared_secret_ex(priv_key, pub_key, out, outlen, - EC25519_LITTLE_ENDIAN); + #ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_set_rng(priv_key, ssl->rng); + if (ret == 0) + #endif + { + ret = wc_curve25519_shared_secret_ex(priv_key, pub_key, out, outlen, + EC25519_LITTLE_ENDIAN); + } } /* Handle async pending response */ diff --git a/src/pk.c b/src/pk.c index 4466c0a1e..162c55649 100644 --- a/src/pk.c +++ b/src/pk.c @@ -14667,6 +14667,13 @@ int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz, res = 0; } if (res) { + #ifdef WOLFSSL_CURVE25519_BLINDING + /* An RNG is needed. */ + if (wc_curve25519_set_rng(&privkey, wolfssl_make_global_rng()) != 0) { + res = 0; + } + else + #endif /* Initialize public key object. */ if (wc_curve25519_init(&pubkey) != MP_OKAY) { WOLFSSL_MSG("wc_curve25519_init pubkey failed"); diff --git a/src/tls.c b/src/tls.c index 4df548fec..c035092d1 100644 --- a/src/tls.c +++ b/src/tls.c @@ -8577,7 +8577,11 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, if (ret == 0) { ssl->ecdhCurveOID = ECC_X25519_OID; - + #ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_set_rng(key, ssl->rng); + } + if (ret == 0) { + #endif ret = wc_curve25519_shared_secret_ex(key, peerX25519Key, ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, diff --git a/tests/api.c b/tests/api.c index d59001a2c..e7a553bbe 100644 --- a/tests/api.c +++ b/tests/api.c @@ -22381,6 +22381,9 @@ static int test_wc_curve25519_shared_secret_ex(void) int endian = EC25519_BIG_ENDIAN; ExpectIntEQ(wc_curve25519_init(&private_key), 0); +#ifdef WOLFSSL_CURVE25519_BLINDING + ExpectIntEQ(wc_curve25519_set_rng(&private_key, &rng), 0); +#endif ExpectIntEQ(wc_curve25519_init(&public_key), 0); ExpectIntEQ(wc_InitRng(&rng), 0); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 5a8306f90..e6894758a 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -11906,6 +11906,21 @@ void bench_curve25519KeyAgree(int useDeviceID) return; } +#ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_set_rng(&genKey, &gRng); + if (ret != 0) { + wc_curve25519_free(&genKey); + wc_curve25519_free(&genKey2); + return; + } + ret = wc_curve25519_set_rng(&genKey2, &gRng); + if (ret != 0) { + wc_curve25519_free(&genKey); + wc_curve25519_free(&genKey2); + return; + } +#endif + /* Shared secret */ bench_stats_start(&count, &start); do { diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index 8aba19b5c..f2f2a4352 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -51,6 +51,14 @@ #include #endif +#if defined(WOLFSSL_CURVE25519_BLINDING) + #if defined(CURVE25519_SMALL) + #error "Blinding not needed nor available for small implementation" + #elif defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM) + #error "Blinding not needed nor available for assembly implementation" + #endif +#endif + #if defined(WOLFSSL_LINUXKM) && !defined(USE_INTEL_SPEEDUP) /* force off unneeded vector register save/restore. */ #undef SAVE_VECTOR_REGISTERS @@ -143,6 +151,7 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE); } #else +#ifndef WOLFSSL_CURVE25519_BLINDING fe_init(); SAVE_VECTOR_REGISTERS(return _svr_ret;); @@ -150,10 +159,119 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, ret = curve25519(pub, priv, (byte*)kCurve25519BasePoint); RESTORE_VECTOR_REGISTERS(); +#else + { + WC_RNG rng; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve25519_make_pub_blind(public_size, pub, private_size, + priv, &rng); + + wc_FreeRng(&rng); + } + } +#endif /* !WOLFSSL_CURVE25519_BLINDING */ +#endif /* FREESCALE_LTC_ECC */ + + return ret; +} + +#ifdef WOLFSSL_CURVE25519_BLINDING +#ifndef FREESCALE_LTC_ECC +#ifndef WOLFSSL_CURVE25519_BLINDING_RAND_CNT + #define WOLFSSL_CURVE25519_BLINDING_RAND_CNT 10 +#endif +static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p, + WC_RNG* rng) +{ + int ret; + byte a[CURVE25519_KEYSIZE]; + byte n_a[CURVE25519_KEYSIZE]; + byte rz[CURVE25519_KEYSIZE]; + int i; + int cnt; + + SAVE_VECTOR_REGISTERS(return _svr_ret;); + + /* Generate random z. */ + for (cnt = 0; cnt < WOLFSSL_CURVE25519_BLINDING_RAND_CNT; cnt++) { + ret = wc_RNG_GenerateBlock(rng, rz, sizeof(rz)); + if (ret < 0) { + return ret; + } + for (i = CURVE25519_KEYSIZE; i > 0; i--) { + if (rz[i] != 0xff) + break; + } + if ((i != 0) || (rz[0] <= 0xec)) { + break; + } + } + if (cnt == WOLFSSL_CURVE25519_BLINDING_RAND_CNT) { + return RNG_FAILURE_E; + } + + /* Generate 253 random bits. */ + ret = wc_RNG_GenerateBlock(rng, a, sizeof(a)); + if (ret != 0) + return ret; + a[CURVE25519_KEYSIZE-1] &= 0x7f; + /* k' = k ^ 2k ^ a */ + n_a[0] = n[0] ^ (n[0] << 1) ^ a[0]; + for (i = 1; i < CURVE25519_KEYSIZE; i++) { + byte b1, b2, b3; + b1 = n[i] ^ a[i]; + b2 = (n[i] << 1) ^ a[i]; + b3 = (n[i-1] >> 7) ^ a[i]; + n_a[i] = b1 ^ b2 ^ b3; + } + /* Scalar multiple blinded scalar with blinding value. */ + ret = curve25519_blind(rp, n_a, a, p, rz); + + RESTORE_VECTOR_REGISTERS(); + + return ret; +} +#endif + +int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size, + const byte* priv, WC_RNG* rng) +{ + int ret; +#ifdef FREESCALE_LTC_ECC + const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint(); + ECPoint wc_pub; +#endif + + if ( (public_size != CURVE25519_KEYSIZE) || + (private_size != CURVE25519_KEYSIZE)) { + return ECC_BAD_ARG_E; + } + if ((pub == NULL) || (priv == NULL)) { + return ECC_BAD_ARG_E; + } + + /* check clamping */ + ret = curve25519_priv_clamp_check(priv); + if (ret != 0) + return ret; + +#ifdef FREESCALE_LTC_ECC + /* input basepoint on Weierstrass curve */ + ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass); + if (ret == 0) { + XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE); + } +#else + fe_init(); + + ret = curve25519_smul_blind(pub, priv, (byte*)kCurve25519BasePoint, rng); #endif return ret; } +#endif /* compute the public key from an existing private key, with supplied basepoint, * using bare vectors. @@ -170,6 +288,7 @@ int wc_curve25519_generic(int public_size, byte* pub, * nxp_ltc_curve25519_GetBasePoint() */ return WC_HW_E; #else +#ifndef WOLFSSL_CURVE25519_BLINDING int ret; if ((public_size != CURVE25519_KEYSIZE) || @@ -194,9 +313,64 @@ int wc_curve25519_generic(int public_size, byte* pub, RESTORE_VECTOR_REGISTERS(); return ret; +#else + WC_RNG rng; + int ret; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve25519_generic_blind(public_size, pub, private_size, priv, + basepoint_size, basepoint, &rng); + + wc_FreeRng(&rng); + } + + return ret; +#endif #endif /* FREESCALE_LTC_ECC */ } +#ifdef WOLFSSL_CURVE25519_BLINDING +/* compute the public key from an existing private key, with supplied basepoint, + * using bare vectors. + * + * return value is propagated from curve25519() (0 on success), + * and the byte vectors are little endian. + */ +int wc_curve25519_generic_blind(int public_size, byte* pub, + int private_size, const byte* priv, + int basepoint_size, const byte* basepoint, + WC_RNG* rng) +{ +#ifdef FREESCALE_LTC_ECC + /* unsupported with NXP LTC, only supports single basepoint with + * nxp_ltc_curve25519_GetBasePoint() */ + return WC_HW_E; +#else + int ret; + + if ((public_size != CURVE25519_KEYSIZE) || + (private_size != CURVE25519_KEYSIZE) || + (basepoint_size != CURVE25519_KEYSIZE)) { + return ECC_BAD_ARG_E; + } + if ((pub == NULL) || (priv == NULL) || (basepoint == NULL)) + return ECC_BAD_ARG_E; + + /* check clamping */ + ret = curve25519_priv_clamp_check(priv); + if (ret != 0) + return ret; + + fe_init(); + + ret = curve25519_smul_blind(pub, priv, basepoint, rng); + + return ret; +#endif /* FREESCALE_LTC_ECC */ +} +#endif + /* generate a new private key, as a bare vector. * * return value is propagated from wc_RNG_GenerateBlock(() (0 on success), @@ -250,8 +424,14 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key) ret = wc_curve25519_make_priv(rng, keysize, key->k); if (ret == 0) { key->privSet = 1; +#ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point), + key->p.point, (int)sizeof(key->k), + key->k, rng); +#else ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point, (int)sizeof(key->k), key->k); +#endif key->pubSet = (ret == 0); } #endif @@ -320,11 +500,16 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key, else #endif { +#ifndef WOLFSSL_CURVE25519_BLINDING SAVE_VECTOR_REGISTERS(return _svr_ret;); ret = curve25519(o.point, private_key->k, public_key->p.point); RESTORE_VECTOR_REGISTERS(); +#else + ret = curve25519_smul_blind(o.point, private_key->k, public_key->p.point, + private_key->rng); +#endif } #endif #ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO @@ -379,8 +564,14 @@ int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, /* calculate public if missing */ if (!key->pubSet) { +#ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point), + key->p.point, (int)sizeof(key->k), + key->k, key->rng); +#else ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point, (int)sizeof(key->k), key->k); +#endif key->pubSet = (ret == 0); } /* export public point with endianness */ @@ -742,6 +933,16 @@ void wc_curve25519_free(curve25519_key* key) #endif } +#ifdef WOLFSSL_CURVE25519_BLINDING +int wc_curve25519_set_rng(curve25519_key* key, WC_RNG* rng) +{ + if (key == NULL) + return BAD_FUNC_ARG; + key->rng = rng; + return 0; +} +#endif + /* get key size */ int wc_curve25519_size(curve25519_key* key) { diff --git a/wolfcrypt/src/fe_operations.c b/wolfcrypt/src/fe_operations.c index 97647de02..384095162 100644 --- a/wolfcrypt/src/fe_operations.c +++ b/wolfcrypt/src/fe_operations.c @@ -128,11 +128,9 @@ void fe_init(void) #if defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL) && \ !defined(FREESCALE_LTC_ECC) +#ifndef WOLFSSL_CURVE25519_BLINDING int curve25519(byte* q, const byte* n, const byte* p) { -#if 0 - unsigned char e[32]; -#endif fe x1 = {0}; fe x2 = {0}; fe z2 = {0}; @@ -143,17 +141,6 @@ int curve25519(byte* q, const byte* n, const byte* p) int pos = 0; unsigned int swap = 0; - /* Clamp already done during key generation and import */ -#if 0 - { - unsigned int i; - for (i = 0;i < 32;++i) e[i] = n[i]; - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; - } -#endif - fe_frombytes(x1,p); fe_1(x2); fe_0(z2); @@ -163,11 +150,7 @@ int curve25519(byte* q, const byte* n, const byte* p) swap = 0; for (pos = 254;pos >= 0;--pos) { unsigned int b; -#if 0 - b = e[pos / 8] >> (pos & 7); -#else b = n[pos / 8] >> (pos & 7); -#endif b &= 1; swap ^= b; fe_cswap(x2,x3,(int)swap); @@ -203,6 +186,74 @@ int curve25519(byte* q, const byte* n, const byte* p) return 0; } +#else +int curve25519_blind(byte* q, const byte* n, const byte* mask, const byte* p, + const byte* rz) +{ + fe x1 = {0}; + fe x2 = {0}; + fe z2 = {0}; + fe x3 = {0}; + fe z3 = {0}; + fe tmp0 = {0}; + fe tmp1 = {0}; + int pos = 0; + unsigned int b; + + fe_frombytes(x1,p); + fe_1(x2); + fe_0(z2); + fe_copy(x3,x1); + fe_frombytes(z3, rz); + fe_mul(x3, x3, z3); + + /* mask_bits[252] */ + b = mask[31] >> 7; + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + for (pos = 255;pos >= 1;--pos) { + b = n[pos / 8] >> (pos & 7); + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + + /* montgomery */ + fe_sub(tmp0,x3,z3); + fe_sub(tmp1,x2,z2); + fe_add(x2,x2,z2); + fe_add(z2,x3,z3); + fe_mul(z3,tmp0,x2); + fe_mul(z2,z2,tmp1); + fe_sq(tmp0,tmp1); + fe_sq(tmp1,x2); + fe_add(x3,z3,z2); + fe_sub(z2,z3,z2); + fe_mul(x2,tmp1,tmp0); + fe_sub(tmp1,tmp1,tmp0); + fe_sq(z2,z2); + fe_mul121666(z3,tmp1); + fe_sq(x3,x3); + fe_add(tmp0,tmp0,z3); + fe_mul(z3,x1,z2); + fe_mul(z2,tmp1,tmp0); + + b = mask[(pos-1) / 8] >> ((pos-1) & 7); + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + } + b = n[0] & 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + + fe_invert(z2,z2); + fe_mul(x2,x2,z2); + fe_tobytes(q,x2); + + return 0; +} +#endif #endif /* HAVE_CURVE25519 && !CURVE25519_SMALL && !FREESCALE_LTC_ECC */ diff --git a/wolfcrypt/src/fe_x25519_128.h b/wolfcrypt/src/fe_x25519_128.h index 7ac6a9c7b..089d8474c 100644 --- a/wolfcrypt/src/fe_x25519_128.h +++ b/wolfcrypt/src/fe_x25519_128.h @@ -404,6 +404,7 @@ void fe_invert(fe r, const fe a) } #ifndef CURVE25519_SMALL +#ifndef WOLFSSL_CURVE25519_BLINDING /* Scalar multiply the field element a by n using Montgomery Ladder and places * result in r. * @@ -462,6 +463,69 @@ int curve25519(byte* r, const byte* n, const byte* a) return 0; } +#else +int curve25519_blind(byte* r, const byte* n, const byte* mask, const byte* a, + const byte* rz) +{ + fe x1, x2, z2, x3, z3; + fe t0, t1; + int pos; + unsigned int b; + + fe_frombytes(x1, a); + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_frombytes(z3, rz); + fe_mul(x3, x3, z3); + + /* mask_bits[252] */ + b = (unsigned int)(mask[31] >> 7); + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + for (pos = 255;pos >= 1;--pos) { + b = (unsigned int)(n[pos / 8] >> (pos & 7)); + b &= 1; + fe_cswap(x2, x3, (int)b); + fe_cswap(z2, z3, (int)b); + + /* montgomery */ + fe_sub(t0, x3, z3); + fe_sub(t1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, t0, x2); + fe_mul(z2, z2, t1); + fe_sq(t0, t1); + fe_sq(t1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, t1, t0); + fe_sub(t1, t1, t0); + fe_sq(z2, z2); + fe_mul121666(z3, t1); + fe_sq(x3, x3); + fe_add(t0, t0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, t1, t0); + + b = (unsigned int)(mask[(pos - 1) / 8] >> ((pos - 1) & 7)); + b &= 1; + fe_cswap(x2, x3, (int)b); + fe_cswap(z2, z3, (int)b); + } + b = (unsigned int)(n[0] & 1); + fe_cswap(x2, x3, (int)b); + fe_cswap(z2, z3, (int)b); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(r, x2); + + return 0; +} +#endif /* WOLFSSL_CURVE25519_BLINDING */ #endif /* !CURVE25519_SMALL */ /* The field element value 0 as an array of bytes. */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a5825bde9..4432aad0b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -35013,7 +35013,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test_buffers(void) #else #define X25519_TEST_CNT 1 #endif -static wc_test_ret_t curve25519_overflow_test(void) +static wc_test_ret_t curve25519_overflow_test(WC_RNG* rng) { /* secret key for party a */ byte sa[X25519_TEST_CNT][32] = { @@ -35131,6 +35131,10 @@ static wc_test_ret_t curve25519_overflow_test(void) curve25519_key userA; wc_curve25519_init_ex(&userA, HEAP_HINT, devId); +#ifdef WOLFSSL_CURVE25519_BLINDING + wc_curve25519_set_rng(&userA, rng); +#endif + (void)rng; for (i = 0; i < X25519_TEST_CNT; i++) { if (wc_curve25519_import_private_raw(sa[i], sizeof(sa[i]), pb[i], @@ -35609,6 +35613,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void) wc_curve25519_init_ex(userB, HEAP_HINT, devId); wc_curve25519_init_ex(pubKey, HEAP_HINT, devId); #endif +#ifdef WOLFSSL_CURVE25519_BLINDING + wc_curve25519_set_rng(userA, &rng); + wc_curve25519_set_rng(userB, &rng); +#endif /* make curve25519 keys */ ret = wc_curve25519_make_key(&rng, 32, userA); @@ -35706,6 +35714,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void) wc_curve25519_free(userB); wc_curve25519_init_ex(userB, HEAP_HINT, devId); +#ifdef WOLFSSL_CURVE25519_BLINDING + wc_curve25519_set_rng(userB, &rng); +#endif ret = wc_curve25519_make_key(&rng, 32, userB); if (ret != 0) @@ -35728,7 +35739,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void) if (XMEMCMP(sharedA, sharedB, x)) ERROR_OUT(WC_TEST_RET_ENC_NC, cleanup); - ret = curve25519_overflow_test(); + ret = curve25519_overflow_test(&rng); if (ret != 0) goto cleanup; ret = curve25519_check_public_test(); diff --git a/wolfssl/wolfcrypt/curve25519.h b/wolfssl/wolfcrypt/curve25519.h index ec736a02e..79fb6d9af 100644 --- a/wolfssl/wolfcrypt/curve25519.h +++ b/wolfssl/wolfcrypt/curve25519.h @@ -91,6 +91,9 @@ struct curve25519_key { int devId; #endif void *heap; +#ifdef WOLFSSL_CURVE25519_BLINDING + WC_RNG* rng; +#endif #ifdef WOLFSSL_SE050 word32 keyId; byte keyIdSet; @@ -109,11 +112,23 @@ enum { WOLFSSL_API int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, const byte* priv); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size, + const byte* priv, WC_RNG* rng); +#endif WOLFSSL_API int wc_curve25519_generic(int public_size, byte* pub, int private_size, const byte* priv, int basepoint_size, const byte* basepoint); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_generic_blind(int public_size, byte* pub, + int private_size, const byte* priv, + int basepoint_size, const byte* basepoint, + WC_RNG* rng); +#endif WOLFSSL_API int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* priv); @@ -139,6 +154,11 @@ int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId); WOLFSSL_API void wc_curve25519_free(curve25519_key* key); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_set_rng(curve25519_key* key, WC_RNG* rng); +#endif + #ifndef WC_NO_CONSTRUCTORS WOLFSSL_API curve25519_key* wc_curve25519_new(void* heap, int devId, int *result_code); diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 8b4ce304e..dd029eca1 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -76,6 +76,10 @@ Bounds on each t[i] vary depending on context. WOLFSSL_LOCAL void fe_init(void); WOLFSSL_LOCAL int curve25519(byte * q, const byte * n, const byte * p); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_LOCAL int curve25519_blind(byte * q, const byte * n, const byte* mask, + const byte * p, const byte* rz); +#endif #endif /* default to be faster but take more memory */