diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 6dfb7a0f2..56fcbc4ef 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -22,6 +22,12 @@ /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */ + +/* Possible Ed25519 enable options: + * WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN Default: OFF + * Check that the private key didn't change during the signing operations. + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -304,6 +310,9 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, ALIGN16 byte nonce[WC_SHA512_DIGEST_SIZE]; ALIGN16 byte hram[WC_SHA512_DIGEST_SIZE]; ALIGN16 byte az[ED25519_PRV_KEY_SIZE]; +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + byte orig_k[ED25519_KEY_SIZE]; +#endif /* sanity check on arguments */ if (in == NULL || out == NULL || outLen == NULL || key == NULL || @@ -331,6 +340,10 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, } *outLen = ED25519_SIG_SIZE; +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + XMEMCPY(orig_k, key->k, ED25519_KEY_SIZE); +#endif + /* step 1: create nonce to use where nonce is r in r = H(h_b, ... ,h_2b-1,M) */ ret = ed25519_hash(key, key->k, ED25519_KEY_SIZE, az); @@ -441,6 +454,18 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce); #endif #endif /* WOLFSSL_SE050 */ + +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + { + int i; + byte c = 0; + for (i = 0; i < ED25519_KEY_SIZE; i++) { + c |= key->k[i] ^ orig_k[i]; + } + ret = ctMaskGT(c, 0) & SIG_VERIFY_E; + } +#endif + return ret; } diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index 8eb83372d..81477213f 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -25,6 +25,11 @@ * Reworked for curve448 by Sean Parkinson. */ +/* Possible Ed448 enable options: + * WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN Default: OFF + * Check that the private key didn't change during the signing operations. + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -279,6 +284,9 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out, byte hram[ED448_SIG_SIZE]; byte az[ED448_PRV_KEY_SIZE]; int ret = 0; +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + byte orig_k[ED448_KEY_SIZE]; +#endif /* sanity check on arguments */ if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL) || @@ -298,6 +306,10 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out, if (ret == 0) { *outLen = ED448_SIG_SIZE; +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + XMEMCPY(orig_k, key->k, ED448_KEY_SIZE); +#endif + /* step 1: create nonce to use where nonce is r in r = H(h_b, ... ,h_2b-1,M) */ ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az)); @@ -391,6 +403,17 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out, sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce); } +#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN + if (ret == 0) { + int i; + byte c = 0; + for (i = 0; i < ED448_KEY_SIZE; i++) { + c |= key->k[i] ^ orig_k[i]; + } + ret = ctMaskGT(c, 0) & SIG_VERIFY_E; + } +#endif + return ret; } diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h index b45671d76..48011fce6 100644 --- a/wolfssl/wolfcrypt/ed448.h +++ b/wolfssl/wolfcrypt/ed448.h @@ -80,7 +80,7 @@ enum { /* An ED448 Key */ struct ed448_key { byte p[ED448_PUB_KEY_SIZE]; /* compressed public key */ - byte k[ED448_PRV_KEY_SIZE]; /* private key : 56 secret -- 56 public */ + byte k[ED448_PRV_KEY_SIZE]; /* private key : 57 secret -- 57 public */ #ifdef FREESCALE_LTC_ECC /* uncompressed point coordinates */ byte pointX[ED448_KEY_SIZE]; /* recovered X coordinate */