Initial revision of SHA-3
This commit is contained in:
parent
60c51db831
commit
4134073c8d
33
configure.ac
33
configure.ac
@ -167,6 +167,7 @@ then
|
||||
enable_ripemd=yes
|
||||
enable_sha512=yes
|
||||
enable_sha224=yes
|
||||
enable_sha3=yes
|
||||
enable_sessioncerts=yes
|
||||
enable_keygen=yes
|
||||
enable_certgen=yes
|
||||
@ -1758,6 +1759,37 @@ fi
|
||||
AM_CONDITIONAL([BUILD_SHA224], [test "x$ENABLED_SHA224" = "xyes"])
|
||||
|
||||
|
||||
# set sha3 default
|
||||
SHA3_DEFAULT=no
|
||||
if test "$host_cpu" = "x86_64"
|
||||
then
|
||||
if test "x$ENABLED_FIPS" = "xno"
|
||||
then
|
||||
SHA3_DEFAULT=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
# SHA3
|
||||
AC_ARG_ENABLE([sha3],
|
||||
[AS_HELP_STRING([--enable-sha3],[Enable wolfSSL SHA-3 support (default: enabled on x86_64)])],
|
||||
[ ENABLED_SHA3=$enableval ],
|
||||
[ ENABLED_SHA3=$SHA3_DEFAULT ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_SHA3" = "small"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA3_SMALL"
|
||||
ENABLED_SHA3="yes"
|
||||
fi
|
||||
|
||||
if test "$ENABLED_SHA3" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA3"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_SHA3], [test "x$ENABLED_SHA3" = "xyes"])
|
||||
|
||||
|
||||
# set POLY1305 default
|
||||
POLY1305_DEFAULT=yes
|
||||
|
||||
@ -3658,6 +3690,7 @@ echo " * RIPEMD: $ENABLED_RIPEMD"
|
||||
echo " * SHA: $ENABLED_SHA"
|
||||
echo " * SHA-224: $ENABLED_SHA224"
|
||||
echo " * SHA-512: $ENABLED_SHA512"
|
||||
echo " * SHA3: $ENABLED_SHA3"
|
||||
echo " * BLAKE2: $ENABLED_BLAKE2"
|
||||
echo " * CMAC: $ENABLED_CMAC"
|
||||
echo " * keygen: $ENABLED_KEYGEN"
|
||||
|
@ -115,6 +115,10 @@ if BUILD_SHA512
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512.c
|
||||
endif
|
||||
|
||||
if BUILD_SHA3
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha3.c
|
||||
endif
|
||||
|
||||
src_libwolfssl_la_SOURCES += \
|
||||
wolfcrypt/src/logging.c \
|
||||
wolfcrypt/src/wc_encrypt.c \
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include <wolfssl/wolfcrypt/sha.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#include <wolfssl/wolfcrypt/ripemd.h>
|
||||
@ -208,6 +209,10 @@ void bench_sha224(int);
|
||||
void bench_sha256(int);
|
||||
void bench_sha384(int);
|
||||
void bench_sha512(int);
|
||||
void bench_sha3_224(int);
|
||||
void bench_sha3_256(int);
|
||||
void bench_sha3_384(int);
|
||||
void bench_sha3_512(int);
|
||||
int bench_ripemd(void);
|
||||
void bench_cmac(void);
|
||||
void bench_scrypt(void);
|
||||
@ -824,6 +829,32 @@ static void* benchmarks_do(void* args)
|
||||
bench_sha512(1);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
#ifndef NO_SW_BENCH
|
||||
bench_sha3_224(0);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
bench_sha3_224(1);
|
||||
#endif
|
||||
#ifndef NO_SW_BENCH
|
||||
bench_sha3_256(0);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
bench_sha3_256(1);
|
||||
#endif
|
||||
#ifndef NO_SW_BENCH
|
||||
bench_sha3_384(0);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
bench_sha3_384(1);
|
||||
#endif
|
||||
#ifndef NO_SW_BENCH
|
||||
bench_sha3_512(0);
|
||||
#endif
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
|
||||
bench_sha3_512(1);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_RIPEMD
|
||||
bench_ripemd();
|
||||
#endif
|
||||
@ -2084,6 +2115,302 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA3
|
||||
void bench_sha3_224(int doAsync)
|
||||
{
|
||||
Sha3 hash[BENCH_MAX_PENDING];
|
||||
double start;
|
||||
int ret, i, count = 0, times;
|
||||
DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, SHA224_DIGEST_SIZE, HEAP_HINT);
|
||||
|
||||
bench_async_begin();
|
||||
|
||||
/* clear for done cleanup */
|
||||
XMEMSET(hash, 0, sizeof(hash));
|
||||
|
||||
/* init keys */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
ret = wc_InitSha3_224(&hash[i], HEAP_HINT,
|
||||
doAsync ? devId : INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("InitSha3_224 failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (times = 0; times < numBlocks || BENCH_ASYNC_IS_PEND(); ) {
|
||||
bench_async_poll();
|
||||
|
||||
/* while free pending slots in queue, submit ops */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_224_Update(&hash[i], bench_plain,
|
||||
BENCH_SIZE);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_224;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} /* for times */
|
||||
count += times;
|
||||
|
||||
times = 0;
|
||||
do {
|
||||
bench_async_poll();
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_224_Final(&hash[i], digest[i]);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_224;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} while (BENCH_ASYNC_IS_PEND());
|
||||
} while (bench_stats_sym_check(start));
|
||||
exit_sha3_224:
|
||||
bench_stats_sym_finish("SHA3-224", doAsync, count, start);
|
||||
|
||||
exit:
|
||||
|
||||
if (ret < 0) {
|
||||
printf("bench_sha3_224 failed: %d\n", ret);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
wc_Sha3_224_Free(&hash[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
|
||||
|
||||
bench_async_end();
|
||||
}
|
||||
|
||||
void bench_sha3_256(int doAsync)
|
||||
{
|
||||
Sha3 hash[BENCH_MAX_PENDING];
|
||||
double start;
|
||||
int ret, i, count = 0, times;
|
||||
DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, SHA3_256_DIGEST_SIZE, HEAP_HINT);
|
||||
|
||||
bench_async_begin();
|
||||
|
||||
/* clear for done cleanup */
|
||||
XMEMSET(hash, 0, sizeof(hash));
|
||||
|
||||
/* init keys */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
ret = wc_InitSha3_256(&hash[i], HEAP_HINT,
|
||||
doAsync ? devId : INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("InitSha3_256 failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (times = 0; times < numBlocks || BENCH_ASYNC_IS_PEND(); ) {
|
||||
bench_async_poll();
|
||||
|
||||
/* while free pending slots in queue, submit ops */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_256_Update(&hash[i], bench_plain,
|
||||
BENCH_SIZE);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_256;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} /* for times */
|
||||
count += times;
|
||||
|
||||
times = 0;
|
||||
do {
|
||||
bench_async_poll();
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_256_Final(&hash[i], digest[i]);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_256;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} while (BENCH_ASYNC_IS_PEND());
|
||||
} while (bench_stats_sym_check(start));
|
||||
exit_sha3_256:
|
||||
bench_stats_sym_finish("SHA3-256", doAsync, count, start);
|
||||
|
||||
exit:
|
||||
|
||||
if (ret < 0) {
|
||||
printf("bench_sha3_256 failed: %d\n", ret);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
wc_Sha3_256_Free(&hash[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
|
||||
|
||||
bench_async_end();
|
||||
}
|
||||
|
||||
void bench_sha3_384(int doAsync)
|
||||
{
|
||||
Sha3 hash[BENCH_MAX_PENDING];
|
||||
double start;
|
||||
int ret, i, count = 0, times;
|
||||
DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, SHA3_384_DIGEST_SIZE, HEAP_HINT);
|
||||
|
||||
bench_async_begin();
|
||||
|
||||
/* clear for done cleanup */
|
||||
XMEMSET(hash, 0, sizeof(hash));
|
||||
|
||||
/* init keys */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
ret = wc_InitSha3_384(&hash[i], HEAP_HINT,
|
||||
doAsync ? devId : INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("InitSha3_384 failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (times = 0; times < numBlocks || BENCH_ASYNC_IS_PEND(); ) {
|
||||
bench_async_poll();
|
||||
|
||||
/* while free pending slots in queue, submit ops */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_384_Update(&hash[i], bench_plain,
|
||||
BENCH_SIZE);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_384;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} /* for times */
|
||||
count += times;
|
||||
|
||||
times = 0;
|
||||
do {
|
||||
bench_async_poll();
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_384_Final(&hash[i], digest[i]);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_384;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} while (BENCH_ASYNC_IS_PEND());
|
||||
} while (bench_stats_sym_check(start));
|
||||
exit_sha3_384:
|
||||
bench_stats_sym_finish("SHA3-384", doAsync, count, start);
|
||||
|
||||
exit:
|
||||
|
||||
if (ret < 0) {
|
||||
printf("bench_sha3_384 failed: %d\n", ret);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
wc_Sha3_384_Free(&hash[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
|
||||
|
||||
bench_async_end();
|
||||
}
|
||||
|
||||
void bench_sha3_512(int doAsync)
|
||||
{
|
||||
Sha3 hash[BENCH_MAX_PENDING];
|
||||
double start;
|
||||
int ret, i, count = 0, times;
|
||||
DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, SHA3_512_DIGEST_SIZE, HEAP_HINT);
|
||||
|
||||
bench_async_begin();
|
||||
|
||||
/* clear for done cleanup */
|
||||
XMEMSET(hash, 0, sizeof(hash));
|
||||
|
||||
/* init keys */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
ret = wc_InitSha3_512(&hash[i], HEAP_HINT,
|
||||
doAsync ? devId : INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("InitSha3_512 failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (times = 0; times < numBlocks || BENCH_ASYNC_IS_PEND(); ) {
|
||||
bench_async_poll();
|
||||
|
||||
/* while free pending slots in queue, submit ops */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_512_Update(&hash[i], bench_plain,
|
||||
BENCH_SIZE);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_512;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} /* for times */
|
||||
count += times;
|
||||
|
||||
times = 0;
|
||||
do {
|
||||
bench_async_poll();
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×, numBlocks)) {
|
||||
ret = wc_Sha3_512_Final(&hash[i], digest[i]);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, ×)) {
|
||||
goto exit_sha3_512;
|
||||
}
|
||||
}
|
||||
} /* for i */
|
||||
} while (BENCH_ASYNC_IS_PEND());
|
||||
} while (bench_stats_sym_check(start));
|
||||
exit_sha3_512:
|
||||
bench_stats_sym_finish("SHA3-512", doAsync, count, start);
|
||||
|
||||
exit:
|
||||
|
||||
if (ret < 0) {
|
||||
printf("bench_sha3_512 failed: %d\n", ret);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
wc_Sha3_512_Free(&hash[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
|
||||
|
||||
bench_async_end();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_RIPEMD
|
||||
int bench_ripemd(void)
|
||||
{
|
||||
|
@ -40,7 +40,8 @@ EXTRA_DIST += \
|
||||
wolfcrypt/src/fp_sqr_comba_8.i \
|
||||
wolfcrypt/src/fp_sqr_comba_9.i \
|
||||
wolfcrypt/src/fp_sqr_comba_small_set.i \
|
||||
wolfcrypt/src/fe_x25519_128.i
|
||||
wolfcrypt/src/fe_x25519_128.i \
|
||||
wolfcrypt/src/sha3_long.i
|
||||
|
||||
EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
|
||||
wolfcrypt/src/port/ti/ti-des3.c \
|
||||
|
710
wolfcrypt/src/sha3.c
Executable file
710
wolfcrypt/src/sha3.c
Executable file
@ -0,0 +1,710 @@
|
||||
/* sha3.c
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#ifdef WOLFSSL_SHA3
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
/* fips wrapper calls, user can call direct */
|
||||
#ifdef HAVE_FIPS
|
||||
|
||||
int wc_InitSha3_224(Sha3* sha, void* heap, int devId)
|
||||
{
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return InitSha3_224_fips(sha);
|
||||
}
|
||||
int wc_Sha3_224_Update(Sha3* sha, const byte* data, word32 len)
|
||||
{
|
||||
if (sha == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_224_Update_fips(sha, data, len);
|
||||
}
|
||||
int wc_Sha3_224_Final(Sha3* sha, byte* out)
|
||||
{
|
||||
if (sha == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_224_Final_fips(sha, out);
|
||||
}
|
||||
void wc_Sha3_224_Free(Sha3* sha)
|
||||
{
|
||||
(void)sha;
|
||||
/* Not supported in FIPS */
|
||||
}
|
||||
|
||||
int wc_InitSha3_256(Sha3* sha, void* heap, int devId)
|
||||
{
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return InitSha3_256_fips(sha);
|
||||
}
|
||||
int wc_Sha3_256_Update(Sha3* sha, const byte* data, word32 len)
|
||||
{
|
||||
if (sha == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_256_Update_fips(sha, data, len);
|
||||
}
|
||||
int wc_Sha3_256_Final(Sha3* sha, byte* out)
|
||||
{
|
||||
if (sha == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_256_Final_fips(sha, out);
|
||||
}
|
||||
void wc_Sha3_256_Free(Sha3* sha)
|
||||
{
|
||||
(void)sha;
|
||||
/* Not supported in FIPS */
|
||||
}
|
||||
|
||||
int wc_InitSha3_384(Sha3* sha, void* heap, int devId)
|
||||
{
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return InitSha3_384_fips(sha);
|
||||
}
|
||||
int wc_Sha3_384_Update(Sha3* sha, const byte* data, word32 len)
|
||||
{
|
||||
if (sha == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_384_Update_fips(sha, data, len);
|
||||
}
|
||||
int wc_Sha3_384_Final(Sha3* sha, byte* out)
|
||||
{
|
||||
if (sha == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_384_Final_fips(sha, out);
|
||||
}
|
||||
void wc_Sha3_384_Free(Sha3* sha)
|
||||
{
|
||||
(void)sha;
|
||||
/* Not supported in FIPS */
|
||||
}
|
||||
|
||||
int wc_InitSha3_512(Sha3* sha, void* heap, int devId)
|
||||
{
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return InitSha3_512_fips(sha);
|
||||
}
|
||||
int wc_Sha3_512_Update(Sha3* sha, const byte* data, word32 len)
|
||||
{
|
||||
if (sha == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_512_Update_fips(sha, data, len);
|
||||
}
|
||||
int wc_Sha3_512_Final(Sha3* sha, byte* out)
|
||||
{
|
||||
if (sha == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return Sha3_512_Final_fips(sha, out);
|
||||
}
|
||||
void wc_Sha3_512_Free(Sha3* sha)
|
||||
{
|
||||
(void)sha;
|
||||
/* Not supported in FIPS */
|
||||
}
|
||||
|
||||
#else /* else build without fips */
|
||||
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA3_SMALL
|
||||
/**
|
||||
* Rotate a 64-bit value left.
|
||||
*
|
||||
* @param [in] a The number to rotate left.
|
||||
* @param [in] r The number od bits to rotate left.
|
||||
* @return The rotated number.
|
||||
*/
|
||||
#define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n))))
|
||||
|
||||
/** An array of values to XOR for block operation. */
|
||||
static const word64 hash_keccak_r[24] =
|
||||
{
|
||||
0x0000000000000001UL, 0x0000000000008082UL,
|
||||
0x800000000000808aUL, 0x8000000080008000UL,
|
||||
0x000000000000808bUL, 0x0000000080000001UL,
|
||||
0x8000000080008081UL, 0x8000000000008009UL,
|
||||
0x000000000000008aUL, 0x0000000000000088UL,
|
||||
0x0000000080008009UL, 0x000000008000000aUL,
|
||||
0x000000008000808bUL, 0x800000000000008bUL,
|
||||
0x8000000000008089UL, 0x8000000000008003UL,
|
||||
0x8000000000008002UL, 0x8000000000000080UL,
|
||||
0x000000000000800aUL, 0x800000008000000aUL,
|
||||
0x8000000080008081UL, 0x8000000000008080UL,
|
||||
0x0000000080000001UL, 0x8000000080008008UL
|
||||
};
|
||||
|
||||
#define K_I_0 10
|
||||
#define K_I_1 7
|
||||
#define K_I_2 11
|
||||
#define K_I_3 17
|
||||
#define K_I_4 18
|
||||
#define K_I_5 3
|
||||
#define K_I_6 5
|
||||
#define K_I_7 16
|
||||
#define K_I_8 8
|
||||
#define K_I_9 21
|
||||
#define K_I_10 24
|
||||
#define K_I_11 4
|
||||
#define K_I_12 15
|
||||
#define K_I_13 23
|
||||
#define K_I_14 19
|
||||
#define K_I_15 13
|
||||
#define K_I_16 12
|
||||
#define K_I_17 2
|
||||
#define K_I_18 20
|
||||
#define K_I_19 14
|
||||
#define K_I_20 22
|
||||
#define K_I_21 9
|
||||
#define K_I_22 6
|
||||
#define K_I_23 1
|
||||
|
||||
#define K_R_0 1
|
||||
#define K_R_1 3
|
||||
#define K_R_2 6
|
||||
#define K_R_3 10
|
||||
#define K_R_4 15
|
||||
#define K_R_5 21
|
||||
#define K_R_6 28
|
||||
#define K_R_7 36
|
||||
#define K_R_8 45
|
||||
#define K_R_9 55
|
||||
#define K_R_10 2
|
||||
#define K_R_11 14
|
||||
#define K_R_12 27
|
||||
#define K_R_13 41
|
||||
#define K_R_14 56
|
||||
#define K_R_15 8
|
||||
#define K_R_16 25
|
||||
#define K_R_17 43
|
||||
#define K_R_18 62
|
||||
#define K_R_19 18
|
||||
#define K_R_20 39
|
||||
#define K_R_21 61
|
||||
#define K_R_22 20
|
||||
#define K_R_23 44
|
||||
|
||||
/**
|
||||
* Swap and rotate left operation.
|
||||
*
|
||||
* @param [in] s The state.
|
||||
* @param [in] t1 Temporary value.
|
||||
* @param [in] t2 Second temporary value.
|
||||
* @param [in] i The index of the loop.
|
||||
*/
|
||||
#define SWAP_ROTL(s, t1, t2, i) \
|
||||
do \
|
||||
{ \
|
||||
t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* Mix the XOR of the column's values into each number by column.
|
||||
*
|
||||
* @param [in] s The state.
|
||||
* @param [in] b Temporary array of XORed column values.
|
||||
* @param [in] x The index of the column.
|
||||
* @param [in] t Temporary variable.
|
||||
*/
|
||||
#define COL_MIX(s, b, x, t) \
|
||||
do \
|
||||
{ \
|
||||
for (x = 0; x < 5; x++) \
|
||||
b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \
|
||||
for (x = 0; x < 5; x++) \
|
||||
{ \
|
||||
t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1); \
|
||||
s[x + 0] ^= t; \
|
||||
s[x + 5] ^= t; \
|
||||
s[x + 10] ^= t; \
|
||||
s[x + 15] ^= t; \
|
||||
s[x + 20] ^= t; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#ifdef SHA3_BY_SPEC
|
||||
/**
|
||||
* Mix the row values.
|
||||
* BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
|
||||
*
|
||||
* @param [in] s The state.
|
||||
* @param [in] b Temporary array of XORed row values.
|
||||
* @param [in] y The index of the row to work on.
|
||||
* @param [in] x The index of the column.
|
||||
* @param [in] t0 Temporary variable.
|
||||
* @param [in] t1 Temporary variable.
|
||||
*/
|
||||
#define ROW_MIX(s, b, y, x, t0, t1) \
|
||||
do \
|
||||
{ \
|
||||
for (y = 0; y < 5; y++) \
|
||||
{ \
|
||||
for (x = 0; x < 5; x++) \
|
||||
b[x] = s[y * 5 + x]; \
|
||||
for (x = 0; x < 5; x++) \
|
||||
s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
/**
|
||||
* Mix the row values.
|
||||
* a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
|
||||
*
|
||||
* @param [in] s The state.
|
||||
* @param [in] b Temporary array of XORed row values.
|
||||
* @param [in] y The index of the row to work on.
|
||||
* @param [in] x The index of the column.
|
||||
* @param [in] t0 Temporary variable.
|
||||
* @param [in] t1 Temporary variable.
|
||||
*/
|
||||
#define ROW_MIX(s, b, y, x, t12, t34) \
|
||||
do \
|
||||
{ \
|
||||
for (y = 0; y < 5; y++) \
|
||||
{ \
|
||||
for (x = 0; x < 5; x++) \
|
||||
b[x] = s[y * 5 + x]; \
|
||||
t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
|
||||
s[y * 5 + 0] = b[0] ^ (b[2] & t12); \
|
||||
s[y * 5 + 1] = t12 ^ (b[2] | b[3]); \
|
||||
s[y * 5 + 2] = b[2] ^ (b[4] & t34); \
|
||||
s[y * 5 + 3] = t34 ^ (b[4] | b[0]); \
|
||||
s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1])); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The block operation performed on the state.
|
||||
*
|
||||
* @param [in] s The state.
|
||||
*/
|
||||
static void BlockSha3(word64 *s)
|
||||
{
|
||||
byte i, x, y;
|
||||
word64 t0, t1;
|
||||
word64 b[5];
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
COL_MIX(s, b, x, t0);
|
||||
|
||||
t0 = s[1];
|
||||
SWAP_ROTL(s, t0, t1, 0);
|
||||
SWAP_ROTL(s, t1, t0, 1);
|
||||
SWAP_ROTL(s, t0, t1, 2);
|
||||
SWAP_ROTL(s, t1, t0, 3);
|
||||
SWAP_ROTL(s, t0, t1, 4);
|
||||
SWAP_ROTL(s, t1, t0, 5);
|
||||
SWAP_ROTL(s, t0, t1, 6);
|
||||
SWAP_ROTL(s, t1, t0, 7);
|
||||
SWAP_ROTL(s, t0, t1, 8);
|
||||
SWAP_ROTL(s, t1, t0, 9);
|
||||
SWAP_ROTL(s, t0, t1, 10);
|
||||
SWAP_ROTL(s, t1, t0, 11);
|
||||
SWAP_ROTL(s, t0, t1, 12);
|
||||
SWAP_ROTL(s, t1, t0, 13);
|
||||
SWAP_ROTL(s, t0, t1, 14);
|
||||
SWAP_ROTL(s, t1, t0, 15);
|
||||
SWAP_ROTL(s, t0, t1, 16);
|
||||
SWAP_ROTL(s, t1, t0, 17);
|
||||
SWAP_ROTL(s, t0, t1, 18);
|
||||
SWAP_ROTL(s, t1, t0, 19);
|
||||
SWAP_ROTL(s, t0, t1, 20);
|
||||
SWAP_ROTL(s, t1, t0, 21);
|
||||
SWAP_ROTL(s, t0, t1, 22);
|
||||
SWAP_ROTL(s, t1, t0, 23);
|
||||
|
||||
ROW_MIX(s, b, y, x, t0, t1);
|
||||
|
||||
s[0] ^= hash_keccak_r[i];
|
||||
}
|
||||
}
|
||||
#else
|
||||
#include "sha3_long.i"
|
||||
#endif
|
||||
|
||||
static word64 Load64BitBigEndian(const byte* x)
|
||||
{
|
||||
#if defined(BIG_ENDIAN_ORDER)
|
||||
word64 r = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
r |= (word64)x[i] << (8 * i);
|
||||
|
||||
return r;
|
||||
#else
|
||||
return *(word64*)x;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int InitSha3(Sha3* sha3)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
sha3->s[i] = 0;
|
||||
sha3->i = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Sha3Update(Sha3* sha3, const byte* data, word32 len, byte p)
|
||||
{
|
||||
byte i;
|
||||
byte l;
|
||||
byte *t;
|
||||
|
||||
if (sha3->i > 0)
|
||||
{
|
||||
l = p * 8 - sha3->i;
|
||||
if (l > len)
|
||||
l = len;
|
||||
|
||||
t = &sha3->t[sha3->i];
|
||||
for (i = 0; i < l; i++)
|
||||
t[i] = data[i];
|
||||
data += i;
|
||||
len -= i;
|
||||
sha3->i += i;
|
||||
|
||||
if (sha3->i == p * 8)
|
||||
{
|
||||
for (i = 0; i < p; i++)
|
||||
sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
|
||||
BlockSha3(sha3->s);
|
||||
sha3->i = 0;
|
||||
}
|
||||
}
|
||||
while (len >= p * 8)
|
||||
{
|
||||
for (i = 0; i < p; i++)
|
||||
sha3->s[i] ^= Load64BitBigEndian(data + 8 * i);
|
||||
BlockSha3(sha3->s);
|
||||
len -= p * 8;
|
||||
data += p * 8;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
sha3->t[i] = data[i];
|
||||
sha3->i += i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Sha3Final(Sha3* sha3, byte* hash, byte r, byte l)
|
||||
{
|
||||
byte i;
|
||||
byte *s8 = (byte *)sha3->s;
|
||||
|
||||
sha3->t[r * 8 - 1] = 0x00;
|
||||
sha3->t[ sha3->i] = 0x06;
|
||||
sha3->t[r * 8 - 1] |= 0x80;
|
||||
for (i=sha3->i + 1; i < r * 8 - 1; i++)
|
||||
sha3->t[i] = 0;
|
||||
for (i = 0; i < r; i++)
|
||||
sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
|
||||
BlockSha3(sha3->s);
|
||||
for (i = 0; i < l; i++)
|
||||
hash[i] = s8[i];
|
||||
#if defined(BIG_ENDIAN_ORDER)
|
||||
ByteReverseWords64((word64*)hash, (word64*)hash, l);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wc_InitSha3(Sha3* sha3, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sha3 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
sha3->heap = heap;
|
||||
ret = InitSha3(sha3);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
ret = wolfAsync_DevCtxInit(&sha3->asyncDev,
|
||||
WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId);
|
||||
#else
|
||||
(void)devId;
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wc_Sha3Update(Sha3* sha3, const byte* data, word32 len, byte p)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sha3 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
|
||||
#if defined(HAVE_INTEL_QA)
|
||||
return IntelQaSymSha3(&sha3->asyncDev, NULL, data, len);
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
Sha3Update(sha3, data, len, p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wc_Sha3Final(Sha3* sha3, byte* hash, byte p, byte len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha3 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
|
||||
#if defined(HAVE_INTEL_QA)
|
||||
return IntelQaSymSha3(&sha3->asyncDev, hash, NULL,
|
||||
SHA3_DIGEST_SIZE);
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
ret = Sha3Final(sha3, hash, p, len);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return InitSha3(sha3); /* reset state */
|
||||
}
|
||||
|
||||
static void wc_Sha3Free(Sha3* sha3)
|
||||
{
|
||||
(void)sha3;
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
|
||||
if (sha3 == NULL)
|
||||
return;
|
||||
|
||||
wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3);
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
}
|
||||
#endif /* HAVE_FIPS */
|
||||
|
||||
static int wc_Sha3Copy(Sha3* src, Sha3* dst)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (src == NULL || dst == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMCPY(dst, src, sizeof(Sha3));
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wc_Sha3GetHash(Sha3* sha3, byte* hash, byte p, byte l)
|
||||
{
|
||||
int ret;
|
||||
Sha3 tmpSha3;
|
||||
|
||||
if (sha3 == NULL || hash == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ret = wc_Sha3Copy(sha3, &tmpSha3);
|
||||
if (ret == 0) {
|
||||
ret = wc_Sha3Final(&tmpSha3, hash, p, l);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_224(Sha3* sha3, void* heap, int devId)
|
||||
{
|
||||
return wc_InitSha3(sha3, heap, devId);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_224_Update(Sha3* sha3, const byte* data, word32 len)
|
||||
{
|
||||
return wc_Sha3Update(sha3, data, len, SHA3_224_COUNT);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_224_Final(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3Final(sha3, hash, SHA3_224_COUNT, SHA3_224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha3_224_Free(Sha3* sha3)
|
||||
{
|
||||
wc_Sha3Free(sha3);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_224_GetHash(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3GetHash(sha3, hash, SHA3_224_COUNT, SHA3_224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_224_Copy(Sha3* src, Sha3* dst)
|
||||
{
|
||||
return wc_Sha3Copy(src, dst);
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_256(Sha3* sha3, void* heap, int devId)
|
||||
{
|
||||
return wc_InitSha3(sha3, heap, devId);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_256_Update(Sha3* sha3, const byte* data, word32 len)
|
||||
{
|
||||
return wc_Sha3Update(sha3, data, len, SHA3_256_COUNT);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_256_Final(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3Final(sha3, hash, SHA3_256_COUNT, SHA3_256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha3_256_Free(Sha3* sha3)
|
||||
{
|
||||
wc_Sha3Free(sha3);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_256_GetHash(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3GetHash(sha3, hash, SHA3_256_COUNT, SHA3_256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_256_Copy(Sha3* src, Sha3* dst)
|
||||
{
|
||||
return wc_Sha3Copy(src, dst);
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_384(Sha3* sha3, void* heap, int devId)
|
||||
{
|
||||
return wc_InitSha3(sha3, heap, devId);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_384_Update(Sha3* sha3, const byte* data, word32 len)
|
||||
{
|
||||
return wc_Sha3Update(sha3, data, len, SHA3_384_COUNT);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_384_Final(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3Final(sha3, hash, SHA3_384_COUNT, SHA3_384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha3_384_Free(Sha3* sha3)
|
||||
{
|
||||
wc_Sha3Free(sha3);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_384_GetHash(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3GetHash(sha3, hash, SHA3_384_COUNT, SHA3_384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_384_Copy(Sha3* src, Sha3* dst)
|
||||
{
|
||||
return wc_Sha3Copy(src, dst);
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_512(Sha3* sha3, void* heap, int devId)
|
||||
{
|
||||
return wc_InitSha3(sha3, heap, devId);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_512_Update(Sha3* sha3, const byte* data, word32 len)
|
||||
{
|
||||
return wc_Sha3Update(sha3, data, len, SHA3_512_COUNT);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_512_Final(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3Final(sha3, hash, SHA3_512_COUNT, SHA3_512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha3_512_Free(Sha3* sha3)
|
||||
{
|
||||
wc_Sha3Free(sha3);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_512_GetHash(Sha3* sha3, byte* hash)
|
||||
{
|
||||
return wc_Sha3GetHash(sha3, hash, SHA3_512_COUNT, SHA3_512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha3_512_Copy(Sha3* src, Sha3* dst)
|
||||
{
|
||||
return wc_Sha3Copy(src, dst);
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA3 */
|
2345
wolfcrypt/src/sha3_long.i
Normal file
2345
wolfcrypt/src/sha3_long.i
Normal file
File diff suppressed because it is too large
Load Diff
@ -95,6 +95,9 @@
|
||||
#ifdef HAVE_BLAKE2
|
||||
#include <wolfssl/wolfcrypt/blake2.h>
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <wolfssl/wolfcrypt/compress.h>
|
||||
#endif
|
||||
@ -209,6 +212,7 @@ int sha224_test(void);
|
||||
int sha256_test(void);
|
||||
int sha512_test(void);
|
||||
int sha384_test(void);
|
||||
int sha3_test(void);
|
||||
int hash_test(void);
|
||||
int hmac_md5_test(void);
|
||||
int hmac_sha_test(void);
|
||||
@ -479,6 +483,13 @@ int wolfcrypt_test(void* args)
|
||||
printf( "SHA-512 test passed!\n");
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA3
|
||||
if ( (ret = sha3_test()) != 0)
|
||||
return err_sys("SHA-3 test failed!\n", ret);
|
||||
else
|
||||
printf( "SHA-3 test passed!\n");
|
||||
#endif
|
||||
|
||||
if ( (ret = hash_test()) != 0)
|
||||
return err_sys("Hash test failed!\n", ret);
|
||||
else
|
||||
@ -1760,6 +1771,245 @@ int sha384_test(void)
|
||||
}
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#ifdef WOLFSSL_SHA3
|
||||
static int sha3_224_test(void)
|
||||
{
|
||||
Sha3 sha;
|
||||
byte hash[SHA3_224_DIGEST_SIZE];
|
||||
byte hashcopy[SHA3_224_DIGEST_SIZE];
|
||||
|
||||
testVector a, b;
|
||||
testVector test_sha[2];
|
||||
int ret;
|
||||
int times = sizeof(test_sha) / sizeof(struct testVector), i;
|
||||
|
||||
a.input = "abc";
|
||||
a.output = "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76"
|
||||
"\x6f\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf";
|
||||
a.inLen = XSTRLEN(a.input);
|
||||
a.outLen = SHA3_224_DIGEST_SIZE;
|
||||
|
||||
b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||
b.output = "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55\x74\x49\x44\x79"
|
||||
"\xba\x5c\x7e\x7a\xb7\x6e\xf2\x64\xea\xd0\xfc\xce\x33";
|
||||
b.inLen = XSTRLEN(b.input);
|
||||
b.outLen = SHA3_224_DIGEST_SIZE;
|
||||
|
||||
test_sha[0] = a;
|
||||
test_sha[1] = b;
|
||||
|
||||
ret = wc_InitSha3_224(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return -2000;
|
||||
|
||||
for (i = 0; i < times; ++i) {
|
||||
ret = wc_Sha3_224_Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
|
||||
if (ret != 0)
|
||||
return -2010 - i;
|
||||
ret = wc_Sha3_224_GetHash(&sha, hashcopy);
|
||||
if (ret != 0)
|
||||
return -2020 - i;
|
||||
ret = wc_Sha3_224_Final(&sha, hash);
|
||||
if (ret != 0)
|
||||
return -2030 - i;
|
||||
|
||||
if (XMEMCMP(hash, test_sha[i].output, SHA3_224_DIGEST_SIZE) != 0)
|
||||
return -2040 - i;
|
||||
|
||||
if (XMEMCMP(hash, hashcopy, SHA3_224_DIGEST_SIZE) != 0)
|
||||
return -2050 - i;
|
||||
}
|
||||
wc_Sha3_224_Free(&sha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha3_256_test(void)
|
||||
{
|
||||
Sha3 sha;
|
||||
byte hash[SHA3_256_DIGEST_SIZE];
|
||||
byte hashcopy[SHA3_256_DIGEST_SIZE];
|
||||
|
||||
testVector a, b;
|
||||
testVector test_sha[2];
|
||||
int ret;
|
||||
int times = sizeof(test_sha) / sizeof(struct testVector), i;
|
||||
|
||||
a.input = "abc";
|
||||
a.output = "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90"
|
||||
"\xbd\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43"
|
||||
"\x15\x32";
|
||||
a.inLen = XSTRLEN(a.input);
|
||||
a.outLen = SHA3_256_DIGEST_SIZE;
|
||||
|
||||
b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||
b.output = "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8\x23\x5e"
|
||||
"\x2c\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32\xdd\x97\x49\x6d"
|
||||
"\x33\x76";
|
||||
b.inLen = XSTRLEN(b.input);
|
||||
b.outLen = SHA3_256_DIGEST_SIZE;
|
||||
|
||||
test_sha[0] = a;
|
||||
test_sha[1] = b;
|
||||
|
||||
ret = wc_InitSha3_256(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return -2100;
|
||||
|
||||
for (i = 0; i < times; ++i) {
|
||||
ret = wc_Sha3_256_Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
|
||||
if (ret != 0)
|
||||
return -2110 - i;
|
||||
ret = wc_Sha3_256_GetHash(&sha, hashcopy);
|
||||
if (ret != 0)
|
||||
return -2120 - i;
|
||||
ret = wc_Sha3_256_Final(&sha, hash);
|
||||
if (ret != 0)
|
||||
return -2130 - i;
|
||||
|
||||
if (XMEMCMP(hash, test_sha[i].output, SHA3_256_DIGEST_SIZE) != 0)
|
||||
return -2140 - i;
|
||||
|
||||
if (XMEMCMP(hash, hashcopy, SHA3_256_DIGEST_SIZE) != 0)
|
||||
return -2150 - i;
|
||||
}
|
||||
wc_Sha3_256_Free(&sha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha3_384_test(void)
|
||||
{
|
||||
Sha3 sha;
|
||||
byte hash[SHA3_384_DIGEST_SIZE];
|
||||
byte hashcopy[SHA3_384_DIGEST_SIZE];
|
||||
|
||||
testVector a, b;
|
||||
testVector test_sha[2];
|
||||
int ret;
|
||||
int times = sizeof(test_sha) / sizeof(struct testVector), i;
|
||||
|
||||
a.input = "abc";
|
||||
a.output = "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad"
|
||||
"\x8d\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b"
|
||||
"\xe4\xb2\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28"
|
||||
"\x37\x6d\x25";
|
||||
a.inLen = XSTRLEN(a.input);
|
||||
a.outLen = SHA3_384_DIGEST_SIZE;
|
||||
|
||||
b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||
b.output = "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7\x8a\x49"
|
||||
"\x2e\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd\xbc\x32\xb9\xd4"
|
||||
"\xad\x5a\xa0\x4a\x1f\x07\x6e\x62\xfe\xa1\x9e\xef\x51\xac\xd0"
|
||||
"\x65\x7c\x22";
|
||||
b.inLen = XSTRLEN(b.input);
|
||||
b.outLen = SHA3_384_DIGEST_SIZE;
|
||||
|
||||
test_sha[0] = a;
|
||||
test_sha[1] = b;
|
||||
|
||||
ret = wc_InitSha3_384(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return -2200;
|
||||
|
||||
for (i = 0; i < times; ++i) {
|
||||
ret = wc_Sha3_384_Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
|
||||
if (ret != 0)
|
||||
return -2210 - i;
|
||||
ret = wc_Sha3_384_GetHash(&sha, hashcopy);
|
||||
if (ret != 0)
|
||||
return -2220 - i;
|
||||
ret = wc_Sha3_384_Final(&sha, hash);
|
||||
if (ret != 0)
|
||||
return -2230 - i;
|
||||
|
||||
if (XMEMCMP(hash, test_sha[i].output, SHA3_384_DIGEST_SIZE) != 0)
|
||||
return -2240 - i;
|
||||
|
||||
if (XMEMCMP(hash, hashcopy, SHA3_384_DIGEST_SIZE) != 0)
|
||||
return -2250 - i;
|
||||
}
|
||||
wc_Sha3_384_Free(&sha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha3_512_test(void)
|
||||
{
|
||||
Sha3 sha;
|
||||
byte hash[SHA3_512_DIGEST_SIZE];
|
||||
byte hashcopy[SHA3_512_DIGEST_SIZE];
|
||||
|
||||
testVector a, b;
|
||||
testVector test_sha[2];
|
||||
int ret;
|
||||
int times = sizeof(test_sha) / sizeof(struct testVector), i;
|
||||
|
||||
a.input = "abc";
|
||||
a.output = "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09"
|
||||
"\x6e\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2"
|
||||
"\x71\x2e\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47"
|
||||
"\xe3\x93\x40\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27"
|
||||
"\x4e\xec\x53\xf0";
|
||||
a.inLen = XSTRLEN(a.input);
|
||||
a.outLen = SHA3_512_DIGEST_SIZE;
|
||||
|
||||
b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||
b.output = "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10\xfc\xa8"
|
||||
"\x18\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7\xec\x2f\x1e\x91"
|
||||
"\x63\x6d\xee\x69\x1f\xbe\x0c\x98\x53\x02\xba\x1b\x0d\x8d\xc7"
|
||||
"\x8c\x08\x63\x46\xb5\x33\xb4\x9c\x03\x0d\x99\xa2\x7d\xaf\x11"
|
||||
"\x39\xd6\xe7\x5e";
|
||||
b.inLen = XSTRLEN(b.input);
|
||||
b.outLen = SHA3_512_DIGEST_SIZE;
|
||||
|
||||
test_sha[0] = a;
|
||||
test_sha[1] = b;
|
||||
|
||||
ret = wc_InitSha3_512(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return -2300;
|
||||
|
||||
for (i = 0; i < times; ++i) {
|
||||
ret = wc_Sha3_512_Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
|
||||
if (ret != 0)
|
||||
return -2310 - i;
|
||||
ret = wc_Sha3_512_GetHash(&sha, hashcopy);
|
||||
if (ret != 0)
|
||||
return -2320 - i;
|
||||
ret = wc_Sha3_512_Final(&sha, hash);
|
||||
if (ret != 0)
|
||||
return -2330 - i;
|
||||
|
||||
if (XMEMCMP(hash, test_sha[i].output, SHA3_512_DIGEST_SIZE) != 0)
|
||||
return -2340 - i;
|
||||
|
||||
if (XMEMCMP(hash, hashcopy, SHA3_512_DIGEST_SIZE) != 0)
|
||||
return -2350 - i;
|
||||
}
|
||||
wc_Sha3_512_Free(&sha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha3_test(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = sha3_224_test()) != 0)
|
||||
return ret;
|
||||
if ((ret = sha3_256_test()) != 0)
|
||||
return ret;
|
||||
if ((ret = sha3_384_test()) != 0)
|
||||
return ret;
|
||||
if ((ret = sha3_512_test()) != 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int hash_test(void)
|
||||
{
|
||||
wc_HashAlg hash;
|
||||
|
@ -59,7 +59,8 @@ nobase_include_HEADERS+= \
|
||||
wolfssl/wolfcrypt/mem_track.h \
|
||||
wolfssl/wolfcrypt/wolfevent.h \
|
||||
wolfssl/wolfcrypt/pkcs12.h \
|
||||
wolfssl/wolfcrypt/wolfmath.h
|
||||
wolfssl/wolfcrypt/wolfmath.h \
|
||||
wolfssl/wolfcrypt/sha3.h
|
||||
|
||||
noinst_HEADERS+= \
|
||||
wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \
|
||||
|
119
wolfssl/wolfcrypt/sha3.h
Normal file
119
wolfssl/wolfcrypt/sha3.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* sha3.h
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* code submitted by raphael.huck@efixo.com */
|
||||
|
||||
#ifndef WOLF_CRYPT_SHA3_H
|
||||
#define WOLF_CRYPT_SHA3_H
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef WOLFSSL_SHA3
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* for fips @wc_fips */
|
||||
#include <cyassl/ctaocrypt/sha3.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FIPS /* avoid redefinition of structs */
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
#include <wolfssl/wolfcrypt/async.h>
|
||||
#endif
|
||||
|
||||
/* in bytes */
|
||||
enum {
|
||||
SHA3_224 = 10, /* hash type unique */
|
||||
SHA3_224_DIGEST_SIZE = 28,
|
||||
SHA3_224_COUNT = 18,
|
||||
|
||||
SHA3_256 = 11, /* hash type unique */
|
||||
SHA3_256_DIGEST_SIZE = 32,
|
||||
SHA3_256_COUNT = 17,
|
||||
|
||||
SHA3_384 = 12, /* hash type unique */
|
||||
SHA3_384_DIGEST_SIZE = 48,
|
||||
SHA3_384_COUNT = 13,
|
||||
|
||||
SHA3_512 = 13, /* hash type unique */
|
||||
SHA3_512_DIGEST_SIZE = 64,
|
||||
SHA3_512_COUNT = 9
|
||||
};
|
||||
|
||||
|
||||
/* Sha3 digest */
|
||||
typedef struct Sha3 {
|
||||
/* State data that is processed for each block. */
|
||||
word64 s[25];
|
||||
/* Unprocessed message data. */
|
||||
byte t[200];
|
||||
/* Index into unprocessed data to place next message byte. */
|
||||
byte i;
|
||||
|
||||
void* heap;
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
WC_ASYNC_DEV asyncDev;
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
} Sha3;
|
||||
|
||||
#endif /* HAVE_FIPS */
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_224(Sha3*, void*, int);
|
||||
WOLFSSL_API int wc_Sha3_224_Update(Sha3*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha3_224_Final(Sha3*, byte*);
|
||||
WOLFSSL_API void wc_Sha3_224_Free(Sha3*);
|
||||
WOLFSSL_API int wc_Sha3_224_GetHash(Sha3*, byte*);
|
||||
WOLFSSL_API int wc_Sha3_224_Copy(Sha3* src, Sha3* dst);
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_256(Sha3*, void*, int);
|
||||
WOLFSSL_API int wc_Sha3_256_Update(Sha3*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha3_256_Final(Sha3*, byte*);
|
||||
WOLFSSL_API void wc_Sha3_256_Free(Sha3*);
|
||||
WOLFSSL_API int wc_Sha3_256_GetHash(Sha3*, byte*);
|
||||
WOLFSSL_API int wc_Sha3_256_Copy(Sha3* src, Sha3* dst);
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_384(Sha3*, void*, int);
|
||||
WOLFSSL_API int wc_Sha3_384_Update(Sha3*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha3_384_Final(Sha3*, byte*);
|
||||
WOLFSSL_API void wc_Sha3_384_Free(Sha3*);
|
||||
WOLFSSL_API int wc_Sha3_384_GetHash(Sha3*, byte*);
|
||||
WOLFSSL_API int wc_Sha3_384_Copy(Sha3* src, Sha3* dst);
|
||||
|
||||
WOLFSSL_API int wc_InitSha3_512(Sha3*, void*, int);
|
||||
WOLFSSL_API int wc_Sha3_512_Update(Sha3*, const byte*, word32);
|
||||
WOLFSSL_API int wc_Sha3_512_Final(Sha3*, byte*);
|
||||
WOLFSSL_API void wc_Sha3_512_Free(Sha3*);
|
||||
WOLFSSL_API int wc_Sha3_512_GetHash(Sha3*, byte*);
|
||||
WOLFSSL_API int wc_Sha3_512_Copy(Sha3* src, Sha3* dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_SHA3 */
|
||||
#endif /* WOLF_CRYPT_SHA3_H */
|
||||
|
Loading…
Reference in New Issue
Block a user