Skip to content
Open
9 changes: 8 additions & 1 deletion .github/configs/os-check-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -601,5 +601,12 @@
"configure": ["--enable-leanpsk"],
"extra_cflags": "-Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -Werror=implicit-function-declaration -Wno-error=cpp",
"check": false,
"run": [["./wolfcrypt/test/testwolfcrypt"]]}
"run": [["./wolfcrypt/test/testwolfcrypt"]]},
{"name": "fpecc-no-shamir",
"comment": "FP_ECC with ECC_TIMING_RESISTANT but no ECC_SHAMIR: only the constant-time comb consumes the fixed-point cache.",
"configure": ["--enable-fpecc", "--disable-eccshamir"]},
{"name": "sp-math-sakke",
"comment": "SAKKE on WOLFSSL_SP_MATH without RSA, DH, or ECCSI: its blinded RSK inverse needs sp_mulmod, which nothing else builds in this shape.",
"configure": ["--enable-cryptonly", "--enable-sp-math", "--enable-sp",
"--disable-rsa", "--disable-dh", "--enable-sakke"]}
]
2 changes: 1 addition & 1 deletion .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,6 @@ WOLFSSL_MLKEM_NO_MALLOC
WOLFSSL_MLKEM_NTT_UNROLL
WOLFSSL_MONT_RED_CT
WOLFSSL_MP_COND_COPY
WOLFSSL_MP_INVMOD_CONSTANT_TIME
WOLFSSL_MULTICIRCULATE_ALTNAMELIST
WOLFSSL_MX2_CONF_INCLUDE
WOLFSSL_NETX_DUO
Expand All @@ -1076,6 +1075,7 @@ WOLFSSL_NO_CHACHA20_POLY1305_FUSED_IFMA
WOLFSSL_NO_CHACHA20_POLY1305_SHORT
WOLFSSL_NO_CHACHA20_POLY1305_SMALL_ASM
WOLFSSL_NO_CLIENT_CERT_ERROR
WOLFSSL_NO_CONST_CMP
WOLFSSL_NO_COPY_KEY
WOLFSSL_NO_CRL_DATE_CHECK
WOLFSSL_NO_CRL_NEXT_DATE
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2040,6 +2040,9 @@ if(WOLFSSL_SAKKE)
if (NOT WOLFSSL_ECC)
message(FATAL_ERROR "cannot enable SAKKE without enabling ECC.")
endif()
if (NOT WOLFSSL_RNG)
message(FATAL_ERROR "cannot enable SAKKE without enabling RNG.")
endif()

list(APPEND WOLFSSL_DEFINITIONS "-DWOLFCRYPT_HAVE_SAKKE")
endif()
Expand Down
8 changes: 7 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,8 @@ then
test "$enable_aessiv" = "" && enable_aessiv=yes
# AFALG lacks AES-EAX
test "$enable_aeseax" = "" && test "$enable_afalg" != "yes" && enable_aeseax=yes
test "$enable_sakke" = "" && test "$enable_ecc" != "no" && enable_sakke=yes
test "$enable_sakke" = "" && test "$enable_ecc" != "no" && \
test "$enable_rng" != "no" && enable_sakke=yes
test "$enable_atomicuser" = "" && enable_atomicuser=yes
test "$enable_cryptocb" = "" && enable_cryptocb=yes
test "$enable_pkcallbacks" = "" && enable_pkcallbacks=yes
Expand Down Expand Up @@ -6721,6 +6722,11 @@ then
AC_MSG_ERROR([SAKKE requires ECC.])
fi

if test "$ENABLED_SAKKE" != "no" && test "$ENABLED_RNG" = "no"
then
AC_MSG_ERROR([--enable-sakke requires --enable-rng])
fi

if test "x$ENABLED_SAKKE" = "xsmall"
then
ENABLED_SAKKE="yes"
Expand Down
4 changes: 2 additions & 2 deletions doc/dox_comments/header_files-ja/doxygen_groups.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
-# wc_MakeSakkeKey(), wc_ExportSakkeKey(), wc_ExportSakkePublicKey() または
-# wc_ImportSakkeKey()
-# リクエストを待機:
-# クライアントのIDに基づいてRSKを作成: wc_MakeSakkeRsk()
-# クライアントのIDに基づいてRSKを作成: wc_MakeSakkeRsk_ex()
-# クライアントへの転送のためにRSKをエンコード: wc_EncodeSakkeRsk()
-# SAKKE鍵の解放: wc_FreeSakkeKey()

Expand Down Expand Up @@ -231,7 +231,7 @@
これらの操作は、受信者秘密鍵(RSK)を作成、検証、エンコード、デコードします。

RSKは、SSVを導出するために必要です(wc_DeriveSakkeSSV()を参照)。\n
KMSで、クライアントのIDからRSKを作成(wc_MakeSakkeRsk())。\n
KMSで、クライアントのIDからRSKを作成(wc_MakeSakkeRsk_ex())。\n
クライアントで、IDでRSKを検証(wc_ValidateSakkeRsk())。\n
クライアントへの転送またはストレージのためにRSKをエンコード(wc_EncodeSakkeRsk())。\n
必要に応じてクライアントでRSKをデコード(wc_DecodeSakkeRsk())。\n
Expand Down
5 changes: 5 additions & 0 deletions doc/dox_comments/header_files-ja/sakke.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ int wc_MakeSakkeRsk(SakkeKey* key, const byte* id, word16 idSz,
/*!
\ingroup SAKKE_RSK
*/
int wc_MakeSakkeRsk_ex(SakkeKey* key, const byte* id, word16 idSz,
ecc_point* rsk, WC_RNG* rng);
/*!
\ingroup SAKKE_RSK
*/
int wc_ValidateSakkeRsk(SakkeKey* key, const byte* id, word16 idSz,
ecc_point* rsk, int* valid);
/*!
Expand Down
4 changes: 2 additions & 2 deletions doc/dox_comments/header_files/doxygen_groups.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
-# wc_MakeSakkeKey(), wc_ExportSakkeKey(), wc_ExportSakkePublicKey() or
-# wc_ImportSakkeKey()
-# Wait for request:
-# Make an RSK base on ID for the client: wc_MakeSakkeRsk()
-# Make an RSK base on ID for the client: wc_MakeSakkeRsk_ex()
-# Encode RSK for transfer to client: wc_EncodeSakkeRsk()
-# Free SAKKE Key: wc_FreeSakkeKey()

Expand Down Expand Up @@ -271,7 +271,7 @@
These operations make, validate, encode and decode a Receiver Secret Key (RSK).

An RSK is required to derive an SSV (see wc_DeriveSakkeSSV()).\n
On the KMS, make an RSK (wc_MakeSakkeRsk()) from the client's ID.\n
On the KMS, make an RSK (wc_MakeSakkeRsk_ex()) from the client's ID.\n
On the client, validate the RSK (wc_ValidateSakkeRsk()) with the ID.\n
Encode the RSK (wc_EncodeSakkeRsk()) to pass to client or for storage.\n
Decode the RSK (wc_DecodeSakkeRsk()) on the client when needed.\n
Expand Down
5 changes: 5 additions & 0 deletions doc/dox_comments/header_files/sakke.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ int wc_MakeSakkeRsk(SakkeKey* key, const byte* id, word16 idSz,
/*!
\ingroup SAKKE_RSK
*/
int wc_MakeSakkeRsk_ex(SakkeKey* key, const byte* id, word16 idSz,
ecc_point* rsk, WC_RNG* rng);
/*!
\ingroup SAKKE_RSK
*/
int wc_ValidateSakkeRsk(SakkeKey* key, const byte* id, word16 idSz,
ecc_point* rsk, int* valid);
/*!
Expand Down
3 changes: 3 additions & 0 deletions src/pk_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,9 @@ static int ec_mul2add(ecc_point* r, ecc_point* b, mp_int* n, ecc_point* q,
*
* r = base point * n + q * m
*
* With both n and q/m given the sum uses Shamir's trick, which is variable
* time: do not pass secret scalars that way.
*
* @param [in] curveIdx Index of curve in ecc_set.
* @param [out] r EC point that is result of operation.
* @param [in] n Scalar to multiply by base point. May be NULL.
Expand Down
88 changes: 86 additions & 2 deletions src/ssl_bn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1969,10 +1969,91 @@ int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
return ret;
}

/* Number of random blinding factors to try. A modulus with many small factors
* rejects most of them. */
#define BN_INVMOD_BLIND_TRIES 128

/* Compute r = a^-1 mod m with a blinded by a random factor.
*
* The factor is tested for an inverse by itself, so that whether one is used
* does not depend on a, and a failure with it means that a has no inverse.
* Invert directly when there is no random number generator or no factor found:
* this API has no way to ask for blinding, so it must not start failing for
* lack of it. r may alias a or m.
*
* @param [in] a MP integer to invert.
* @param [in] m Big number that is the modulus.
* @param [out] r MP integer to hold the result.
* @return MP_OKAY on success.
* @return Other value on error, including when there is no inverse.
*/
static int wolfssl_bn_invmod_blind(mp_int* a, const WOLFSSL_BIGNUM* m,
mp_int* r)
{
mp_int* mod = (mp_int*)m->internal;
int err = MP_OKAY;
int found = 0;
WOLFSSL_BIGNUM* t = wolfSSL_BN_new();
#ifndef WC_NO_RNG
int i;
WOLFSSL_BIGNUM* b = wolfSSL_BN_new();

if ((t == NULL) || (b == NULL)) {
err = MEMORY_E;
}
if ((err == MP_OKAY) && (mp_cmp_d(mod, 2) == MP_GT)) {
for (i = 0; (err == MP_OKAY) && (!found) &&
(i < BN_INVMOD_BLIND_TRIES) &&
(wolfSSL_BN_rand_range(b, m) == 1); i++) {
if (mp_iszero((mp_int*)b->internal)) {
continue;
}
err = mp_invmod((mp_int*)b->internal, mod, (mp_int*)t->internal);
if (err == MP_OKAY) {
found = 1;
}
else if (err == WC_NO_ERR_TRACE(MP_VAL)) {
err = MP_OKAY;
}
}
}
if ((err == MP_OKAY) && found) {
err = mp_mulmod(a, (mp_int*)b->internal, mod, (mp_int*)t->internal);
if (err == MP_OKAY) {
err = mp_invmod((mp_int*)t->internal, mod, (mp_int*)t->internal);
}
if (err == MP_OKAY) {
err = mp_mulmod((mp_int*)t->internal, (mp_int*)b->internal, mod,
(mp_int*)t->internal);
}
}
#else
if (t == NULL) {
err = MEMORY_E;
}
#endif
if ((err == MP_OKAY) && (!found)) {
err = mp_invmod(a, mod, (mp_int*)t->internal);
}
if (err == MP_OKAY) {
err = mp_copy((mp_int*)t->internal, r);
}

#ifndef WC_NO_RNG
wolfSSL_BN_clear_free(b);
#endif
wolfSSL_BN_clear_free(t);

return err;
}

/* Calculate the modular inverse of a mod m into r. r = a^-1 mod m
*
* A new big number is allocated when r is NULL.
*
* The operand is blinded when a random blinding factor can be generated, and
* inverted unblinded otherwise. BN_FLG_CONSTTIME is not checked.
*
* @param [in, out] r Big number to hold result. May be NULL.
* @param [in] a Big number to invert.
* @param [in] m Big number that is the modulus.
Expand Down Expand Up @@ -2009,8 +2090,8 @@ WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a,
}

/* Compute inverse of a modulo n and return in r */
if ((!err) && (mp_invmod((mp_int *)a->internal, (mp_int *)m->internal,
(mp_int*)r->internal) != MP_OKAY)) {
if ((!err) && (wolfssl_bn_invmod_blind((mp_int *)a->internal,
(const WOLFSSL_BIGNUM*)m, (mp_int*)r->internal) != MP_OKAY)) {
WOLFSSL_MSG("mp_invmod() error");
err = 1;
}
Expand Down Expand Up @@ -2153,6 +2234,9 @@ int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
ret = 0;
}
/* Dispose of buffer - no longer needed. */
if (buff != NULL) {
ForceZero(buff, len);
}
XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);

/* Truncate to requested bit length when not a whole number of bytes. */
Expand Down
Loading
Loading