mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 10:47:28 +02:00
add option for additional sanity checks
This commit is contained in:
10
configure.ac
10
configure.ac
@ -2357,6 +2357,16 @@ else
|
|||||||
AM_CFLAGS="$AM_CFLAGS -DWC_NO_HARDEN -DWC_NO_CACHE_RESISTANT"
|
AM_CFLAGS="$AM_CFLAGS -DWC_NO_HARDEN -DWC_NO_CACHE_RESISTANT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Fault protection hardening
|
||||||
|
AC_ARG_ENABLE([faultharden],
|
||||||
|
[AS_HELP_STRING([--enable-faultharden],[Enable Fault Hardened build (default: disabled)])],
|
||||||
|
[ENABLED_FAULTHARDEN=$enableval],
|
||||||
|
[ENABLED_FAULTHARDEN=yes])
|
||||||
|
|
||||||
|
if test "$ENABLED_FAULTHARDEN" = "yes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_SIG_FAULTS -DWOLFSSL_CHECK_VER_FAULTS"
|
||||||
|
fi
|
||||||
|
|
||||||
# IPv6 Test Apps
|
# IPv6 Test Apps
|
||||||
AC_ARG_ENABLE([ipv6],
|
AC_ARG_ENABLE([ipv6],
|
||||||
|
@ -104,6 +104,9 @@ Possible ECC enable options:
|
|||||||
* unmasked copy is computed and stored each time it is
|
* unmasked copy is computed and stored each time it is
|
||||||
* needed.
|
* needed.
|
||||||
* default: off
|
* default: off
|
||||||
|
* WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
* Sanity check on verification steps in case of faults.
|
||||||
|
* default: off
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8970,13 +8973,28 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
if (u1 == NULL || u2 == NULL)
|
||||||
|
err = MEMORY_E;
|
||||||
|
#else
|
||||||
u1 = e;
|
u1 = e;
|
||||||
u2 = w;
|
u2 = w;
|
||||||
|
#endif
|
||||||
v = w;
|
v = w;
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
|
err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY) {
|
||||||
|
err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
|
||||||
|
}
|
||||||
|
if (err == MP_OKAY) {
|
||||||
|
err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* allocate points */
|
/* allocate points */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
@ -9000,10 +9018,22 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_mulmod(e, w, curve->order, u1);
|
err = mp_mulmod(e, w, curve->order, u1);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* u2 = rw */
|
/* u2 = rw */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_mulmod(r, w, curve->order, u2);
|
err = mp_mulmod(r, w, curve->order, u2);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* find mG and mQ */
|
/* find mG and mQ */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_copy(curve->Gx, mG->x);
|
err = mp_copy(curve->Gx, mG->x);
|
||||||
@ -9031,16 +9061,35 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
#ifndef ECC_SHAMIR
|
#ifndef ECC_SHAMIR
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
{
|
{
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
ecc_point mG1, mQ1;
|
||||||
|
wc_ecc_copy_point(mQ, &mQ1);
|
||||||
|
wc_ecc_copy_point(mG, &mG1);
|
||||||
|
#endif
|
||||||
|
|
||||||
mp_digit mp = 0;
|
mp_digit mp = 0;
|
||||||
|
|
||||||
if (!mp_iszero((MP_INT_SIZE*)u1)) {
|
if (!mp_iszero((MP_INT_SIZE*)u1)) {
|
||||||
/* compute u1*mG + u2*mQ = mG */
|
/* compute u1*mG + u2*mQ = mG */
|
||||||
err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
|
err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
|
||||||
key->heap);
|
key->heap);
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store new value for comparing with after add operation */
|
||||||
|
wc_ecc_copy_point(mG, &mG1);
|
||||||
|
#endif
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
||||||
key->heap);
|
key->heap);
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* find the montgomery mp */
|
/* find the montgomery mp */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
@ -9050,6 +9099,14 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
|
err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
|
||||||
curve->prime, mp, NULL);
|
curve->prime, mp, NULL);
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
|
||||||
|
err = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* compute 0*mG + u2*mQ = mG */
|
/* compute 0*mG + u2*mQ = mG */
|
||||||
@ -9072,6 +9129,7 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
}
|
}
|
||||||
#endif /* ECC_SHAMIR */
|
#endif /* ECC_SHAMIR */
|
||||||
#endif /* FREESCALE_LTC_ECC */
|
#endif /* FREESCALE_LTC_ECC */
|
||||||
|
|
||||||
/* v = X_x1 mod n */
|
/* v = X_x1 mod n */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = mp_mod(mG->x, curve->order, v);
|
err = mp_mod(mG->x, curve->order, v);
|
||||||
@ -9089,6 +9147,12 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
|
|||||||
mp_clear(e);
|
mp_clear(e);
|
||||||
mp_clear(w);
|
mp_clear(w);
|
||||||
FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
|
FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
mp_clear(u1);
|
||||||
|
FREE_MP_INT_SIZE(u1, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
mp_clear(u2);
|
||||||
|
FREE_MP_INT_SIZE(u2, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
#endif
|
||||||
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
|
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
|
||||||
FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
|
FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||||
#include <wolfssl/wolfcrypt/ge_operations.h>
|
#include <wolfssl/wolfcrypt/ge_operations.h>
|
||||||
|
#include <wolfssl/wolfcrypt/logging.h>
|
||||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
#include <wolfssl/wolfcrypt/hash.h>
|
#include <wolfssl/wolfcrypt/hash.h>
|
||||||
#ifdef NO_INLINE
|
#ifdef NO_INLINE
|
||||||
@ -628,6 +629,35 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
|
|||||||
|
|
||||||
#ifdef HAVE_ED25519_VERIFY
|
#ifdef HAVE_ED25519_VERIFY
|
||||||
#ifndef WOLFSSL_SE050
|
#ifndef WOLFSSL_SE050
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
static const byte sha512_empty[] = {
|
||||||
|
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
|
||||||
|
0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
|
||||||
|
0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
|
||||||
|
0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
|
||||||
|
0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
|
||||||
|
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
|
||||||
|
0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
|
||||||
|
0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
|
||||||
|
};
|
||||||
|
|
||||||
|
/* sanity check that hash operation happened
|
||||||
|
* returns 0 on success */
|
||||||
|
static int ed25519_hash_check(ed25519_key* key, byte* h)
|
||||||
|
{
|
||||||
|
(void)key; /* passing in key in case other hash algroithms are used */
|
||||||
|
|
||||||
|
if (XMEMCMP(h, sha512_empty, WC_SHA512_DIGEST_SIZE) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return BAD_STATE_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sig is array of bytes containing the signature
|
sig is array of bytes containing the signature
|
||||||
sigLen is the length of sig byte array
|
sigLen is the length of sig byte array
|
||||||
@ -675,6 +705,22 @@ static int ed25519_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
|
|||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2);
|
ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
/* sanity check that hash operation happened */
|
||||||
|
if (ret == 0) {
|
||||||
|
byte h[WC_MAX_DIGEST_SIZE];
|
||||||
|
|
||||||
|
ret = wc_Sha512GetHash(sha, h);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = ed25519_hash_check(key, h);
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("Unexpected initial state of hash found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
|
ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
|
||||||
|
|
||||||
|
@ -512,6 +512,33 @@ int ge_frombytes_negate_vartime(ge_p3 *p,const unsigned char *s)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
/* return 0 if equal and -1 if not equal */
|
||||||
|
static int ge_equal(ge a, ge b)
|
||||||
|
{
|
||||||
|
if (XMEMCMP(a, b, sizeof(ge)) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns 0 if a == b */
|
||||||
|
static int ge_p3_equal(ge_p3* a, ge_p3* b)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret |= ge_equal(a->X, b->X);
|
||||||
|
ret |= ge_equal(a->Y, b->Y);
|
||||||
|
ret |= ge_equal(a->Z, b->Z);
|
||||||
|
ret |= ge_equal(a->T, b->T);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ge_double_scalarmult_vartime(ge_p2* R, const unsigned char *h,
|
int ge_double_scalarmult_vartime(ge_p2* R, const unsigned char *h,
|
||||||
const ge_p3 *inA,const unsigned char *sig)
|
const ge_p3 *inA,const unsigned char *sig)
|
||||||
@ -526,9 +553,19 @@ int ge_double_scalarmult_vartime(ge_p2* R, const unsigned char *h,
|
|||||||
|
|
||||||
/* find H(R,A,M) * -A */
|
/* find H(R,A,M) * -A */
|
||||||
ed25519_smult(&A, &A, h);
|
ed25519_smult(&A, &A, h);
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (ge_p3_equal(&A, (ge_p3*)inA) == 0) {
|
||||||
|
ret = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SB + -H(R,A,M)A */
|
/* SB + -H(R,A,M)A */
|
||||||
ed25519_add(&A, &p, &A);
|
ed25519_add(&A, &p, &A);
|
||||||
|
#ifdef WOLFSSL_CHECK_VER_FAULTS
|
||||||
|
if (ge_p3_equal(&A, &p) == 0) {
|
||||||
|
ret = BAD_STATE_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lm_copy(R->X, A.X);
|
lm_copy(R->X, A.X);
|
||||||
lm_copy(R->Y, A.Y);
|
lm_copy(R->Y, A.Y);
|
||||||
|
Reference in New Issue
Block a user