ED: add --enable-ed25519-stream and --enable-ed448-stream to configure.ac, disabled by default, and add them to --enable-all and --enable-all-crypto lists, along with --enable-aesgcm-stream; report AES-GCM and ED* streaming API options in feature summary rendered at end;

refactor ED routines to pivot on WOLFSSL_ED*_PERSISTENT_SHA and WOLFSSL_ED*_STREAMING_VERIFY macros, with sha state in the key struct only when WOLFSSL_ED*_PERSISTENT_SHA, otherwise on the stack as before;

add ed*_hash_init() and ed*_hash_free() local helpers;

ED* peer review: fix line lengths, remove superfluous retval checks, tweaks for efficiency, and add ED448_PREHASH_SIZE to ed448.h.
This commit is contained in:
Daniel Pouzzner
2021-07-14 15:32:33 -05:00
parent 9b43e57ccf
commit 5e8da2348f
7 changed files with 462 additions and 150 deletions

View File

@@ -350,6 +350,7 @@ then
test "$enable_atomicuser" = "" && enable_atomicuser=yes
test "$enable_pkcallbacks" = "" && enable_pkcallbacks=yes
test "$enable_aesgcm" = "" && enable_aesgcm=yes
test "$enable_aesgcm_stream" = "" && enable_aesgcm_stream=yes
test "$enable_aesccm" = "" && enable_aesccm=yes
test "$enable_aesctr" = "" && enable_aesctr=yes
test "$enable_aesofb" = "" && enable_aesofb=yes
@@ -459,7 +460,9 @@ then
test "$enable_scep" = "" && enable_scep=yes
test "$enable_pkcs7" = "" && enable_pkcs7=yes
test "$enable_ed25519" = "" && enable_ed25519=yes
test "$enable_ed25519_stream" = "" && enable_ed25519_stream=yes
test "$enable_ed448" = "" && enable_ed448=yes
test "$enable_ed448_stream" = "" && enable_ed448_stream=yes
if test "$ENABLED_LINUXKM_DEFAULTS" != "yes"
then
@@ -493,6 +496,7 @@ then
test "$enable_atomicuser" = "" && enable_atomicuser=yes
test "$enable_pkcallbacks" = "" && enable_pkcallbacks=yes
test "$enable_aesgcm" = "" && enable_aesgcm=yes
test "$enable_aesgcm_stream" = "" && enable_aesgcm_stream=yes
test "$enable_aesccm" = "" && enable_aesccm=yes
test "$enable_aesctr" = "" && enable_aesctr=yes
test "$enable_aesofb" = "" && enable_aesofb=yes
@@ -561,7 +565,9 @@ then
then
test "$enable_xchacha" = "" && enable_xchacha=yes
test "$enable_ed25519" = "" && enable_ed25519=yes
test "$enable_ed25519_stream" = "" && enable_ed25519_stream=yes
test "$enable_ed448" = "" && enable_ed448=yes
test "$enable_ed448_stream" = "" && enable_ed448_stream=yes
test "$enable_pkcs7" = "" && enable_pkcs7=yes
if test "$ENABLED_LINUXKM_DEFAULTS" != "yes"
@@ -1311,7 +1317,7 @@ AC_ARG_ENABLE([aesgcm],
[ ENABLED_AESGCM=yes ]
)
AC_ARG_ENABLE([aesgcm-stream],
[AS_HELP_STRING([--enable-aesgcm-stream],[Enable wolfSSL AES-GCM support with streaming APIs (default: enabled)])],
[AS_HELP_STRING([--enable-aesgcm-stream],[Enable wolfSSL AES-GCM support with streaming APIs (default: disabled)])],
[ ENABLED_AESGCM_STREAM=$enableval ],
[ ENABLED_AESGCM_STREAM=no ]
)
@@ -2141,6 +2147,11 @@ AC_ARG_ENABLE([ed25519],
[ ENABLED_ED25519=$enableval ],
[ ENABLED_ED25519=no ]
)
AC_ARG_ENABLE([ed25519-stream],
[AS_HELP_STRING([--enable-ed25519-stream],[Enable wolfSSL ED25519 support with streaming verify APIs (default: disabled)])],
[ ENABLED_ED25519_STREAM=$enableval ],
[ ENABLED_ED25519_STREAM=no ]
)
if test "$ENABLED_OPENSSH" = "yes"
@@ -2169,6 +2180,17 @@ then
ENABLED_CERTS=yes
fi
if test "$ENABLED_ED25519_STREAM" != "no"
then
if test "$ENABLED_ED25519" = "no"
then
AC_MSG_ERROR([ED25519 verify streaming enabled but ED25519 is disabled])
else
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ED25519_STREAMING_VERIFY"
fi
fi
# for using memory optimization setting on both curve448 and ed448
ENABLED_CURVE448_SMALL=no
@@ -2206,6 +2228,11 @@ AC_ARG_ENABLE([ed448],
[ ENABLED_ED448=$enableval ],
[ ENABLED_ED448=no ]
)
AC_ARG_ENABLE([ed448-stream],
[AS_HELP_STRING([--enable-ed448-stream],[Enable wolfSSL ED448 support with streaming verify APIs (default: disabled)])],
[ ENABLED_ED448_STREAM=$enableval ],
[ ENABLED_ED448_STREAM=no ]
)
if test "$ENABLED_ED448" != "no" && test "$ENABLED_32BIT" = "no"
then
@@ -2236,6 +2263,17 @@ then
ENABLED_CERTS=yes
fi
if test "$ENABLED_ED448_STREAM" != "no"
then
if test "$ENABLED_ED448" = "no"
then
AC_MSG_ERROR([ED448 verify streaming enabled but ED448 is disabled])
else
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ED448_STREAMING_VERIFY"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_ED448_STREAMING_VERIFY"
fi
fi
# FP ECC, Fixed Point cache ECC
@@ -6671,6 +6709,7 @@ echo " * AES-NI: $ENABLED_AESNI"
echo " * AES-CBC: $ENABLED_AESCBC"
echo " * AES-CBC length checks: $ENABLED_AESCBC_LENGTH_CHECKS"
echo " * AES-GCM: $ENABLED_AESGCM"
echo " * AES-GCM streaming: $ENABLED_AESGCM_STREAM"
echo " * AES-CCM: $ENABLED_AESCCM"
echo " * AES-CTR: $ENABLED_AESCTR"
echo " * AES-CFB: $ENABLED_AESCFB"
@@ -6722,8 +6761,10 @@ echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES"
echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ"
echo " * CURVE25519: $ENABLED_CURVE25519"
echo " * ED25519: $ENABLED_ED25519"
echo " * ED25519 streaming: $ENABLED_ED25519_STREAM"
echo " * CURVE448: $ENABLED_CURVE448"
echo " * ED448: $ENABLED_ED448"
echo " * ED448 streaming: $ENABLED_ED448_STREAM"
echo " * FPECC: $ENABLED_FPECC"
echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT"
echo " * ECCSI $ENABLED_ECCSI"

View File

@@ -56,6 +56,27 @@ static const byte ed25519Ctx[ED25519CTX_SIZE+1] =
"SigEd25519 no Ed25519 collisions";
#endif
static int ed25519_hash_init(ed25519_key* key, wc_Sha512 *sha)
{
int ret;
ret = wc_InitSha512_ex(sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
if (ret == 0)
key->sha_clean_flag = 1;
#endif
return ret;
}
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
static int ed25519_hash_reset(ed25519_key* key)
{
int ret;
@@ -75,36 +96,73 @@ static int ed25519_hash_reset(ed25519_key* key)
}
return ret;
}
#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
static int ed25519_hash_update(ed25519_key* key, const byte* data, word32 len)
static int ed25519_hash_update(ed25519_key* key, wc_Sha512 *sha,
const byte* data, word32 len)
{
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
if (key->sha_clean_flag)
key->sha_clean_flag = 0;
return wc_Sha512Update(&key->sha, data, len);
#else
(void)key;
#endif
return wc_Sha512Update(sha, data, len);
}
static int ed25519_hash_final(ed25519_key* key, byte* hash)
static int ed25519_hash_final(ed25519_key* key, wc_Sha512 *sha, byte* hash)
{
int ret = wc_Sha512Final(&key->sha, hash);
int ret = wc_Sha512Final(sha, hash);
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
if (ret == 0)
key->sha_clean_flag = 1;
#else
(void)key;
#endif
return ret;
}
static void ed25519_hash_free(ed25519_key* key, wc_Sha512 *sha)
{
wc_Sha512Free(sha);
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
key->sha_clean_flag = 0;
#else
(void)key;
#endif
}
static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen,
byte* hash)
{
int ret;
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 sha[1];
#else
wc_Sha512 *sha;
#endif
if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
sha = &key->sha;
ret = ed25519_hash_reset(key);
#else
ret = ed25519_hash_init(key, sha);
#endif
if (ret < 0)
return ret;
ret = ed25519_hash_update(key, sha, in, inLen);
if (ret == 0)
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, hash);
ret = ed25519_hash_final(key, sha, hash);
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
ed25519_hash_free(key, sha);
#endif
return ret;
}
@@ -252,23 +310,38 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
az[31] |= 64;
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
{
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 *sha = &key->sha;
#else
wc_Sha512 sha[1];
ret = ed25519_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, sha, &type, sizeof(type));
if (ret == 0)
ret = ed25519_hash_update(key, sha, &contextLen,
sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, sha, context, contextLen);
}
if (ret == 0)
ret = ed25519_hash_update(key, &type, sizeof(type));
ret = ed25519_hash_update(key, sha, az + ED25519_KEY_SIZE,
ED25519_KEY_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, context, contextLen);
ret = ed25519_hash_update(key, sha, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, sha, nonce);
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
ed25519_hash_free(key, sha);
#endif
}
if (ret == 0)
ret = ed25519_hash_update(key, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, nonce);
if (ret != 0)
return ret;
@@ -290,23 +363,39 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
/* step 3: hash R + public key + message getting H(R,A,M) then
creating S = (r + H(R,A,M)a) mod l */
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
{
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 *sha = &key->sha;
#else
wc_Sha512 sha[1];
ret = ed25519_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, sha, &type, sizeof(type));
if (ret == 0)
ret = ed25519_hash_update(key, sha, &contextLen,
sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, sha, context, contextLen);
}
if (ret == 0)
ret = ed25519_hash_update(key, &type, sizeof(type));
ret = ed25519_hash_update(key, sha, out, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, context, contextLen);
ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, sha, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, sha, hram);
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
ed25519_hash_free(key, sha);
#endif
}
if (ret == 0)
ret = ed25519_hash_update(key, out, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, in, inLen);
if (ret == 0)
ret = ed25519_hash_final(key, hram);
if (ret != 0)
return ret;
@@ -413,10 +502,12 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
context extra signing data
contextLen length of extra signing data
*/
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
byte type, const byte* context, byte contextLen)
static int ed25519_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
ed25519_key* key, wc_Sha512 *sha,
byte type, const byte* context,
byte contextLen)
{
int ret;
int ret;
/* sanity check on arguments */
if (sig == NULL || key == NULL ||
@@ -430,22 +521,27 @@ int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
/* find H(R,A,M) and store it as h */
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
ret = ed25519_hash_reset(key);
if (ret != 0)
return ret;
#else
ret = 0;
#endif
if (type == Ed25519ctx || type == Ed25519ph) {
ret = ed25519_hash_update(key, ed25519Ctx, ED25519CTX_SIZE);
ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = ed25519_hash_update(key, &type, sizeof(type));
ret = ed25519_hash_update(key, sha, &type, sizeof(type));
if (ret == 0)
ret = ed25519_hash_update(key, &contextLen, sizeof(contextLen));
ret = ed25519_hash_update(key, sha, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = ed25519_hash_update(key, context, contextLen);
ret = ed25519_hash_update(key, sha, context, contextLen);
}
if (ret == 0)
ret = ed25519_hash_update(key, sig, ED25519_SIG_SIZE/2);
ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = ed25519_hash_update(key, key->p, ED25519_PUB_KEY_SIZE);
ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
return ret;
}
@@ -456,13 +552,15 @@ int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
key Ed25519 public key
return 0 on success
*/
int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed25519_key* key) {
static int ed25519_verify_msg_update_with_sha(const byte* msgSegment,
word32 msgSegmentLen,
ed25519_key* key,
wc_Sha512 *sha) {
/* sanity check on arguments */
if (msgSegment == NULL || key == NULL)
return BAD_FUNC_ARG;
return ed25519_hash_update(key, msgSegment, msgSegmentLen);
return ed25519_hash_update(key, sha, msgSegment, msgSegmentLen);
}
/*
@@ -472,8 +570,9 @@ int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
key Ed25519 public key
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
ed25519_key* key)
static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
int* res, ed25519_key* key,
wc_Sha512 *sha)
{
byte rcheck[ED25519_KEY_SIZE];
byte h[WC_SHA512_DIGEST_SIZE];
@@ -502,7 +601,7 @@ int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
/* find H(R,A,M) and store it as h */
ret = ed25519_hash_final(key, h);
ret = ed25519_hash_final(key, sha, h);
if (ret != 0)
return ret;
@@ -535,6 +634,27 @@ int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
return ret;
}
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
byte type, const byte* context, byte contextLen) {
return ed25519_verify_msg_init_with_sha(sig, sigLen, key, &key->sha,
type, context, contextLen);
}
int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed25519_key* key) {
return ed25519_verify_msg_update_with_sha(msgSegment, msgSegmentLen,
key, &key->sha);
}
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
ed25519_key* key) {
return ed25519_verify_msg_final_with_sha(sig, sigLen, res,
key, &key->sha);
}
#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */
/*
sig is array of bytes containing the signature
@@ -550,6 +670,11 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
byte type, const byte* context, byte contextLen)
{
int ret;
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 *sha;
#else
wc_Sha512 sha[1];
#endif
/* sanity check on arguments */
if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
@@ -566,16 +691,24 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
}
#endif
ret = wc_ed25519_verify_msg_init(sig, sigLen, key,
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
sha = &key->sha;
#else
ret = ed25519_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
ret = ed25519_verify_msg_init_with_sha(sig, sigLen, key, sha,
type, context, contextLen);
if (ret < 0)
return ret;
ret = wc_ed25519_verify_msg_update(msg, msgLen, key);
ret = ed25519_verify_msg_update_with_sha(msg, msgLen, key, sha);
if (ret < 0)
return ret;
return wc_ed25519_verify_msg_final(sig, sigLen, res, key);
return ed25519_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
}
/*
@@ -591,7 +724,7 @@ int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key)
{
return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
(byte)Ed25519, NULL, 0);
(byte)Ed25519, NULL, 0);
}
/*
@@ -610,7 +743,7 @@ int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
const byte* context, byte contextLen)
{
return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
Ed25519ctx, context, contextLen);
Ed25519ctx, context, contextLen);
}
/*
@@ -629,7 +762,7 @@ int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
const byte* context, byte contextLen)
{
return wc_ed25519_verify_msg_ex(sig, sigLen, hash, hashLen, res, key,
Ed25519ph, context, contextLen);
Ed25519ph, context, contextLen);
}
/*
@@ -655,7 +788,7 @@ int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
return ret;
return wc_ed25519_verify_msg_ex(sig, sigLen, hash, sizeof(hash), res, key,
Ed25519ph, context, contextLen);
Ed25519ph, context, contextLen);
}
#endif /* HAVE_ED25519_VERIFY */
@@ -663,8 +796,6 @@ int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
/* initialize information and memory for key */
int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
{
int ret;
if (key == NULL)
return BAD_FUNC_ARG;
@@ -680,18 +811,11 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
fe_init();
#endif
ret = wc_InitSha512_ex(&key->sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
return ed25519_hash_init(key, &key->sha);
#else /* !WOLFSSL_ED25519_PERSISTENT_SHA */
return 0;
#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
}
int wc_ed25519_init(ed25519_key* key)
@@ -705,7 +829,9 @@ void wc_ed25519_free(ed25519_key* key)
if (key == NULL)
return;
wc_Sha512Free(&key->sha);
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
ed25519_hash_free(key, &key->sha);
#endif
ForceZero(key, sizeof(ed25519_key));
}

View File

@@ -51,6 +51,28 @@
static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448";
#endif
static int ed448_hash_init(ed448_key* key, wc_Shake *sha)
{
int ret;
ret = wc_InitShake256(sha, key->heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
if (ret == 0)
key->sha_clean_flag = 1;
#endif
return ret;
}
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
static int ed448_hash_reset(ed448_key* key)
{
int ret;
@@ -71,36 +93,74 @@ static int ed448_hash_reset(ed448_key* key)
}
return ret;
}
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
static int ed448_hash_update(ed448_key* key, const byte* data, word32 len)
static int ed448_hash_update(ed448_key* key, wc_Shake *sha, const byte* data,
word32 len)
{
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
if (key->sha_clean_flag)
key->sha_clean_flag = 0;
return wc_Shake256_Update(&key->sha, data, len);
#else
(void)key;
#endif
return wc_Shake256_Update(sha, data, len);
}
static int ed448_hash_final(ed448_key* key, byte* hash, word32 hashLen)
static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash,
word32 hashLen)
{
int ret = wc_Shake256_Final(&key->sha, hash, hashLen);
int ret = wc_Shake256_Final(sha, hash, hashLen);
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
if (ret == 0)
key->sha_clean_flag = 1;
#else
(void)key;
#endif
return ret;
}
static void ed448_hash_free(ed448_key* key, wc_Shake *sha)
{
wc_Shake256_Free(sha);
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
key->sha_clean_flag = 0;
#else
(void)key;
#endif
}
static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
byte* hash, word32 hashLen)
{
int ret;
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
wc_Shake sha[1];
#else
wc_Shake *sha;
#endif
if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
sha = &key->sha;
ret = ed448_hash_reset(key);
#else
ret = ed448_hash_init(key, sha);
#endif
if (ret < 0)
return ret;
ret = ed448_hash_update(key, sha, in, inLen);
if (ret == 0)
ret = ed448_hash_update(key, in, inLen);
if (ret == 0)
ret = ed448_hash_final(key, hash, hashLen);
ret = ed448_hash_final(key, sha, hash, hashLen);
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_free(key, sha);
#endif
return ret;
}
@@ -234,34 +294,52 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
}
if (ret == 0) {
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
wc_Shake *sha = &key->sha;
#else
wc_Shake sha[1];
ret = ed448_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
/* apply clamp */
az[0] &= 0xfc;
az[55] |= 0x80;
az[56] = 0x00;
ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
ret = ed448_hash_update(key, sha, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = ed448_hash_update(key, context, contextLen);
ret = ed448_hash_update(key, sha, context, contextLen);
}
if (ret == 0) {
ret = ed448_hash_update(key, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
}
if (ret == 0) {
ret = ed448_hash_update(key, in, inLen);
ret = ed448_hash_update(key, sha, in, inLen);
}
if (ret == 0) {
ret = ed448_hash_final(key, nonce, sizeof(nonce));
ret = ed448_hash_final(key, sha, nonce, sizeof(nonce));
}
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_free(key, sha);
#endif
}
if (ret == 0) {
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
wc_Shake *sha = &key->sha;
#else
wc_Shake sha[1];
ret = ed448_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
sc448_reduce(nonce);
/* step 2: computing R = rB where rB is the scalar multiplication of
@@ -271,30 +349,32 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
/* step 3: hash R + public key + message getting H(R,A,M) then
creating S = (r + H(R,A,M)a) mod l */
ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = ed448_hash_update(key, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = ed448_hash_update(key, context, contextLen);
}
if (ret == 0) {
ret = ed448_hash_update(key, out, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE);
}
if (ret == 0) {
ret = ed448_hash_update(key, in, inLen);
}
if (ret == 0) {
ret = ed448_hash_final(key, hram, sizeof(hram));
}
ret = ed448_hash_update(key, sha, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = ed448_hash_update(key, sha, context, contextLen);
}
if (ret == 0) {
ret = ed448_hash_update(key, sha, out, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
}
if (ret == 0) {
ret = ed448_hash_update(key, sha, in, inLen);
}
if (ret == 0) {
ret = ed448_hash_final(key, sha, hram, sizeof(hram));
}
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_free(key, sha);
#endif
}
if (ret == 0) {
@@ -374,8 +454,8 @@ int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
ed448_key* key, const byte* context, byte contextLen)
{
int ret = 0;
byte hash[64];
int ret;
byte hash[ED448_PREHASH_SIZE];
ret = ed448_hash(key, in, inLen, hash, sizeof(hash));
@@ -404,8 +484,10 @@ int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
* other -ve values when hash fails,
* 0 otherwise.
*/
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
byte type, const byte* context, byte contextLen)
static int ed448_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
ed448_key* key, wc_Shake *sha, byte type,
const byte* context, byte contextLen)
{
int ret;
@@ -421,25 +503,27 @@ int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
}
/* find H(R,A,M) and store it as h */
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
ret = ed448_hash_reset(key);
if (ret < 0)
return ret;
#endif
ret = ed448_hash_update(key, ed448Ctx, ED448CTX_SIZE);
ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
if (ret == 0) {
ret = ed448_hash_update(key, &type, sizeof(type));
ret = ed448_hash_update(key, sha, &type, sizeof(type));
}
if (ret == 0) {
ret = ed448_hash_update(key, &contextLen, sizeof(contextLen));
ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
}
if ((ret == 0) && (context != NULL)) {
ret = ed448_hash_update(key, context, contextLen);
ret = ed448_hash_update(key, sha, context, contextLen);
}
if (ret == 0) {
ret = ed448_hash_update(key, sig, ED448_SIG_SIZE/2);
ret = ed448_hash_update(key, sha, sig, ED448_SIG_SIZE/2);
}
if (ret == 0) {
ret = ed448_hash_update(key, key->p, ED448_PUB_KEY_SIZE);
ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
}
return ret;
@@ -451,14 +535,16 @@ int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
key Ed448 public key
return 0 on success
*/
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed448_key* key)
static int ed448_verify_msg_update_with_sha(const byte* msgSegment,
word32 msgSegmentLen,
ed448_key* key,
wc_Shake *sha)
{
/* sanity check on arguments */
if (msgSegment == NULL || key == NULL)
return BAD_FUNC_ARG;
return ed448_hash_update(key, msgSegment, msgSegmentLen);
return ed448_hash_update(key, sha, msgSegment, msgSegmentLen);
}
/* Verify the message using the ed448 public key.
@@ -472,8 +558,8 @@ int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
* other -ve values when hash fails,
* 0 otherwise.
*/
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
int* res, ed448_key* key)
static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
int* res, ed448_key* key, wc_Shake *sha)
{
byte rcheck[ED448_KEY_SIZE];
byte h[ED448_SIG_SIZE];
@@ -496,7 +582,7 @@ int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
return BAD_FUNC_ARG;
ret = ed448_hash_final(key, h, sizeof(h));
ret = ed448_hash_final(key, sha, h, sizeof(h));
if (ret != 0)
return ret;
@@ -524,6 +610,28 @@ int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
return ret;
}
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
byte type, const byte* context, byte contextLen)
{
return ed448_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, type,
context, contextLen);
}
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
ed448_key* key)
{
return ed448_verify_msg_update_with_sha(msgSegment, msgSegmentLen, key,
&key->sha);
}
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
int* res, ed448_key* key)
{
return ed448_verify_msg_final_with_sha(sig, sigLen, res, key, &key->sha);
}
#endif
/* Verify the message using the ed448 public key.
*
* sig [in] Signature to verify.
@@ -546,16 +654,35 @@ int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
byte type, const byte* context, byte contextLen)
{
int ret;
ret = wc_ed448_verify_msg_init(sig, sigLen, key,
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
wc_Shake *sha;
#else
wc_Shake sha[1];
#endif
if (key == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
sha = &key->sha;
#else
ret = ed448_hash_init(key, sha);
if (ret < 0)
return ret;
#endif
ret = ed448_verify_msg_init_with_sha(sig, sigLen, key, sha,
type, context, contextLen);
if (ret < 0)
return ret;
if (ret == 0)
ret = ed448_verify_msg_update_with_sha(msg, msgLen, key, sha);
if (ret == 0)
ret = ed448_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
ret = wc_ed448_verify_msg_update(msg, msgLen, key);
if (ret < 0)
return ret;
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_free(key, sha);
#endif
return wc_ed448_verify_msg_final(sig, sigLen, res, key);
return ret;
}
/* Verify the message using the ed448 public key.
@@ -627,7 +754,7 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
const byte* context, byte contextLen)
{
int ret = 0;
byte hash[64];
byte hash[ED448_PREHASH_SIZE];
ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash));
@@ -648,8 +775,6 @@ int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
*/
int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
{
int ret;
if (key == NULL)
return BAD_FUNC_ARG;
@@ -664,18 +789,11 @@ int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
fe448_init();
ret = wc_InitShake256(&key->sha, heap,
#if defined(WOLF_CRYPTO_CB)
key->devId
#else
INVALID_DEVID
#endif
);
if (ret == 0)
key->sha_clean_flag = 1;
return ret;
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
return ed448_hash_init(key, &key->sha);
#else /* !WOLFSSL_ED448_PERSISTENT_SHA */
return 0;
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
}
/* Initialize the ed448 private/public key.
@@ -694,7 +812,9 @@ int wc_ed448_init(ed448_key* key) {
void wc_ed448_free(ed448_key* key)
{
if (key != NULL) {
wc_Shake256_Free(&key->sha);
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_free(key, &key->sha);
#endif
ForceZero(key, sizeof(ed448_key));
}
}

View File

@@ -25143,7 +25143,9 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
int i;
word32 outlen;
#ifdef HAVE_ED25519_VERIFY
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
int j;
#endif
int verify;
#endif /* HAVE_ED25519_VERIFY */
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */
@@ -25551,6 +25553,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
&key) != 0 || verify != 1)
return -11031 - i;
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
/* test verify on good msg using streaming interface directly */
if (wc_ed25519_verify_msg_init(out, outlen,
&key, (byte)Ed25519, NULL, 0) != 0)
@@ -25562,6 +25565,7 @@ WOLFSSL_TEST_SUBROUTINE int ed25519_test(void)
if (wc_ed25519_verify_msg_final(out, outlen, &verify,
&key) != 0 || verify != 1)
return -11231 - i;
#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */
/* test verify on bad msg */
out[outlen-1] = out[outlen-1] + 1;
@@ -26455,7 +26459,9 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
int i;
word32 outlen;
#ifdef HAVE_ED448_VERIFY
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
int j;
#endif /* WOLFSSL_ED448_STREAMING_VERIFY */
int verify;
#endif /* HAVE_ED448_VERIFY */
#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */
@@ -26966,6 +26972,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
return -11731 - i;
}
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
/* test verify on good msg using streaming interface directly */
if (wc_ed448_verify_msg_init(out, outlen,
&key, (byte)Ed448, NULL, 0) != 0)
@@ -26977,6 +26984,7 @@ WOLFSSL_TEST_SUBROUTINE int ed448_test(void)
if (wc_ed448_verify_msg_final(out, outlen, &verify,
&key) != 0 || verify != 1)
return -11931 - i;
#endif /* WOLFSSL_ED448_STREAMING_VERIFY */
/* test verify on bad msg */
out[outlen-2] = out[outlen-2] + 1;

View File

@@ -94,8 +94,10 @@ struct ed25519_key {
int devId;
#endif
void *heap;
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 sha;
int sha_clean_flag;
#endif
};
@@ -145,6 +147,7 @@ WOLFSSL_API
int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
byte type, const byte* context, byte contextLen);
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
WOLFSSL_API
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
byte type, const byte* context, byte contextLen);
@@ -154,6 +157,7 @@ int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
WOLFSSL_API
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
ed25519_key* key);
#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */
#endif /* HAVE_ED25519_VERIFY */

View File

@@ -65,6 +65,7 @@
/* both private and public key */
#define ED448_PRV_KEY_SIZE (ED448_PUB_KEY_SIZE+ED448_KEY_SIZE)
#define ED448_PREHASH_SIZE 64
enum {
Ed448 = 0,
@@ -93,8 +94,10 @@ struct ed448_key {
int devId;
#endif
void *heap;
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
wc_Shake sha;
int sha_clean_flag;
#endif
};
@@ -125,6 +128,7 @@ WOLFSSL_API
int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed448_key* key,
byte type, const byte* context, byte contextLen);
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
WOLFSSL_API
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
byte type, const byte* context, byte contextLen);
@@ -134,6 +138,7 @@ int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
WOLFSSL_API
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
int* stat, ed448_key* key);
#endif /* WOLFSSL_ED448_STREAMING_VERIFY */
WOLFSSL_API
int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed448_key* key,

View File

@@ -1867,6 +1867,10 @@ extern void uITRON4_free(void *p) ;
#ifndef NO_ED25519_VERIFY
#undef HAVE_ED25519_VERIFY
#define HAVE_ED25519_VERIFY
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
#undef WOLFSSL_ED25519_PERSISTENT_SHA
#define WOLFSSL_ED25519_PERSISTENT_SHA
#endif
#endif
#ifndef NO_ED25519_KEY_EXPORT
#undef HAVE_ED25519_KEY_EXPORT
@@ -1905,6 +1909,10 @@ extern void uITRON4_free(void *p) ;
#ifndef NO_ED448_VERIFY
#undef HAVE_ED448_VERIFY
#define HAVE_ED448_VERIFY
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
#undef WOLFSSL_ED448_PERSISTENT_SHA
#define WOLFSSL_ED448_PERSISTENT_SHA
#endif
#endif
#ifndef NO_ED448_KEY_EXPORT
#undef HAVE_ED448_KEY_EXPORT