Compare commits

...

37 Commits

Author SHA1 Message Date
John Safranek
9e3e14c875 Add guard around ECC PCT for builds without validate keygen. 2021-03-25 10:22:34 -07:00
John Safranek
5a05fea772 Add types for the RNG seed callback and the OS_Seed. 2021-03-25 10:22:31 -07:00
John Safranek
dad73837f4 Hushed compiler warnings about unused variables. 2021-03-24 17:48:48 -07:00
John Safranek
c6545b5ad5 Merge branch 'master' into fipsv3 2021-03-24 17:15:15 -07:00
John Safranek
e788b2805f 56Ar3 Testing Updates
1. Add PCTs for ECC and FFC.
2. Update the public key checks for ECC and FFC.
2021-03-24 16:58:52 -07:00
John Safranek
0f0eebfc08 RNG Update
1. When the seed callback is enabled, allow wc_GenerateSeed() to be used
   as a default callback.
2. Modify all the tests and examples to use the default seed callback if
   the seed callback is enabled.
2021-03-24 16:45:19 -07:00
John Safranek
1c064dd957 If the RNG seeding callback is missing or returns an error, the RNG instantiate fails. 2021-03-17 12:18:21 -07:00
John Safranek
ff64584f34 Removed an outdated comment. 2021-03-11 14:37:00 -08:00
John Safranek
b87fca669d 1. Rename and relabel the FIPS 140-3 option as wolfCrypt v5.
2. Make sure the correct SHA assembly files are copied over for the latest FIPS build.
2021-03-11 08:51:54 -08:00
John Safranek
30d0188fca Add callback option for RNG seeding. 2021-03-09 10:43:26 -08:00
John Safranek
7134608d9f Merge branch 'master' into fipsv3
# Conflicts:
#	wolfssl/wolfcrypt/hash.h
2021-03-05 07:59:04 -08:00
John Safranek
49b80c94b7 Add option to fips-check script to checkout specific named files from the FIPS tag. 2021-03-04 16:26:19 -08:00
John Safranek
69d2e4db6a DH key gen should call DH check key. 2021-03-04 14:10:48 -08:00
John Safranek
6fa1fe5b8e ECC key gen should call ECC check key. 2021-03-04 13:19:02 -08:00
John Safranek
5080b1d633 Restrict AES-GCM IV minimum size to 96-bits for newer FIPS builds. 2021-03-04 09:55:44 -08:00
John Safranek
8634ccc51b Remove MD5 and old TLS from the newest FIPS build. 2021-03-03 08:30:09 -08:00
John Safranek
675a571818 Add CASTs for TLSv1.2, TLSv1.3, and SSH KDFs. 2021-03-01 08:47:03 -08:00
John Safranek
d68622539d Fix another configure error due to rebase. 2021-02-26 13:15:10 -08:00
John Safranek
1368cac8b5 Add RSA PAT. 2021-02-26 10:17:51 -08:00
John Safranek
4a75585c7a Add ECDSA-KAT CAST. 2021-02-25 16:03:55 -08:00
John Safranek
466076a7cc FIPSv3
1. Remove the CAST IDs for the redundant RSA tests.
2. Remove the flags in configure.ac that enable the keys for the redundant RSA tests.
2021-02-25 11:07:26 -08:00
John Safranek
edca780b61 Restore a configure check lost in a rebase. 2021-02-24 18:47:53 -08:00
John Safranek
3da0713ecd Use the new APIs for HKDF extract with label. 2021-02-24 18:23:37 -08:00
John Safranek
5343092346 1. Add flag to DH keys when using safe parameters.
2. The LN check is skipped when using safe parameters.
3. Enable all FFDHE parameter sets when building for FIPS 140-3.
2021-02-24 18:23:37 -08:00
John Safranek
8ab396cb45 Move the TLSv1.3 KDF into wolfCrypt with the other KDFs. 2021-02-24 18:23:37 -08:00
John Safranek
77e6849786 Add HMAC-SHA2-512 to the TLSv1.2 PRF. 2021-02-24 18:23:37 -08:00
John Safranek
08c2f7f656 Add prototype for the ssh-kdf test in the wolfCrypt test. 2021-02-24 18:23:36 -08:00
John Safranek
131fb2c1e6 KDF Update
1. Move wolfSSH's KDF into wolfCrypt.
2021-02-24 18:23:36 -08:00
John Safranek
2672856042 FIPS KDF Update
1. Copied the TLSv1.2 PRF into hmac.c since it uses it and the TLSv1.3
   HKDF is in there as well.
2. Added guard around the old TLS PRF so that it switches in correctly
   for older FIPS builds only.
2021-02-24 18:23:36 -08:00
John Safranek
344950a36d FIPS CAST Update
1. In the unit test, when checking the build options, also check for
   FIPSv4 to make sure 2048-bit RSA is used.
2. In the standalone SHA-1 one step hash function, wc_InitSha() wasn't
   getting called, so the FIPS flags didn't get checked. (It was using
   wc_InitSha_ex() which bypasses the FIPS checks.)
2021-02-24 18:23:36 -08:00
John Safranek
9c1fe16e62 Fix a bad assignment in the configure script. 2021-02-24 18:23:34 -08:00
John Safranek
c4a45b372f FIPS CAST Update
1. Added a public API to run a CAST.
2. Added the other test certs for the RSA tests.
3. Added IDs for the new RSA tests and the SHA3-pairwise test.
2021-02-24 18:21:07 -08:00
John Safranek
7d727938ec Update the fips-check script to pull the sources from GitHub rather than
from a directory on a local machine.
2021-02-24 18:21:07 -08:00
John Safranek
d5f6ef9f3b FIPS 140-3
1. Change the internal version number for the FIPS 140-3 changes as v4.
2. Insert v3 as an alias for FIPS Ready.
3. Use the correct directory for the FIPS old files sources. (For local
   testing of 140-3 builds.)
4. Change back the check for the FIPS version in internal.c for
   EccMakeKey().
2021-02-24 18:21:02 -08:00
John Safranek
bad6cd9677 FIPS 140-3
1. Fix issue with FIPS Ready and FIPS 140-3. FR acts at the latest
   version in the code, but that leaves DES3 out of the build. The code
   was still including the header. Force DES3 disabled in FIPS Ready
   builds.
2021-02-24 18:00:50 -08:00
John Safranek
8e4983f823 FIPS 140-3
1. Add the old known answer test prototype back into fips_test.h for FIPSv2 builds.
2021-02-24 18:00:50 -08:00
John Safranek
2b6dc31145 FIPS 140-3
1. Added enable option for FIPS 140-3 in configure script.
2. Modify DES3 source to disallow DES3 for the new option.
3. Added the new constants to fips_test.h.
4. Added some new test functions.
5. Added API for doing the POST.
6. Added a processing state for the CASTs.
7. Delete some unused prototypes from FIPS test API.
2021-02-24 18:00:44 -08:00
37 changed files with 1807 additions and 322 deletions

View File

@@ -180,23 +180,32 @@ ENABLED_CERTS="no"
# FIPS
# FIPS 140-2
AC_ARG_ENABLE([fips],
[AS_HELP_STRING([--enable-fips],[Enable FIPS 140-2, Will NOT work w/o FIPS license (default: disabled)])],
[ENABLED_FIPS=$enableval],
[ENABLED_FIPS="no"])
# The FIPS options are:
# v5 - FIPS 140-3 (wolfCrypt v5.0.0)
# v3 - FIPS Ready
# ready - same as v3
# rand - wolfRand
# v2 - FIPS 140-2 Cert 3389
# no - FIPS build disabled
# v1 - FIPS 140-2 Cert 2425
# default - same as v1
AS_CASE([$ENABLED_FIPS],
[ready],[
[ready|v3],[
ENABLED_FIPS="yes"
FIPS_VERSION="v2"
FIPS_VERSION="v3"
FIPS_READY="yes"
],
[no],[
FIPS_VERSION="none"
ENABLED_FIPS="no"
],
[rand|v1|v2],[
[rand|v1|v2|v5],[
FIPS_VERSION="$ENABLED_FIPS"
ENABLED_FIPS="yes"
],
@@ -207,7 +216,7 @@ AS_CASE([$ENABLED_FIPS],
FIPS_VERSION="v1"
],
[
AC_MSG_ERROR([Invalid value for --enable-fips "$ENABLED_FIPS" (allowed: ready, rand, v1, v2)])
AC_MSG_ERROR([Invalid value for --enable-fips "$ENABLED_FIPS" (allowed: ready, rand, v1, v2, v5)])
])
AS_CASE([$FIPS_VERSION],
@@ -227,6 +236,13 @@ AS_CASE([$FIPS_VERSION],
]
)
# FIPS 140-3
AC_ARG_ENABLE([fips-3],
[AS_HELP_STRING([--enable-fips-3],[Enable FIPS 140-3, Will NOT work w/o FIPS license (default: disabled)])],
[ENABLED_FIPS_140_3=$enableval],
[ENABLED_FIPS_140_3="no"])
AS_IF([test "x$ENABLED_FIPS_140_3" = "xyes"],[ENABLED_FIPS="yes";FIPS_VERSION="v5"])
# Linux Kernel Module
AC_ARG_ENABLE([linuxkm],
[AS_HELP_STRING([--enable-linuxkm],[Enable Linux Kernel Module (default: disabled)])],
@@ -1742,7 +1758,7 @@ fi
SHA3_DEFAULT=no
if test "$host_cpu" = "x86_64" || test "$host_cpu" = "aarch64"
then
if test "x$ENABLED_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2"
if test "x$ENABLED_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2" || test "x$FIPS_VERSION" = "xv3" || test "x$FIPS_VERSION" = "xv5"
then
SHA3_DEFAULT=yes
fi
@@ -3015,13 +3031,43 @@ fi
# FIPS
AS_CASE([$FIPS_VERSION],
["v2"],[
AS_IF([test "x$FIPS_READY" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS_VERSION=3"],
[AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS_VERSION=2"])
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS -DWOLFSSL_KEY_GEN -DWOLFSSL_SHA224 -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DHAVE_ECC_CDH -DWC_RSA_NO_PADDING -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q"
["v5"], [ # FIPS 140-3
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS -DHAVE_FIPS_VERSION=5 -DWOLFSSL_KEY_GEN -DWOLFSSL_SHA224 -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DHAVE_ECC_CDH -DWC_RSA_NO_PADDING"
ENABLED_KEYGEN="yes"; ENABLED_SHA224="yes"; ENABLED_DES3="no"; ENABLED=WOLFSSH="yes"
# Shake256 is a SHA-3 algorithm not in our FIPS algorithm list
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_SHAKE256"
AS_IF([test "x$ENABLED_AESCCM" != "xyes"],
[ENABLED_AESCCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESCCM"])
AS_IF([test "x$ENABLED_RSAPSS" != "xyes"],
[ENABLED_RSAPSS="yes"; AM_CFLAGS="$AM_CFLAGS -DWC_RSA_PSS"])
AS_IF([test "x$ENABLED_ECC" != "xyes"],
[ENABLED_ECC="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC -DTFM_ECC256"
AS_IF([test "x$ENABLED_ECC_SHAMIR" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DECC_SHAMIR"])],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT -DWOLFSSL_VALIDATE_ECC_KEYGEN"])
AS_IF([test "x$ENABLED_AESCTR" != "xyes"],
[ENABLED_AESCTR="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_COUNTER"])
AS_IF([test "x$ENABLED_CMAC" != "xyes"],
[ENABLED_CMAC="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CMAC"])
AS_IF([test "x$ENABLED_HKDF" != "xyes"],
[ENABLED_HKDF="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_HKDF"])
AS_IF([test "x$ENABLED_INTELASM" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DFORCE_FAILURE_RDSEED"])
AS_IF([test "x$ENABLED_SHA512" = "xno"],
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
AS_IF([test "x$ENABLED_AESGCM" = "xno"],
[ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"])
AS_IF([test "x$ENABLED_MD5" = "xyes"],[ENABLED_MD5="no"; ENABLED_OLD_TLS="no"; AM_CFLAGS="$AM_CFLAGS -DNO_MD5 -DNO_OLD_TLS"])
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT -DECC_USER_CURVES -DHAVE_ECC256 -DHAVE_ECC384 -DHAVE_ECC521"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECDSA_SET_K -DWC_RNG_SEED_CB"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q"
AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DFP_MAX_BITS=16384"
],
["v3"],[ # FIPS Ready
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS -DHAVE_FIPS_VERSION=3 -DWOLFSSL_KEY_GEN -DWOLFSSL_SHA224 -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DHAVE_ECC_CDH -DWC_RSA_NO_PADDING -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q"
ENABLED_KEYGEN="yes"
ENABLED_SHA224="yes"
ENABLED_DES3="yes"
# Shake256 is a SHA-3 algorithm not in our FIPS algorithm list
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_SHAKE256"
AS_IF([test "x$ENABLED_AESCCM" != "xyes"],
@@ -3047,29 +3093,61 @@ AS_CASE([$FIPS_VERSION],
AM_CFLAGS="$AM_CFLAGS -DHAVE_HKDF"])
AS_IF([test "x$ENABLED_INTELASM" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DFORCE_FAILURE_RDSEED"])
AS_IF([test "x$ENABLED_SHA512" = "xno"],
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
AS_IF([test "x$ENABLED_AESGCM" = "xno"],
[ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"])
],
["v2"],[ # Cert 3389
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS -DHAVE_FIPS_VERSION=2 -DWOLFSSL_KEY_GEN -DWOLFSSL_SHA224 -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DHAVE_ECC_CDH -DWC_RSA_NO_PADDING -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q"
ENABLED_KEYGEN="yes"
ENABLED_SHA224="yes"
ENABLED_DES3="yes"
# Shake256 is a SHA-3 algorithm not in our FIPS algorithm list
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_SHAKE256"
AS_IF([test "x$ENABLED_AESCCM" != "xyes"],
[ENABLED_AESCCM="yes"
AM_CFLAGS="$AM_CFLAGS -DHAVE_AESCCM"])
AS_IF([test "x$ENABLED_RSAPSS" != "xyes"],
[ENABLED_RSAPSS="yes"
AM_CFLAGS="$AM_CFLAGS -DWC_RSA_PSS"])
AS_IF([test "x$ENABLED_ECC" != "xyes"],
[ENABLED_ECC="yes"
AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC -DTFM_ECC256 -DWOLFSSL_VALIDATE_ECC_IMPORT"
AS_IF([test "x$ENABLED_ECC_SHAMIR" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DECC_SHAMIR"])],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT"])
AS_IF([test "x$ENABLED_AESCTR" != "xyes"],
[ENABLED_AESCTR="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_COUNTER"])
AS_IF([test "x$ENABLED_CMAC" != "xyes"],
[ENABLED_CMAC="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CMAC"])
AS_IF([test "x$ENABLED_HKDF" != "xyes"],
[ENABLED_HKDF="yes"
AM_CFLAGS="$AM_CFLAGS -DHAVE_HKDF"])
AS_IF([test "x$ENABLED_INTELASM" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DFORCE_FAILURE_RDSEED"])
AS_IF([test "x$ENABLED_SHA512" = "xno"],
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
AS_IF([test "x$ENABLED_AESGCM" = "xno"],
[ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"])
],
["rand"],[
AM_CFLAGS="$AM_CFLAGS -DWOLFCRYPT_FIPS_RAND -DHAVE_FIPS -DHAVE_FIPS_VERSION=2"
],
["v1"],[
["v1"],[ # Cert 2425
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS"
AS_IF([test "x$ENABLED_SHA512" = "xno"],
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
AS_IF([test "x$ENABLED_AESGCM" = "xno"],
[ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"])
AS_IF([test "x$ENABLED_DES3" = "xno"],[ENABLED_DES3="yes"])
])
AS_IF([test "x$ENABLED_FIPS" = "xyes" && test "x$thread_ls_on" = "xno"],
[AC_MSG_ERROR([FIPS requires Thread Local Storage])])
AS_IF([test "x$ENABLED_FIPS" = "xyes" && test "x$FIPS_VERSION" != "xrand"],
[
# Force enable the prerequisites.
AS_IF([test "x$ENABLED_SHA512" = "xno"],
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
AS_IF([test "x$ENABLED_AESGCM" = "xno"],
[ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"])
AS_IF([test "x$ENABLED_DES3" = "xno"],[ENABLED_DES3="yes"])
],
[
AS_IF([test "x$ENABLED_FORTRESS" = "xyes"],[ENABLED_DES3="yes"])
])
# SELFTEST
@@ -3101,22 +3179,12 @@ AS_CASE([$SELFTEST_VERSION],
])
# set POLY1305 default
POLY1305_DEFAULT=yes
if test "x$ENABLED_FIPS" = "xyes"
then
POLY1305_DEFAULT=no
fi
# Set SHA-3 and SHAKE256 flags
if test "$ENABLED_SHA3" = "yes" && test "$ENABLED_32BIT" = "no"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA3"
fi
AS_IF([test "x$ENABLED_FIPS" = "xyes"],[ENABLED_SHAKE256="no"])
if test "$ENABLED_SHAKE256" = "yes" || test "$ENABLED_SHAKE256" = "small"
then
@@ -3130,6 +3198,13 @@ then
fi
fi
# set POLY1305 default
POLY1305_DEFAULT=yes
if test "x$ENABLED_FIPS" = "xyes"
then
POLY1305_DEFAULT=no
fi
# POLY1305
AC_ARG_ENABLE([poly1305],
@@ -6041,6 +6116,8 @@ if test "x$ENABLED_OPENSSLCOEXIST" = "xyes"; then
fi
fi
AS_IF([test "x$ENABLED_WOLFSSH" = "xyes"],[AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_WOLFSSH"])
if test "x$ENABLED_CERTS" = "xno" || test "x$ENABLED_LEANPSK" = "xyes" || test "x$ENABLED_ASN" = "xno"; then
AM_CFLAGS="$AM_CFLAGS -DNO_ASN -DNO_CERTS"
fi
@@ -6251,7 +6328,9 @@ AM_CONDITIONAL([BUILD_FIPS],[test "x$ENABLED_FIPS" = "xyes"])
AM_CONDITIONAL([BUILD_FIPS_V1],[test "x$FIPS_VERSION" = "xv1"])
AM_CONDITIONAL([BUILD_FIPS_V2],[test "x$FIPS_VERSION" = "xv2"])
AM_CONDITIONAL([BUILD_FIPS_RAND],[test "x$FIPS_VERSION" = "xrand"])
AM_CONDITIONAL([BUILD_FIPS_READY],[test "x$FIPS_READY" = "xyes"])
AM_CONDITIONAL([BUILD_FIPS_V3],[test "x$FIPS_VERSION" = "xv3"])
AM_CONDITIONAL([BUILD_FIPS_V4],[test "x$FIPS_VERSION" = "xv5"])
AM_CONDITIONAL([BUILD_FIPS_CURRENT],[test "x$FIPS_VERSION" = "xv2" || test "x$FIPS_VERSION" = "xv3" || test "x$FIPS_VERSION" = "xv5"])
AM_CONDITIONAL([BUILD_CMAC],[test "x$ENABLED_CMAC" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_SELFTEST],[test "x$ENABLED_SELFTEST" = "xyes"])
AM_CONDITIONAL([BUILD_SHA224],[test "x$ENABLED_SHA224" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])

View File

@@ -1586,6 +1586,9 @@ int bench_tls(void* args)
/* Initialize wolfSSL */
wolfSSL_Init();
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
/* Parse command line arguments */
while ((ch = mygetopt(argc, argv, "?" "udeil:p:t:vT:sch:P:mS:")) != -1) {

View File

@@ -3875,6 +3875,9 @@ exit:
wolfSSL_Debugging_ON();
#endif
wolfSSL_Init();
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
ChangeToWolfRoot();
#ifndef NO_WOLFSSL_CLIENT

View File

@@ -387,6 +387,9 @@ void echoclient_test(void* args)
#if defined(DEBUG_CYASSL) && !defined(WOLFSSL_MDK_SHELL)
CyaSSL_Debugging_ON();
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#ifndef CYASSL_TIRTOS
ChangeToWolfRoot();
#endif

View File

@@ -558,6 +558,9 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
CyaSSL_Init();
#if defined(DEBUG_CYASSL) && !defined(CYASSL_MDK_SHELL)
CyaSSL_Debugging_ON();
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
ChangeToWolfRoot();
#ifndef NO_WOLFSSL_SERVER

View File

@@ -70,6 +70,9 @@ int main()
const char* response = "hello there";
char buffer[80];
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
if (ctx == NULL)
err_sys("ctx new dtls client failed");

View File

@@ -76,6 +76,9 @@ int main()
const char* response = "well hello to you";
char buffer[80];
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
if (ctx == NULL)
err_sys("ctx new dtls server failed");

View File

@@ -2952,6 +2952,9 @@ exit:
wolfSSL_Debugging_ON();
#endif
wolfSSL_Init();
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
ChangeToWolfRoot();
#ifndef NO_WOLFSSL_SERVER

View File

@@ -36,6 +36,7 @@ Platform is one of:
stm32l4-v2 (FIPSv2, use for STM32L4)
wolfrand
solaris
linuxv5 (FIPS 140-3)
Keep (default off) retains the XXX-fips-test temp dir for inspection.
Example:
@@ -265,6 +266,21 @@ solaris)
FIPS_OPTION=v2
MAKE=gmake
;;
linuxv5)
FIPS_REPO="git@github.com:ejohnstown/fips.git"
FIPS_VERSION="fipsv3"
CRYPT_REPO="git@github.com:ejohnstown/wolfssl.git"
CRYPT_VERSION="fipsv3"
CRYPT_INC_PATH="wolfssl/wolfcrypt"
CRYPT_SRC_PATH="wolfcrypt/src"
WC_MODS=( aes sha sha256 sha512 rsa hmac random cmac dh ecc sha3 )
RNG_VERSION="fipsv3"
FIPS_SRCS=( fips.c fips_test.c wolfcrypt_first.c wolfcrypt_last.c )
FIPS_INCS=( fips.h )
FIPS_OPTION="v5"
COPY_DIRECT=( wolfcrypt/src/aes_asm.S wolfcrypt/src/aes_asm.asm
wolfcrypt/src/sha256_asm.S wolfcrypt/src/sha512_asm.S )
;;
*)
Usage
exit 1
@@ -304,7 +320,7 @@ then
cp "old-tree/$CRYPT_SRC_PATH/random.c" $CRYPT_SRC_PATH
cp "old-tree/$CRYPT_INC_PATH/random.h" $CRYPT_INC_PATH
fi
elif [ "x$FIPS_OPTION" == "xv2" ] || [ "x$FIPS_OPTION" == "xrand" ]
elif [ "x$FIPS_OPTION" == "xv2" ] || [ "x$FIPS_OPTION" == "xrand" ] || [ "x$FIPS_OPTION" == "xv5" ]
then
$GIT branch --no-track "my$CRYPT_VERSION" $CRYPT_VERSION
# Checkout the fips versions of the wolfCrypt files from the repo.
@@ -313,9 +329,14 @@ then
$GIT checkout "my$CRYPT_VERSION" -- "$CRYPT_SRC_PATH/$MOD.c" "$CRYPT_INC_PATH/$MOD.h"
done
$GIT branch --no-track "my$RNG_VERSION" $RNG_VERSION
for MOD in "${COPY_DIRECT[@]}"
do
$GIT checkout "my$CRYPT_VERSION" -- "$MOD"
done
$GIT branch --no-track "myrng$RNG_VERSION" $RNG_VERSION
# Checkout the fips versions of the wolfCrypt files from the repo.
$GIT checkout "my$RNG_VERSION" -- "$CRYPT_SRC_PATH/random.c" "$CRYPT_INC_PATH/random.h"
$GIT checkout "myrng$RNG_VERSION" -- "$CRYPT_SRC_PATH/random.c" "$CRYPT_INC_PATH/random.h"
elif [ "x$FIPS_OPTION" == "xready" ]
then
echo "Don't need to copy anything in particular for FIPS Ready."
@@ -325,14 +346,14 @@ else
fi
# clone the FIPS repository
if [ "x$FIPS_OPTION" != "xready" ]
if [ "x$FIPS_OPTION" = "xready" ]
then
if ! $GIT clone --depth 1 -b $FIPS_VERSION $FIPS_REPO fips; then
echo "fips-check: Couldn't checkout the FIPS repository."
if ! $GIT clone --depth 1 $FIPS_REPO fips; then
echo "fips-check: Couldn't checkout the FIPS repository for FIPS Ready."
exit 1
fi
else
if ! $GIT clone --depth 1 $FIPS_REPO fips; then
if ! $GIT clone --depth 1 -b $FIPS_VERSION $FIPS_REPO fips; then
echo "fips-check: Couldn't checkout the FIPS repository."
exit 1
fi

View File

@@ -61,12 +61,12 @@ src_libwolfssl_la_SOURCES += ctaocrypt/src/fips_test.c
# fips last file
src_libwolfssl_la_SOURCES += ctaocrypt/src/wolfcrypt_last.c
endif
endif BUILD_FIPS_V1
if BUILD_FIPS_V2
# FIPSv2 first file
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/wolfcrypt_first.c
wolfcrypt/src/wolfcrypt_first.c
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/hmac.c \
@@ -83,11 +83,6 @@ endif
if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM
if BUILD_FIPS_READY
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-aes.c
endif
endif
endif
if BUILD_AESNI
@@ -105,10 +100,152 @@ if BUILD_SHA
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha.c
endif
if BUILD_ARMASM
if BUILD_FIPS_READY
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha256.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256_asm.S
endif
if BUILD_SHA512
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512_asm.S
endif
endif
if BUILD_SHA3
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha3.c
endif
if BUILD_DH
src_libwolfssl_la_SOURCES += wolfcrypt/src/dh.c
endif
if BUILD_CMAC
src_libwolfssl_la_SOURCES += wolfcrypt/src/cmac.c
endif
src_libwolfssl_la_SOURCES += wolfcrypt/src/fips.c \
wolfcrypt/src/fips_test.c
# fips last file
src_libwolfssl_la_SOURCES += wolfcrypt/src/wolfcrypt_last.c
endif BUILD_FIPS_V2
if BUILD_FIPS_RAND
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/wolfcrypt_first.c \
wolfcrypt/src/hmac.c \
wolfcrypt/src/random.c \
wolfcrypt/src/sha256.c \
wolfcrypt/src/sha256_asm.S \
wolfcrypt/src/fips.c \
wolfcrypt/src/fips_test.c \
wolfcrypt/src/wolfcrypt_last.c
endif BUILD_FIPS_RAND
if BUILD_FIPS_V3
# FIPS Ready first file
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/wolfcrypt_first.c
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/hmac.c \
wolfcrypt/src/random.c \
wolfcrypt/src/sha256.c
if BUILD_RSA
src_libwolfssl_la_SOURCES += wolfcrypt/src/rsa.c
endif
if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif
if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
endif
if BUILD_AESNI
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_asm.S
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_gcm_asm.S
endif
endif
if BUILD_DES3
src_libwolfssl_la_SOURCES += wolfcrypt/src/des3.c
endif
if BUILD_SHA
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256_asm.S
endif
endif
if BUILD_SHA512
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512.c
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512_asm.S
endif
endif
if BUILD_SHA3
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha3.c
endif
if BUILD_DH
src_libwolfssl_la_SOURCES += wolfcrypt/src/dh.c
endif
if BUILD_CMAC
src_libwolfssl_la_SOURCES += wolfcrypt/src/cmac.c
endif
src_libwolfssl_la_SOURCES += wolfcrypt/src/fips.c \
wolfcrypt/src/fips_test.c
# FIPS Ready last file
src_libwolfssl_la_SOURCES += wolfcrypt/src/wolfcrypt_last.c
endif BUILD_FIPS_V3
if BUILD_FIPS_V4
# FIPS 140-3 first file
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/wolfcrypt_first.c
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/hmac.c \
wolfcrypt/src/random.c \
wolfcrypt/src/sha256.c
if BUILD_RSA
src_libwolfssl_la_SOURCES += wolfcrypt/src/rsa.c
endif
if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif
if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-aes.c
endif
endif
if BUILD_AESNI
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_asm.S
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_gcm_asm.S
endif
endif
if BUILD_SHA
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha.c
endif
if BUILD_ARMASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha256.c
endif
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256_asm.S
@@ -117,12 +254,10 @@ endif
if BUILD_SHA512
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512.c
if BUILD_ARMASM
if BUILD_FIPS_READY
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha512.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha512-asm.S
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-32-sha512-asm.S
endif
endif
if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512_asm.S
endif
@@ -145,19 +280,7 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/fips.c \
# fips last file
src_libwolfssl_la_SOURCES += wolfcrypt/src/wolfcrypt_last.c
endif
if BUILD_FIPS_RAND
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/wolfcrypt_first.c \
wolfcrypt/src/hmac.c \
wolfcrypt/src/random.c \
wolfcrypt/src/sha256.c \
wolfcrypt/src/sha256_asm.S \
wolfcrypt/src/fips.c \
wolfcrypt/src/fips_test.c \
wolfcrypt/src/wolfcrypt_last.c
endif BUILD_FIPS_RAND
endif BUILD_FIPS_V4
endif BUILD_FIPS
@@ -168,9 +291,9 @@ if !BUILD_FIPS_RAND
# For wolfRand, exclude just a couple files.
# For old FIPS, keep the wolfCrypt versions of the
# CtaoCrypt files included above.
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
src_libwolfssl_la_SOURCES += wolfcrypt/src/hmac.c
endif
endif !BUILD_FIPS_CURRENT
# CAVP self test
if BUILD_SELFTEST
@@ -185,13 +308,13 @@ src_libwolfssl_la_SOURCES += \
if !BUILD_FIPS_RAND
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_RNG
src_libwolfssl_la_SOURCES += wolfcrypt/src/random.c
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_ARMASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha256.c
else
@@ -200,7 +323,7 @@ if BUILD_INTELASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256_asm.S
endif
endif
endif
endif !BUILD_FIPS_CURRENT
if BUILD_AFALG
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/af_alg/afalg_hash.c
@@ -219,9 +342,9 @@ if BUILD_RSA
if BUILD_FAST_RSA
src_libwolfssl_la_SOURCES += wolfcrypt/user-crypto/src/rsa.c
else
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
src_libwolfssl_la_SOURCES += wolfcrypt/src/rsa.c
endif
endif !BUILD_FIPS_CURRENT
endif
endif
endif
@@ -234,7 +357,7 @@ if BUILD_SP
if BUILD_SP_C
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_c32.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_c64.c
endif
endif BUILD_SP_C
if BUILD_SP_X86_64
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_x86_64.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_x86_64_asm.S
@@ -258,9 +381,9 @@ endif
if BUILD_SP_ARM_CORTEX
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_cortexm.c
endif
endif
endif BUILD_SP
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM
@@ -270,27 +393,27 @@ if BUILD_AFALG
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/af_alg/afalg_aes.c
endif
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_CMAC
src_libwolfssl_la_SOURCES += wolfcrypt/src/cmac.c
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_DES3
src_libwolfssl_la_SOURCES += wolfcrypt/src/des3.c
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_SHA
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha.c
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_SHA512
if BUILD_ARMASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-sha512.c
@@ -303,14 +426,13 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512_asm.S
endif
endif
endif
endif
endif !BUILD_FIPS_CURRENT
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_SHA3
src_libwolfssl_la_SOURCES += wolfcrypt/src/sha3.c
endif
endif
endif !BUILD_FIPS_CURRENT
endif !BUILD_FIPS_RAND
@@ -331,7 +453,7 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/memory.c
endif
if !BUILD_FIPS_RAND
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_DH
src_libwolfssl_la_SOURCES += wolfcrypt/src/dh.c
endif
@@ -380,7 +502,7 @@ if BUILD_DSA
src_libwolfssl_la_SOURCES += wolfcrypt/src/dsa.c
endif
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_AESNI
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_asm.S
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_gcm_asm.S
@@ -440,7 +562,7 @@ if BUILD_SLOWMATH
src_libwolfssl_la_SOURCES += wolfcrypt/src/integer.c
endif
if !BUILD_FIPS_V2
if !BUILD_FIPS_CURRENT
if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif

View File

@@ -4362,7 +4362,7 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
#endif
{
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2)) && \
!defined(HAVE_SELFTEST)
ret = wc_ecc_set_rng(priv_key, ssl->rng);
if (ret == 0)

View File

@@ -32,6 +32,7 @@
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>

View File

@@ -139,6 +139,18 @@
*/
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
#if (defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))) || \
defined(HAVE_SELFTEST)
enum {
/*
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE
*/
MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE
};
/* Extract data using HMAC, salt and input.
* RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
@@ -148,40 +160,35 @@
* saltLen The length of the salt.
* ikm The input keying material.
* ikmLen The length of the input keying material.
* mac The type of digest to use.
* digest The type of digest to use.
* returns 0 on success, otherwise failure.
*/
static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
byte* ikm, int ikmLen, int mac)
static int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
byte* ikm, int ikmLen, int digest)
{
int ret;
int hash = 0;
int len = 0;
switch (mac) {
switch (digest) {
#ifndef NO_SHA256
case sha256_mac:
hash = WC_SHA256;
case WC_SHA256:
len = WC_SHA256_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_SHA384
case sha384_mac:
hash = WC_SHA384;
case WC_SHA384:
len = WC_SHA384_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
hash = WC_SHA512;
case WC_SHA512:
len = WC_SHA512_DIGEST_SIZE;
break;
#endif
default:
break;
return BAD_FUNC_ARG;
}
/* When length is 0 then use zeroed data of digest length. */
@@ -197,7 +204,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
WOLFSSL_BUFFER(ikm, ikmLen);
#endif
ret = wc_HKDF_Extract(hash, salt, saltLen, ikm, ikmLen, prk);
ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG(" PRK");
@@ -207,6 +214,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
return ret;
}
/* Expand data using HMAC, salt and label and info.
* TLS v1.3 defines this function.
*
@@ -221,7 +229,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
* digest The type of digest to use.
* returns 0 on success, otherwise failure.
*/
static int HKDF_Expand_Label(byte* okm, word32 okmLen,
static int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
const byte* prk, word32 prkLen,
const byte* protocol, word32 protocolLen,
const byte* label, word32 labelLen,
@@ -230,7 +238,7 @@ static int HKDF_Expand_Label(byte* okm, word32 okmLen,
{
int ret = 0;
int idx = 0;
byte data[MAX_HKDF_LABEL_SZ];
byte data[MAX_TLS13_HKDF_LABEL_SZ];
/* Output length. */
data[idx++] = (byte)(okmLen >> 8);
@@ -270,6 +278,8 @@ static int HKDF_Expand_Label(byte* okm, word32 okmLen,
return ret;
}
#endif /* HAVE_FIPS */
/* Size of the TLS v1.3 label use when deriving keys. */
#define TLS13_PROTOCOL_LABEL_SZ 6
/* The protocol label for TLS v1.3. */
@@ -363,7 +373,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
if (outputLen == -1)
outputLen = hashSz;
return HKDF_Expand_Label(output, outputLen, secret, hashSz,
return wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
protocol, protocolLen, label, labelLen,
hash, hashSz, digestAlg);
}
@@ -435,11 +445,41 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
if (includeMsgs)
hashOutSz = hashSz;
return HKDF_Expand_Label(output, outputLen, secret, hashSz,
return wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
protocol, protocolLen, label, labelLen,
hash, hashOutSz, digestAlg);
}
/* Convert TLS mac ID to a hash algorithm ID
*
* mac Mac ID to convert
* returns hash ID on success, or the NONE type.
*/
static WC_INLINE int mac2hash(int mac)
{
int hash = WC_HASH_TYPE_NONE;
switch (mac) {
#ifndef NO_SHA256
case sha256_mac:
hash = WC_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case sha384_mac:
hash = WC_SHA384;
break;
#endif
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
hash = WC_SHA512;
break;
#endif
}
return hash;
}
#ifndef NO_PSK
/* The length of the binder key label. */
#define BINDER_KEY_LABEL_SZ 10
@@ -814,7 +854,7 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
}
/* Derive-Secret(Secret, label, "") */
ret = HKDF_Expand_Label(firstExpand, hashLen,
ret = wc_Tls13_HKDF_Expand_Label(firstExpand, hashLen,
ssl->arrays->exporterSecret, hashLen,
protocol, protocolLen, (byte*)label, (word32)labelLen,
emptyHash, hashLen, hashType);
@@ -826,7 +866,7 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
if (ret != 0)
return ret;
ret = HKDF_Expand_Label(out, (word32)outLen, firstExpand, hashLen,
ret = wc_Tls13_HKDF_Expand_Label(out, (word32)outLen, firstExpand, hashLen,
protocol, protocolLen, exporterLabel, EXPORTER_LABEL_SZ,
hashOut, hashLen, hashType);
@@ -915,12 +955,12 @@ int DeriveEarlySecret(WOLFSSL* ssl)
return BAD_FUNC_ARG;
}
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
return wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
ssl->arrays->psk_key, ssl->arrays->psk_keySz,
ssl->specs.mac_algorithm);
mac2hash(ssl->specs.mac_algorithm));
#else
return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
return wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm));
#endif
}
@@ -948,10 +988,10 @@ int DeriveHandshakeSecret(WOLFSSL* ssl)
if (ret != 0)
return ret;
return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
return wc_Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
key, ssl->specs.hash_size,
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
ssl->specs.mac_algorithm);
mac2hash(ssl->specs.mac_algorithm));
}
/* Derive the master secret using HKDF Extract.
@@ -972,9 +1012,9 @@ int DeriveMasterSecret(WOLFSSL* ssl)
if (ret != 0)
return ret;
ret = Tls13_HKDF_Extract(ssl->arrays->masterSecret,
ret = wc_Tls13_HKDF_Extract(ssl->arrays->masterSecret,
key, ssl->specs.hash_size,
ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm));
#ifdef HAVE_KEYING_MATERIAL
if (ret != 0)
@@ -1032,7 +1072,7 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret)
return BAD_FUNC_ARG;
}
return HKDF_Expand_Label(secret, ssl->specs.hash_size,
return wc_Tls13_HKDF_Expand_Label(secret, ssl->specs.hash_size,
ssl->session.masterSecret, ssl->specs.hash_size,
protocol, protocolLen, resumptionLabel,
RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);

View File

@@ -400,7 +400,8 @@ static const char* failed = "failed";
#define TEST_STRING "Everyone gets Friday off."
#define TEST_STRING_SZ 25
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
#define TEST_RSA_BITS 1024
#else
#define TEST_RSA_BITS 2048
@@ -14678,7 +14679,8 @@ static int test_wc_MakeRsaKey (void)
RsaKey genKey;
WC_RNG rng;
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
int bits = 1024;
#else
int bits = 2048;
@@ -15339,7 +15341,8 @@ static int test_wc_RsaKeyToDer (void)
RsaKey genKey;
WC_RNG rng;
byte* der;
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
int bits = 1024;
word32 derSz = 611;
/* (2 x 128) + 2 (possible leading 00) + (5 x 64) + 5 (possible leading 00)
@@ -15449,7 +15452,8 @@ static int test_wc_RsaKeyToPublicDer (void)
RsaKey key;
WC_RNG rng;
byte* der;
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
int bits = 1024;
word32 derLen = 162;
#else
@@ -15927,7 +15931,8 @@ static int test_wc_RsaEncryptSize (void)
}
printf(testingFmt, "wc_RsaEncryptSize()");
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
if (ret == 0) {
ret = MAKE_RSA_KEY(&key, 1024, WC_RSA_EXPONENT, &rng);
if (ret == 0) {
@@ -15997,7 +16002,8 @@ static int test_wc_RsaFlattenPublicKey (void)
byte n[256];
word32 eSz = sizeof(e);
word32 nSz = sizeof(n);
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
int bits = 1024;
#else
int bits = 2048;

View File

@@ -64,6 +64,9 @@ int unit_test(int argc, char** argv)
wolfSSL_Debugging_ON();
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#ifdef HAVE_WNR
if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0)
err_sys("Whitewood netRandom global config failed");

View File

@@ -127,6 +127,9 @@ int testsuite_test(int argc, char** argv)
#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND)
wolfSSL_Debugging_ON();
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#if !defined(WOLFSSL_TIRTOS)
ChangeToWolfRoot();

View File

@@ -2055,6 +2055,9 @@ int benchmark_init(void)
printf("wolfCrypt_Init failed %d\n", ret);
return EXIT_FAILURE;
}
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
bench_stats_init();

View File

@@ -31,8 +31,8 @@
#ifndef NO_DES3
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION == 2 || HAVE_FIPS_VERSION == 3)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS

View File

@@ -944,6 +944,7 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
#else
(void)devId;
#endif
key->trustedGroup = 0;
return ret;
}
@@ -973,6 +974,12 @@ int wc_FreeDhKey(DhKey* key)
}
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
const byte* prime, word32 primeSz, int partial);
static int _ffc_pairwise_consistency_test(DhKey* key,
const byte* pub, word32 pubSz, const byte* priv, word32 privSz);
#ifndef WC_NO_RNG
/* if defined to not use floating point values do not compile in */
#ifndef WOLFSSL_DH_CONST
@@ -1066,7 +1073,9 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
pSz = mp_unsigned_bin_size(&key->p);
/* verify (L,N) pair bit lengths */
if (CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
/* Trusted primes don't need to be checked. */
if (!key->trustedGroup &&
CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
return BAD_FUNC_ARG;
}
@@ -1325,7 +1334,16 @@ static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
ret = GeneratePrivateDh(key, rng, priv, privSz);
return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz);
if (ret == 0)
ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz);
if (ret == 0)
ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
if (ret == 0) {
ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz);
if (ret != 0) ret = DHE_PCT_FIPS_E;
}
return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
@@ -1388,20 +1406,132 @@ static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
/* Performs a Pairwise Consistency Test on an FFC key pair. */
static int _ffc_pairwise_consistency_test(DhKey* key,
const byte* pub, word32 pubSz, const byte* priv, word32 privSz)
{
#ifdef WOLFSSL_SMALL_STACK
mp_int* publicKey = NULL;
mp_int* privateKey = NULL;
mp_int* checkKey = NULL;
#else
mp_int publicKey[1];
mp_int privateKey[1];
mp_int checkKey[1];
#endif
int ret = 0;
if (key == NULL || pub == NULL || priv == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_SMALL_STACK
publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (publicKey == NULL)
return MEMORY_E;
privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (privateKey == NULL) {
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
return MEMORY_E;
}
checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (checkKey == NULL) {
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
return MEMORY_E;
}
#endif
if (mp_init_multi(publicKey, privateKey, checkKey,
NULL, NULL, NULL) != MP_OKAY) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
#endif
return MP_INIT_E;
}
/* Load the private and public keys into big integers. */
if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
ret = MP_READ_E;
}
/* Calculate checkKey = g^privateKey mod p */
if (ret == 0) {
#ifdef WOLFSSL_HAVE_SP_DH
#ifndef WOLFSSL_SP_NO_2048
if (mp_count_bits(&key->p) == 2048) {
ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifndef WOLFSSL_SP_NO_3072
if (mp_count_bits(&key->p) == 3072) {
ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifdef WOLFSSL_SP_4096
if (mp_count_bits(&key->p) == 4096) {
ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#endif
{
#if !defined(WOLFSSL_SP_MATH)
if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
ret = MP_EXPTMOD_E;
#else
ret = WC_KEY_SIZE_E;
#endif
}
}
/* Compare the calculated public key to the supplied check value. */
if (ret == 0) {
if (mp_cmp(checkKey, publicKey) != MP_EQ)
ret = MP_CMP_E;
}
mp_forcezero(privateKey);
mp_clear(publicKey);
mp_clear(checkKey);
#ifdef WOLFSSL_SMALL_STACK
XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
#endif
return ret;
}
/* Check DH Public Key for invalid numbers, optionally allowing
* the public key to be checked against the large prime (q).
* Check per process in SP 800-56Ar3, section 5.6.2.3.1.
* If q is NULL, the q value of key is used.
* Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2.
*
* key DH key group parameters.
* pub Public Key.
* pubSz Public Key size.
* prime Large prime (q), optionally NULL to skip check
* primeSz Size of large prime
* partial Do the partial test process. (section 5.6.2.3.2)
*
* returns 0 on success or error code
*/
int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
const byte* prime, word32 primeSz)
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
const byte* prime, word32 primeSz, int partial)
{
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
@@ -1458,7 +1588,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
ret = MP_INIT_E;
}
/* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */
/* SP 800-56Ar3, section 5.6.2.3.2 */
/* pub (y) should not be 0 or 1 */
if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
ret = MP_CMP_E;
@@ -1475,55 +1605,57 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
ret = MP_CMP_E;
}
if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
if (!partial) {
if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
/* restore key->p into p */
if (mp_copy(&key->p, p) != MP_OKAY)
ret = MP_INIT_E;
}
/* restore key->p into p */
if (mp_copy(&key->p, p) != MP_OKAY)
ret = MP_INIT_E;
}
/* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
if (ret == 0 && prime != NULL) {
/* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
if (ret == 0 && prime != NULL) {
#ifdef WOLFSSL_HAVE_SP_DH
#ifndef WOLFSSL_SP_NO_2048
if (mp_count_bits(&key->p) == 2048) {
ret = sp_ModExp_2048(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
if (mp_count_bits(&key->p) == 2048) {
ret = sp_ModExp_2048(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifndef WOLFSSL_SP_NO_3072
if (mp_count_bits(&key->p) == 3072) {
ret = sp_ModExp_3072(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
if (mp_count_bits(&key->p) == 3072) {
ret = sp_ModExp_3072(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifdef WOLFSSL_SP_4096
if (mp_count_bits(&key->p) == 4096) {
ret = sp_ModExp_4096(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
if (mp_count_bits(&key->p) == 4096) {
ret = sp_ModExp_4096(y, q, p, y);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#endif
{
{
#if !defined(WOLFSSL_SP_MATH)
/* calculate (y^q) mod(p), store back into y */
if (mp_exptmod(y, q, p, y) != MP_OKAY)
ret = MP_EXPTMOD_E;
/* calculate (y^q) mod(p), store back into y */
if (mp_exptmod(y, q, p, y) != MP_OKAY)
ret = MP_EXPTMOD_E;
#else
ret = WC_KEY_SIZE_E;
ret = WC_KEY_SIZE_E;
#endif
}
}
/* verify above == 1 */
if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
ret = MP_CMP_E;
/* verify above == 1 */
if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
ret = MP_CMP_E;
}
}
mp_clear(y);
@@ -1539,7 +1671,16 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
}
/* Check DH Public Key for invalid numbers
/* Performs a full public-key validation routine. */
int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
const byte* prime, word32 primeSz)
{
return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0);
}
/* Check DH Public Key for invalid numbers. Performs a partial public-key
* validation routine.
*
* key DH key group parameters.
* pub Public Key.
@@ -1549,7 +1690,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
*/
int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
{
return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0);
return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1);
}
@@ -1719,109 +1860,7 @@ int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
const byte* priv, word32 privSz)
{
#ifdef WOLFSSL_SMALL_STACK
mp_int* publicKey = NULL;
mp_int* privateKey = NULL;
mp_int* checkKey = NULL;
#else
mp_int publicKey[1];
mp_int privateKey[1];
mp_int checkKey[1];
#endif
int ret = 0;
if (key == NULL || pub == NULL || priv == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_SMALL_STACK
publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (publicKey == NULL)
return MEMORY_E;
privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (privateKey == NULL) {
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
return MEMORY_E;
}
checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
if (checkKey == NULL) {
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
return MEMORY_E;
}
#endif
if (mp_init_multi(publicKey, privateKey, checkKey,
NULL, NULL, NULL) != MP_OKAY) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
#endif
return MP_INIT_E;
}
/* Load the private and public keys into big integers. */
if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
ret = MP_READ_E;
}
/* Calculate checkKey = g^privateKey mod p */
if (ret == 0) {
#ifdef WOLFSSL_HAVE_SP_DH
#ifndef WOLFSSL_SP_NO_2048
if (mp_count_bits(&key->p) == 2048) {
ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifndef WOLFSSL_SP_NO_3072
if (mp_count_bits(&key->p) == 3072) {
ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#ifdef WOLFSSL_SP_4096
if (mp_count_bits(&key->p) == 4096) {
ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
else
#endif
#endif
{
#if !defined(WOLFSSL_SP_MATH)
if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
ret = MP_EXPTMOD_E;
#else
ret = WC_KEY_SIZE_E;
#endif
}
}
/* Compare the calculated public key to the supplied check value. */
if (ret == 0) {
if (mp_cmp(checkKey, publicKey) != MP_EQ)
ret = MP_CMP_E;
}
mp_forcezero(privateKey);
mp_clear(publicKey);
mp_clear(checkKey);
#ifdef WOLFSSL_SMALL_STACK
XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
#endif
return ret;
return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz);
}
@@ -1845,6 +1884,10 @@ int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
}
if (ret == 0) {
ret = wc_DhCheckKeyPair(key, pub, *pubSz, priv, *privSz);
}
return ret;
}
@@ -2293,6 +2336,8 @@ static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
if (ret == 0 && q != NULL) {
if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
ret = MP_INIT_E;
else
key->trustedGroup = trusted;
}
if (ret != 0 && key != NULL) {
@@ -2328,7 +2373,6 @@ int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
}
#ifdef WOLFSSL_KEY_GEN
/* modulus_size in bits */

View File

@@ -1207,6 +1207,11 @@ static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
mp_int* prime, mp_int* order);
#endif
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
static int _ecc_pairwise_consistency_test(ecc_key* key);
#endif
int mp_jacobi(mp_int* a, mp_int* n, int* c);
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
@@ -4699,6 +4704,16 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
#endif /* WOLFSSL_ATECC508A */
if (err == MP_OKAY) {
err = _ecc_validate_public_key(key, 0, 0);
}
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
if (err == MP_OKAY) {
err = _ecc_pairwise_consistency_test(key);
}
#endif
return err;
}
@@ -7616,6 +7631,20 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
return err;
}
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
/* Performs a Pairwise Consistency Test on an ECC key pair. */
static int _ecc_pairwise_consistency_test(ecc_key* key)
{
int err = 0;
if (ecc_check_privkey_gen_helper(key) != 0)
err = ECC_PCT_FIPS_E;
return err;
}
#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN */
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
@@ -7697,8 +7726,14 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
}
#endif /* OPENSSLALL */
/* perform sanity checks on ecc key validity, 0 on success */
int wc_ecc_check_key(ecc_key* key)
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
* ECC Full Public Key Validation Routine. If the parameter
* partial is set, then it follows section 5.6.2.3.4, the ECC
* Partial Public Key Validation Routine.
* If the parameter priv is set, add in a few extra
* checks on the bounds of the private key. */
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
{
#ifndef WOLFSSL_SP_MATH
int err;
@@ -7777,6 +7812,7 @@ int wc_ecc_check_key(ecc_key* key)
#endif
/* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
/* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
/* pubkey point cannot be at infinity */
if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
#ifdef WOLFSSL_SMALL_STACK
@@ -7806,6 +7842,7 @@ int wc_ecc_check_key(ecc_key* key)
#endif
/* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
/* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
/* Qx must be in the range [0, p-1] */
if (err == MP_OKAY) {
if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
@@ -7818,29 +7855,34 @@ int wc_ecc_check_key(ecc_key* key)
err = ECC_OUT_OF_RANGE_E;
}
/* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */
/* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
/* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
/* make sure point is actually on curve */
if (err == MP_OKAY)
err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
/* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */
/* pubkey * order must be at infinity */
if (err == MP_OKAY)
err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime,
curve->order);
/* SP 800-56Ar3, section 5.6.2.1.2 */
/* private keys must be in the range [1, n-1] */
if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
(mp_iszero(&key->k) || mp_isneg(&key->k) ||
(mp_cmp(&key->k, curve->order) != MP_LT))) {
err = ECC_PRIV_KEY_E;
if (!partial) {
/* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
/* pubkey * order must be at infinity */
if (err == MP_OKAY)
err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
curve->prime, curve->order);
}
/* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
/* private * base generator must equal pubkey */
if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
if (priv) {
/* SP 800-56Ar3, section 5.6.2.1.2 */
/* private keys must be in the range [1, n-1] */
if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
(mp_iszero(&key->k) || mp_isneg(&key->k) ||
(mp_cmp(&key->k, curve->order) != MP_LT))) {
err = ECC_PRIV_KEY_E;
}
/* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
/* private * base generator must equal pubkey */
if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
}
wc_ecc_curve_free(curve);
@@ -7855,10 +7897,20 @@ int wc_ecc_check_key(ecc_key* key)
#endif /* WOLFSSL_ATECC508A */
return err;
#else
(void)partial;
(void)priv;
return WC_KEY_SIZE_E;
#endif /* !WOLFSSL_SP_MATH */
}
/* perform sanity checks on ecc key validity, 0 on success */
int wc_ecc_check_key(ecc_key* key)
{
return _ecc_validate_public_key(key, 0, 1);
}
#ifdef HAVE_ECC_KEY_IMPORT
/* import public ECC key in ANSI X9.63 format */
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,

View File

@@ -527,6 +527,27 @@ const char* wc_GetErrorString(int error)
case MISSING_KEY:
return "Required key not set";
case ECDSA_KAT_FIPS_E:
return "wolfcrypt FIPS ECDSA Known Answer Test Failure";
case RSA_PAT_FIPS_E:
return "wolfcrypt FIPS RSA Pairwise Agreement Test Failure";
case KDF_TLS12_KAT_FIPS_E:
return "wolfcrypt FIPS TLSv1.2 KDF Known Answer Test Failure";
case KDF_TLS13_KAT_FIPS_E:
return "wolfcrypt FIPS TLSv1.3 KDF Known Answer Test Failure";
case KDF_SSH_KAT_FIPS_E:
return "wolfcrypt FIPS SSH KDF Known Answer Test Failure";
case DHE_PCT_FIPS_E:
return "wolfcrypt FIPS DHE Pairwise Consistency Test Failure";
case ECC_PCT_FIPS_E:
return "wolfcrypt FIPS ECDHE Pairwise Consistency Test Failure";
default:
return "unknown error number";

View File

@@ -1423,7 +1423,8 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags)
#endif /* !NO_HASH_WRAPPER */
#ifdef WOLFSSL_HAVE_PRF
#if defined(WOLFSSL_HAVE_PRF) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))
#ifdef WOLFSSL_SHA384
#define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE

View File

@@ -1178,6 +1178,289 @@ int wolfSSL_GetHmacMaxSize(void)
return WC_MAX_DIGEST_SIZE;
}
#if defined(WOLFSSL_HAVE_PRF) && defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4)
#ifdef WOLFSSL_SHA512
#define P_HASH_MAX_SIZE WC_SHA512_DIGEST_SIZE
#elif defined(WOLFSSL_SHA384)
#define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
#else
#define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE
#endif
/* Pseudo Random Function for MD5, SHA-1, SHA-256, SHA-384, or SHA-512 */
int wc_PRF(byte* result, word32 resLen, const byte* secret,
word32 secLen, const byte* seed, word32 seedLen, int hash,
void* heap, int devId)
{
word32 len = P_HASH_MAX_SIZE;
word32 times;
word32 lastLen;
word32 lastTime;
word32 i;
word32 idx = 0;
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
byte* previous;
byte* current;
Hmac* hmac;
#else
byte previous[P_HASH_MAX_SIZE]; /* max size */
byte current[P_HASH_MAX_SIZE]; /* max size */
Hmac hmac[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
if (previous == NULL || current == NULL || hmac == NULL) {
if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
if (current) XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
if (hmac) XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
return MEMORY_E;
}
#endif
switch (hash) {
#ifndef NO_MD5
case md5_mac:
hash = WC_MD5;
len = WC_MD5_DIGEST_SIZE;
break;
#endif
#ifndef NO_SHA256
case sha256_mac:
hash = WC_SHA256;
len = WC_SHA256_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_SHA384
case sha384_mac:
hash = WC_SHA384;
len = WC_SHA384_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_SHA512
case sha512_mac:
hash = WC_SHA512;
len = WC_SHA512_DIGEST_SIZE;
break;
#endif
#ifndef NO_SHA
case sha_mac:
default:
hash = WC_SHA;
len = WC_SHA_DIGEST_SIZE;
break;
#endif
}
times = resLen / len;
lastLen = resLen % len;
if (lastLen)
times += 1;
lastTime = times - 1;
ret = wc_HmacInit(hmac, heap, devId);
if (ret == 0) {
ret = wc_HmacSetKey(hmac, hash, secret, secLen);
if (ret == 0)
ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
if (ret == 0)
ret = wc_HmacFinal(hmac, previous); /* A1 */
if (ret == 0) {
for (i = 0; i < times; i++) {
ret = wc_HmacUpdate(hmac, previous, len);
if (ret != 0)
break;
ret = wc_HmacUpdate(hmac, seed, seedLen);
if (ret != 0)
break;
ret = wc_HmacFinal(hmac, current);
if (ret != 0)
break;
if ((i == lastTime) && lastLen)
XMEMCPY(&result[idx], current,
min(lastLen, P_HASH_MAX_SIZE));
else {
XMEMCPY(&result[idx], current, len);
idx += len;
ret = wc_HmacUpdate(hmac, previous, len);
if (ret != 0)
break;
ret = wc_HmacFinal(hmac, previous);
if (ret != 0)
break;
}
}
}
wc_HmacFree(hmac);
}
ForceZero(previous, P_HASH_MAX_SIZE);
ForceZero(current, P_HASH_MAX_SIZE);
ForceZero(hmac, sizeof(Hmac));
#ifdef WOLFSSL_SMALL_STACK
XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
#endif
return ret;
}
#undef P_HASH_MAX_SIZE
/* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */
int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
word32 secLen, const byte* label, word32 labLen,
const byte* seed, word32 seedLen, void* heap, int devId)
{
int ret = 0;
word32 half = (secLen + 1) / 2;
#ifdef WOLFSSL_SMALL_STACK
byte* md5_half;
byte* sha_half;
byte* md5_result;
byte* sha_result;
#else
byte md5_half[MAX_PRF_HALF]; /* half is real size */
byte sha_half[MAX_PRF_HALF]; /* half is real size */
byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
if (labelSeed == NULL)
return MEMORY_E;
#else
byte labelSeed[MAX_PRF_LABSEED];
#endif
if (half > MAX_PRF_HALF ||
labLen + seedLen > MAX_PRF_LABSEED ||
digLen > MAX_PRF_DIG)
{
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
FREE_VAR(labelSeed, heap);
#endif
return BUFFER_E;
}
#ifdef WOLFSSL_SMALL_STACK
md5_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST);
sha_half = (byte*)XMALLOC(MAX_PRF_HALF, heap, DYNAMIC_TYPE_DIGEST);
md5_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
if (md5_half == NULL || sha_half == NULL || md5_result == NULL ||
sha_result == NULL) {
if (md5_half) XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST);
if (sha_half) XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST);
if (md5_result) XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
if (sha_result) XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
FREE_VAR(labelSeed, heap);
#endif
return MEMORY_E;
}
#endif
XMEMSET(md5_result, 0, digLen);
XMEMSET(sha_result, 0, digLen);
XMEMCPY(md5_half, secret, half);
XMEMCPY(sha_half, secret + half - secLen % 2, half);
XMEMCPY(labelSeed, label, labLen);
XMEMCPY(labelSeed + labLen, seed, seedLen);
if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
labLen + seedLen, md5_mac, heap, devId)) == 0) {
if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
labLen + seedLen, sha_mac, heap, devId)) == 0) {
/* calculate XOR for TLSv1 PRF */
XMEMCPY(digest, md5_result, digLen);
xorbuf(digest, sha_result, digLen);
}
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(md5_half, heap, DYNAMIC_TYPE_DIGEST);
XFREE(sha_half, heap, DYNAMIC_TYPE_DIGEST);
XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
FREE_VAR(labelSeed, heap);
#endif
return ret;
}
/* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */
/* In TLS 1.2 case call straight thru to wc_PRF */
int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
const byte* label, word32 labLen, const byte* seed, word32 seedLen,
int useAtLeastSha256, int hash_type, void* heap, int devId)
{
int ret = 0;
if (useAtLeastSha256) {
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
if (labelSeed == NULL)
return MEMORY_E;
#else
byte labelSeed[MAX_PRF_LABSEED];
#endif
if (labLen + seedLen > MAX_PRF_LABSEED)
return BUFFER_E;
XMEMCPY(labelSeed, label, labLen);
XMEMCPY(labelSeed + labLen, seed, seedLen);
/* If a cipher suite wants an algorithm better than sha256, it
* should use better. */
if (hash_type < sha256_mac || hash_type == blake2b_mac)
hash_type = sha256_mac;
/* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
labLen + seedLen, hash_type, heap, devId);
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
FREE_VAR(labelSeed, heap);
#endif
}
#ifndef NO_OLD_TLS
else {
/* compute TLSv1 PRF (pseudo random function using HMAC) */
ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,
seedLen, heap, devId);
}
#endif
return ret;
}
#endif /* WOLFSSL_HAVE_PRF */
#ifdef HAVE_HKDF
/* HMAC-KDF-Extract.
* RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
@@ -1320,7 +1603,378 @@ int wolfSSL_GetHmacMaxSize(void)
return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
}
#if !defined(HAVE_FIPS) || \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4)
/* Extract data using HMAC, salt and input.
* RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
*
* prk The generated pseudorandom key.
* salt The salt.
* saltLen The length of the salt.
* ikm The input keying material.
* ikmLen The length of the input keying material.
* digest The type of digest to use.
* returns 0 on success, otherwise failure.
*/
int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
byte* ikm, int ikmLen, int digest)
{
int ret;
int len = 0;
switch (digest) {
#ifndef NO_SHA256
case WC_SHA256:
len = WC_SHA256_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_SHA384
case WC_SHA384:
len = WC_SHA384_DIGEST_SIZE;
break;
#endif
#ifdef WOLFSSL_TLS13_SHA512
case WC_SHA512:
len = WC_SHA512_DIGEST_SIZE;
break;
#endif
default:
return BAD_FUNC_ARG;
}
/* When length is 0 then use zeroed data of digest length. */
if (ikmLen == 0) {
ikmLen = len;
XMEMSET(ikm, 0, len);
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG(" Salt");
WOLFSSL_BUFFER(salt, saltLen);
WOLFSSL_MSG(" IKM");
WOLFSSL_BUFFER(ikm, ikmLen);
#endif
ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG(" PRK");
WOLFSSL_BUFFER(prk, len);
#endif
return ret;
}
/* Expand data using HMAC, salt and label and info.
* TLS v1.3 defines this function.
*
* okm The generated pseudorandom key - output key material.
* okmLen The length of generated pseudorandom key -
* output key material.
* prk The salt - pseudo-random key.
* prkLen The length of the salt - pseudo-random key.
* protocol The TLS protocol label.
* protocolLen The length of the TLS protocol label.
* info The information to expand.
* infoLen The length of the information.
* digest The type of digest to use.
* returns 0 on success, otherwise failure.
*/
int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
const byte* prk, word32 prkLen,
const byte* protocol, word32 protocolLen,
const byte* label, word32 labelLen,
const byte* info, word32 infoLen,
int digest)
{
int ret = 0;
int idx = 0;
byte data[MAX_TLS13_HKDF_LABEL_SZ];
/* Output length. */
data[idx++] = (byte)(okmLen >> 8);
data[idx++] = (byte)okmLen;
/* Length of protocol | label. */
data[idx++] = (byte)(protocolLen + labelLen);
/* Protocol */
XMEMCPY(&data[idx], protocol, protocolLen);
idx += protocolLen;
/* Label */
XMEMCPY(&data[idx], label, labelLen);
idx += labelLen;
/* Length of hash of messages */
data[idx++] = (byte)infoLen;
/* Hash of messages */
XMEMCPY(&data[idx], info, infoLen);
idx += infoLen;
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG(" PRK");
WOLFSSL_BUFFER(prk, prkLen);
WOLFSSL_MSG(" Info");
WOLFSSL_BUFFER(data, idx);
#endif
ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG(" OKM");
WOLFSSL_BUFFER(okm, okmLen);
#endif
ForceZero(data, idx);
return ret;
}
#endif /* newer HAVE_FIPS */
#endif /* HAVE_HKDF */
#ifdef WOLFSSL_WOLFSSH
static
int _HashInit(byte hashId, wc_Hmac_Hash* hash)
{
int ret = BAD_FUNC_ARG;
switch (hashId) {
#ifndef NO_SHA
case WC_SHA:
ret = wc_InitSha(&hash->sha);
break;
#endif /* !NO_SHA */
#ifndef NO_SHA256
case WC_SHA256:
ret = wc_InitSha256(&hash->sha256);
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case WC_SHA384:
ret = wc_InitSha384(&hash->sha384);
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
case WC_SHA512:
ret = wc_InitSha512(&hash->sha512);
break;
#endif /* WOLFSSL_SHA512 */
}
return ret;
}
static
int _HashUpdate(byte hashId, wc_Hmac_Hash* hash,
const byte* data, word32 dataSz)
{
int ret = BAD_FUNC_ARG;
switch (hashId) {
#ifndef NO_SHA
case WC_SHA:
ret = wc_ShaUpdate(&hash->sha, data, dataSz);
break;
#endif /* !NO_SHA */
#ifndef NO_SHA256
case WC_SHA256:
ret = wc_Sha256Update(&hash->sha256, data, dataSz);
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case WC_SHA384:
ret = wc_Sha384Update(&hash->sha384, data, dataSz);
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
case WC_SHA512:
ret = wc_Sha512Update(&hash->sha512, data, dataSz);
break;
#endif /* WOLFSSL_SHA512 */
}
return ret;
}
static
int _HashFinal(byte hashId, wc_Hmac_Hash* hash, byte* digest)
{
int ret = BAD_FUNC_ARG;
switch (hashId) {
#ifndef NO_SHA
case WC_SHA:
ret = wc_ShaFinal(&hash->sha, digest);
break;
#endif /* !NO_SHA */
#ifndef NO_SHA256
case WC_SHA256:
ret = wc_Sha256Final(&hash->sha256, digest);
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case WC_SHA384:
ret = wc_Sha384Final(&hash->sha384, digest);
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
case WC_SHA512:
ret = wc_Sha512Final(&hash->sha512, digest);
break;
#endif /* WOLFSSL_SHA512 */
}
return ret;
}
static
void _HashFree(byte hashId, wc_Hmac_Hash* hash)
{
switch (hashId) {
#ifndef NO_SHA
case WC_SHA:
wc_ShaFree(&hash->sha);
break;
#endif /* !NO_SHA */
#ifndef NO_SHA256
case WC_SHA256:
wc_Sha256Free(&hash->sha256);
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case WC_SHA384:
wc_Sha384Free(&hash->sha384);
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
case WC_SHA512:
wc_Sha512Free(&hash->sha512);
break;
#endif /* WOLFSSL_SHA512 */
}
}
#define LENGTH_SZ 4
int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
const byte* k, word32 kSz, const byte* h, word32 hSz,
const byte* sessionId, word32 sessionIdSz)
{
word32 blocks, remainder;
wc_Hmac_Hash hash;
enum wc_HashType enmhashId = (enum wc_HashType)hashId;
byte kPad = 0;
byte pad = 0;
byte kSzFlat[LENGTH_SZ];
int digestSz;
int ret;
if (key == NULL || keySz == 0 ||
k == NULL || kSz == 0 ||
h == NULL || hSz == 0 ||
sessionId == NULL || sessionIdSz == 0) {
return BAD_FUNC_ARG;
}
digestSz = wc_HmacSizeByType(enmhashId);
if (digestSz < 0) {
return BAD_FUNC_ARG;
}
if (k[0] & 0x80) kPad = 1;
c32toa(kSz + kPad, kSzFlat);
blocks = keySz / digestSz;
remainder = keySz % digestSz;
ret = _HashInit(enmhashId, &hash);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
if (ret == 0 && kPad)
ret = _HashUpdate(enmhashId, &hash, &pad, 1);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, k, kSz);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, h, hSz);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
if (ret == 0) {
if (blocks == 0) {
if (remainder > 0) {
byte lastBlock[WC_MAX_DIGEST_SIZE];
ret = _HashFinal(enmhashId, &hash, lastBlock);
if (ret == 0)
XMEMCPY(key, lastBlock, remainder);
}
}
else {
word32 runningKeySz, curBlock;
runningKeySz = digestSz;
ret = _HashFinal(enmhashId, &hash, key);
for (curBlock = 1; curBlock < blocks; curBlock++) {
ret = _HashInit(enmhashId, &hash);
if (ret != 0) break;
ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
if (ret != 0) break;
if (kPad)
ret = _HashUpdate(enmhashId, &hash, &pad, 1);
if (ret != 0) break;
ret = _HashUpdate(enmhashId, &hash, k, kSz);
if (ret != 0) break;
ret = _HashUpdate(enmhashId, &hash, h, hSz);
if (ret != 0) break;
ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
if (ret != 0) break;
ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
if (ret != 0) break;
runningKeySz += digestSz;
}
if (remainder > 0) {
byte lastBlock[WC_MAX_DIGEST_SIZE];
if (ret == 0)
ret = _HashInit(enmhashId, &hash);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
if (ret == 0 && kPad)
ret = _HashUpdate(enmhashId, &hash, &pad, 1);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, k, kSz);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, h, hSz);
if (ret == 0)
ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
if (ret == 0)
ret = _HashFinal(enmhashId, &hash, lastBlock);
if (ret == 0)
XMEMCPY(key + runningKeySz, lastBlock, remainder);
}
}
}
_HashFree(enmhashId, &hash);
return ret;
}
#endif /* WOLFSSL_WOLFSSH */
#endif /* HAVE_FIPS */
#endif /* NO_HMAC */

View File

@@ -286,11 +286,25 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
#define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)
#ifdef WC_RNG_SEED_CB
static wc_RngSeed_Cb seedCb = NULL;
int wc_SetSeed_Cb(wc_RngSeed_Cb cb)
{
seedCb = cb;
return 0;
}
#endif
/* Internal return codes */
#define DRBG_SUCCESS 0
#define DRBG_FAILURE 1
#define DRBG_NEED_RESEED 2
#define DRBG_CONT_FAILURE 3
#define DRBG_NO_SEED_CB 4
/* RNG health states */
#define DRBG_NOT_INIT 0
@@ -805,7 +819,19 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
rng->drbg = (struct DRBG*)&rng->drbg_data;
#endif
if (ret == 0) {
#ifdef WC_RNG_SEED_CB
if (seedCb == NULL) {
ret = DRBG_NO_SEED_CB;
}
else {
ret = seedCb(&rng->seed, seed, seedSz);
if (ret != 0) {
ret = DRBG_FAILURE;
}
}
#else
ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
#endif
if (ret == 0)
ret = wc_RNG_TestSeed(seed, seedSz);
else {
@@ -813,10 +839,11 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
rng->status = DRBG_FAILED;
}
if (ret == DRBG_SUCCESS)
ret = Hash_DRBG_Instantiate((DRBG_internal *)rng->drbg,
seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
nonce, nonceSz, rng->heap, devId);
if (ret == DRBG_SUCCESS) {
ret = Hash_DRBG_Instantiate((DRBG_internal *)rng->drbg,
seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
nonce, nonceSz, rng->heap, devId);
}
if (ret != DRBG_SUCCESS) {
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)

View File

@@ -600,7 +600,6 @@ int wc_FreeRsaKey(RsaKey* key)
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK)
/* Check the pair-wise consistency of the RSA key.
* From NIST SP 800-56B, section 6.4.1.1.
* Verify that k = (k^e)^d, for some k: 1 < k < n-1. */
int wc_CheckRsaKey(RsaKey* key)
{

View File

@@ -392,6 +392,7 @@ WOLFSSL_TEST_SUBROUTINE int hmac_sha384_test(void);
WOLFSSL_TEST_SUBROUTINE int hmac_sha512_test(void);
WOLFSSL_TEST_SUBROUTINE int hmac_sha3_test(void);
/* WOLFSSL_TEST_SUBROUTINE */ static int hkdf_test(void);
WOLFSSL_TEST_SUBROUTINE int sshkdf_test(void);
WOLFSSL_TEST_SUBROUTINE int x963kdf_test(void);
WOLFSSL_TEST_SUBROUTINE int arc4_test(void);
WOLFSSL_TEST_SUBROUTINE int rc2_test(void);
@@ -965,6 +966,13 @@ initDefaultName();
#endif
#endif /* !NO_HMAC */
#ifdef WOLFSSL_WOLFSSH
if ( (ret = sshkdf_test()) != 0)
return err_sys("SSH-KDF test failed!\n", ret);
else
test_pass("SSH-KDF test passed!\n");
#endif /* WOLFSSL_WOLFSSH */
#if defined(HAVE_X963_KDF) && defined(HAVE_ECC)
if ( (ret = x963kdf_test()) != 0)
return err_sys("X963-KDF test failed!\n", ret);
@@ -1475,6 +1483,10 @@ initDefaultName();
err_sys("Error with wolfCrypt_Init!\n", -1003);
}
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#ifdef HAVE_STACK_SIZE
StackSizeCheck(&args, wolfcrypt_test);
#else
@@ -11535,6 +11547,77 @@ static int random_rng_test(void)
#if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK)
#ifdef WC_RNG_SEED_CB
static int seed_cb(OS_Seed* os, byte* output, word32 sz)
{
word32 i;
(void)os;
/* Known answer test. Set the seed to the same value every time. */
for (i = 0; i < sz; i++)
output[i] = (byte)i;
return 0;
}
static int rng_seed_test(void)
{
#ifndef HAVE_FIPS
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
0x83, 0x46, 0x65, 0x2f, 0x5c, 0x44, 0x16, 0x5f,
0xb3, 0x89, 0x26, 0xde, 0x0b, 0x6b, 0xa2, 0x06,
0x7e, 0xa7, 0x9a, 0x55, 0x22, 0x01, 0xb0, 0x22,
0xf4, 0x7e, 0xa2, 0x66, 0xc4, 0x08, 0x6f, 0xba
};
#else
/* FIPS uses a longer seed, so different check value. */
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
0xaf, 0x31, 0xcc, 0xef, 0xa9, 0x29, 0x4c, 0x24,
0xbd, 0xa5, 0xa3, 0x52, 0x69, 0xf3, 0xb9, 0xb2,
0x1e, 0xd4, 0x52, 0x3b, 0x9a, 0x96, 0x06, 0x20,
0xc0, 0x5f, 0x44, 0x06, 0x1f, 0x80, 0xdf, 0xe0
};
#endif
byte output[WC_SHA256_DIGEST_SIZE];
WC_RNG rng;
int ret;
ret = wc_SetSeed_Cb(seed_cb);
if (ret != 0) {
ret = -7007;
goto exit;
}
ret = wc_InitRng(&rng);
if (ret != 0) {
ret = -7008;
goto exit;
}
ret = wc_RNG_GenerateBlock(&rng, output, sizeof(output));
if (ret != 0) {
ret = -7009;
goto exit;
}
ret = XMEMCMP(output, check, sizeof(output));
if (ret != 0) {
ret = -7010;
goto exit;
}
ret = wc_FreeRng(&rng);
if (ret != 0) {
ret = -7011;
goto exit;
}
ret = wc_SetSeed_Cb(wc_GenerateSeed);
if (ret != 0) {
ret = -7012;
}
exit:
return ret;
}
#endif
WOLFSSL_TEST_SUBROUTINE int random_test(void)
{
WOLFSSL_SMALL_STACK_STATIC const byte test1Entropy[] =
@@ -11640,6 +11723,13 @@ WOLFSSL_TEST_SUBROUTINE int random_test(void)
return -7006;
}
#endif
/* Test the seed callback. */
#ifdef WC_RNG_SEED_CB
if ((ret = rng_seed_test()) != 0)
return ret;
#endif
return 0;
}
@@ -16051,7 +16141,7 @@ static int dh_generate_test(WC_RNG *rng)
{
int ret = 0;
DhKey smallKey;
byte p[2] = { 0, 5 };
byte p[2] = { 1, 7 }; /* 263 in decimal */
byte g[2] = { 0, 2 };
#if !defined(WOLFSSL_SP_MATH)
#ifdef WOLFSSL_DH_CONST
@@ -20075,6 +20165,167 @@ WOLFSSL_TEST_SUBROUTINE int pwdbased_test(void)
#endif /* HAVE_HKDF */
#ifdef WOLFSSL_WOLFSSH
typedef struct {
byte hashId;
byte keyId;
const byte* k;
word32 kSz;
const byte* h;
word32 hSz;
const byte* sessionId;
word32 sessionIdSz;
const byte* expectedKey;
word32 expectedKeySz;
} SshKdfTestVector;
/** Test Vector Set #3: SHA-256 **/
const byte sshKdfTvSet3k[] = {
0x6A, 0xC3, 0x82, 0xEA, 0xAC, 0xA0, 0x93, 0xE1,
0x25, 0xE2, 0x5C, 0x24, 0xBE, 0xBC, 0x84, 0x64,
0x0C, 0x11, 0x98, 0x75, 0x07, 0x34, 0x4B, 0x5C,
0x73, 0x9C, 0xEB, 0x84, 0xA9, 0xE0, 0xB2, 0x22,
0xB9, 0xA8, 0xB5, 0x1C, 0x83, 0x9E, 0x5E, 0xBE,
0x49, 0xCF, 0xAD, 0xBF, 0xB3, 0x95, 0x99, 0x76,
0x4E, 0xD5, 0x22, 0x09, 0x9D, 0xC9, 0x12, 0x75,
0x19, 0x50, 0xDC, 0x7D, 0xC9, 0x7F, 0xBD, 0xC0,
0x63, 0x28, 0xB6, 0x8F, 0x22, 0x78, 0x1F, 0xD3,
0x15, 0xAF, 0x56, 0x80, 0x09, 0xA5, 0x50, 0x9E,
0x5B, 0x87, 0xA1, 0x1B, 0xF5, 0x27, 0xC0, 0x56,
0xDA, 0xFF, 0xD8, 0x2A, 0xB6, 0xCB, 0xC2, 0x5C,
0xCA, 0x37, 0x14, 0x34, 0x59, 0xE7, 0xBC, 0x63,
0xBC, 0xDE, 0x52, 0x75, 0x7A, 0xDE, 0xB7, 0xDF,
0x01, 0xCF, 0x12, 0x17, 0x3F, 0x1F, 0xEF, 0x81,
0x02, 0xEC, 0x5A, 0xB1, 0x42, 0xC2, 0x13, 0xDD,
0x9D, 0x30, 0x69, 0x62, 0x78, 0xA8, 0xD8, 0xBC,
0x32, 0xDD, 0xE9, 0x59, 0x2D, 0x28, 0xC0, 0x78,
0xC6, 0xD9, 0x2B, 0x94, 0x7D, 0x82, 0x5A, 0xCA,
0xAB, 0x64, 0x94, 0x84, 0x6A, 0x49, 0xDE, 0x24,
0xB9, 0x62, 0x3F, 0x48, 0x89, 0xE8, 0xAD, 0xC3,
0x8E, 0x8C, 0x66, 0x9E, 0xFF, 0xEF, 0x17, 0x60,
0x40, 0xAD, 0x94, 0x5E, 0x90, 0xA7, 0xD3, 0xEE,
0xC1, 0x5E, 0xFE, 0xEE, 0x78, 0xAE, 0x71, 0x04,
0x3C, 0x96, 0x51, 0x11, 0x03, 0xA1, 0x6B, 0xA7,
0xCA, 0xF0, 0xAC, 0xD0, 0x64, 0x2E, 0xFD, 0xBE,
0x80, 0x99, 0x34, 0xFA, 0xA1, 0xA5, 0xF1, 0xBD,
0x11, 0x04, 0x36, 0x49, 0xB2, 0x5C, 0xCD, 0x1F,
0xEE, 0x2E, 0x38, 0x81, 0x5D, 0x4D, 0x5F, 0x5F,
0xC6, 0xB4, 0x10, 0x29, 0x69, 0xF2, 0x1C, 0x22,
0xAE, 0x1B, 0x0E, 0x7D, 0x36, 0x03, 0xA5, 0x56,
0xA1, 0x32, 0x62, 0xFF, 0x62, 0x8D, 0xE2, 0x22
};
const byte sshKdfTvSet3h[] = {
0x7B, 0x70, 0x01, 0x18, 0x5E, 0x25, 0x6D, 0x44,
0x93, 0x44, 0x5F, 0x39, 0xA5, 0x5F, 0xB9, 0x05,
0xE6, 0x32, 0x1F, 0x4B, 0x5D, 0xD8, 0xBB, 0xF3,
0x10, 0x0D, 0x51, 0xBA, 0x0B, 0xDA, 0x3D, 0x2D
};
const byte sshKdfTvSet3sid[] = {
0x7B, 0x70, 0x01, 0x18, 0x5E, 0x25, 0x6D, 0x44,
0x93, 0x44, 0x5F, 0x39, 0xA5, 0x5F, 0xB9, 0x05,
0xE6, 0x32, 0x1F, 0x4B, 0x5D, 0xD8, 0xBB, 0xF3,
0x10, 0x0D, 0x51, 0xBA, 0x0B, 0xDA, 0x3D, 0x2D
};
const byte sshKdfTvSet3a[] = {
0x81, 0xF0, 0x33, 0x0E, 0xF6, 0xF0, 0x53, 0x61,
0xB3, 0x82, 0x3B, 0xFD, 0xED, 0x6E, 0x1D, 0xE9
};
const byte sshKdfTvSet3b[] = {
0x3F, 0x6F, 0xD2, 0x06, 0x5E, 0xEB, 0x2B, 0x0B,
0x1D, 0x93, 0x19, 0x5A, 0x1F, 0xED, 0x48, 0xA5
};
const byte sshKdfTvSet3c[] = {
0xC3, 0x54, 0x71, 0x03, 0x4E, 0x6F, 0xD6, 0x54,
0x76, 0x13, 0x17, 0x8E, 0x23, 0x43, 0x5F, 0x21
};
const byte sshKdfTvSet3d[] = {
0x7E, 0x9D, 0x79, 0x03, 0x20, 0x90, 0xD9, 0x9F,
0x98, 0xB0, 0x15, 0x63, 0x4D, 0xD9, 0xF4, 0x62
};
const byte sshKdfTvSet3e[] = {
0x24, 0xEE, 0x55, 0x9A, 0xD7, 0xCE, 0x71, 0x2B,
0x68, 0x5D, 0x0B, 0x22, 0x71, 0xE4, 0x43, 0xC1,
0x7A, 0xB1, 0xD1, 0xDC, 0xEB, 0x5A, 0x36, 0x05,
0x69, 0xD2, 0x5D, 0x5D, 0xC2, 0x43, 0x00, 0x2F
};
const byte sshKdfTvSet3f[] = {
0xC3, 0x41, 0x9C, 0x2B, 0x96, 0x62, 0x35, 0x86,
0x9D, 0x71, 0x4B, 0xA5, 0xAC, 0x48, 0xDD, 0xB7,
0xD9, 0xE3, 0x5C, 0x8C, 0x19, 0xAA, 0xC7, 0x34,
0x22, 0x33, 0x7A, 0x37, 0x34, 0x53, 0x60, 0x7E
};
static const SshKdfTestVector sshKdfTestVectors[] = {
{WC_HASH_TYPE_SHA256, 'A',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3a, sizeof(sshKdfTvSet3a)},
{WC_HASH_TYPE_SHA256, 'B',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3b, sizeof(sshKdfTvSet3b)},
{WC_HASH_TYPE_SHA256, 'C',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3c, sizeof(sshKdfTvSet3c)},
{WC_HASH_TYPE_SHA256, 'D',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3d, sizeof(sshKdfTvSet3d)},
{WC_HASH_TYPE_SHA256, 'E',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3e, sizeof(sshKdfTvSet3e)},
{WC_HASH_TYPE_SHA256, 'F',
sshKdfTvSet3k, sizeof(sshKdfTvSet3k),
sshKdfTvSet3h, sizeof(sshKdfTvSet3h),
sshKdfTvSet3sid, sizeof(sshKdfTvSet3sid),
sshKdfTvSet3f, sizeof(sshKdfTvSet3f)},
};
int sshkdf_test(void)
{
int result = 0;
word32 i;
word32 tc = sizeof(sshKdfTestVectors)/sizeof(SshKdfTestVector);
const SshKdfTestVector* tv = NULL;
byte cKey[32]; /* Greater of SHA256_DIGEST_SIZE and AES_BLOCK_SIZE */
/* sId - Session ID, eKey - Expected Key, cKey - Calculated Key */
for (i = 0, tv = sshKdfTestVectors; i < tc; i++, tv++) {
result = wc_SSH_KDF(tv->hashId, tv->keyId,
cKey, tv->expectedKeySz,
tv->k, tv->kSz, tv->h, tv->hSz,
tv->sessionId, tv->sessionIdSz);
if (result != 0) {
printf("KDF: Could not derive key.\n");
result = -101;
}
else {
if (memcmp(cKey, tv->expectedKey, tv->expectedKeySz) != 0) {
printf("KDF: Calculated Key does not match Expected Key.\n");
result = -102;
}
}
if (result != 0) break;
}
return result;
}
#endif /* WOLFSSL_WOLFSSH */
#if defined(HAVE_ECC) && defined(HAVE_X963_KDF)
WOLFSSL_TEST_SUBROUTINE int x963kdf_test(void)

View File

@@ -1362,9 +1362,6 @@ enum Misc {
KEY_LABEL_SZ = 13, /* TLS key block expansion sz */
PROTOCOL_LABEL_SZ = 9, /* Length of the protocol label */
MAX_LABEL_SZ = 34, /* Maximum length of a label */
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE,
MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */
SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */
TLS_MAX_PAD_SZ = 255, /* Max padding in TLS */

View File

@@ -131,7 +131,7 @@ enum {
KEYWRAP_BLOCK_SIZE = 8,
GCM_NONCE_MAX_SZ = 16, /* wolfCrypt's maximum nonce size allowed. */
GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */
GCM_NONCE_MID_SZ = 12, /* The default nonce size for AES-GCM. */
GCM_NONCE_MIN_SZ = 8, /* wolfCrypt's minimum nonce size allowed. */
CCM_NONCE_MIN_SZ = 7,
CCM_NONCE_MAX_SZ = 13,

View File

@@ -56,6 +56,10 @@ This library defines the interface APIs for X509 certificates.
#endif
#ifndef WC_RNG_TYPE_DEFINED
typedef struct WC_RNG WC_RNG;
#ifdef WC_RNG_SEED_CB
typedef struct OS_Seed OS_Seed;
typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz);
#endif
#define WC_RNG_TYPE_DEFINED
#endif

View File

@@ -30,15 +30,15 @@
#ifndef NO_DES3
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION == 2 || HAVE_FIPS_VERSION == 3)
#include <wolfssl/wolfcrypt/fips.h>
#endif /* HAVE_FIPS_VERSION >= 2 */
#if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
/* included for fips @wc_fips */
#include <cyassl/ctaocrypt/des3.h>
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
/* included for fips @wc_fips */
#include <cyassl/ctaocrypt/des3.h>
#endif
#ifdef __cplusplus
@@ -54,8 +54,8 @@ enum {
/* avoid redefinition of structs */
#if !defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION == 2 || HAVE_FIPS_VERSION == 3))
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
@@ -117,7 +117,7 @@ struct Des3 {
typedef struct Des3 Des3;
#define WC_DES3_TYPE_DEFINED
#endif
#endif /* HAVE_FIPS */
#endif /* HAVE_FIPS && HAVE_FIPS_VERSION >= 2 */
WOLFSSL_API int wc_Des_SetKey(Des* des, const byte* key,

View File

@@ -75,6 +75,7 @@ struct DhKey {
#ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev;
#endif
int trustedGroup;
};
#ifndef WC_DH_TYPE_DEFINED

View File

@@ -237,8 +237,15 @@ enum {
SAKKE_VERIFY_FAIL_E = -276, /* SAKKE derivation verification error */
MISSING_IV = -277, /* IV was not set */
MISSING_KEY = -278, /* Key was not set */
ECDSA_KAT_FIPS_E = -279, /* ECDSA KAT failure */
RSA_PAT_FIPS_E = -280, /* RSA Pairwise failure */
KDF_TLS12_KAT_FIPS_E = -281, /* TLS12 KDF KAT failure */
KDF_TLS13_KAT_FIPS_E = -282, /* TLS13 KDF KAT failure */
KDF_SSH_KAT_FIPS_E = -283, /* SSH KDF KAT failure */
DHE_PCT_FIPS_E = -284, /* DHE Pairwise Consistency Test failure */
ECC_PCT_FIPS_E = -285, /* ECDHE Pairwise Consistency Test failure */
WC_LAST_E = -278, /* Update this to indicate last error */
WC_LAST_E = -285, /* Update this to indicate last error */
MIN_CODE_E = -300 /* errors -101 - -299 */
/* add new companion error id strings for any new error codes

View File

@@ -31,8 +31,41 @@
extern "C" {
#endif
/* Known Answer Test string inputs are hex, internal */
WOLFSSL_LOCAL int DoKnownAnswerTests(char*, int);
enum FipsCastId {
FIPS_CAST_AES_CBC,
FIPS_CAST_AES_GCM,
FIPS_CAST_HMAC_SHA1,
FIPS_CAST_HMAC_SHA2_256,
FIPS_CAST_HMAC_SHA2_512,
FIPS_CAST_HMAC_SHA3_256,
FIPS_CAST_DRBG,
FIPS_CAST_RSA_SIGN_PKCS1v15,
FIPS_CAST_RSA_PAIRWISE,
FIPS_CAST_ECC_CDH,
FIPS_CAST_ECC_PRIMITIVE_Z,
FIPS_CAST_DH_PRIMITIVE_Z,
FIPS_CAST_ECDSA,
FIPS_CAST_ECDSA_PAIRWISE,
FIPS_CAST_ECDSA_SHA3_PAIRWISE,
FIPS_CAST_KDF_TLS12,
FIPS_CAST_KDF_TLS13,
FIPS_CAST_KDF_SSH,
FIPS_CAST_COUNT
};
enum FipsCastStateId {
FIPS_CAST_STATE_INIT,
FIPS_CAST_STATE_PROCESSING,
FIPS_CAST_STATE_SUCCESS,
FIPS_CAST_STATE_FAILURE
};
enum FipsModeId {
FIPS_MODE_INIT,
FIPS_MODE_NORMAL,
FIPS_MODE_DEGRADED,
FIPS_MODE_FAILED
};
/* FIPS failure callback */
@@ -50,6 +83,13 @@ WOLFSSL_API const char* wolfCrypt_GetCoreHash_fips(void);
WOLFSSL_API int wolfCrypt_SetStatus_fips(int);
#endif
WOLFSSL_LOCAL int DoIntegrityTest(char*, int);
WOLFSSL_LOCAL int DoPOST(char*, int);
WOLFSSL_LOCAL int DoCAST(int);
WOLFSSL_LOCAL int DoKnownAnswerTests(char*, int); /* FIPSv1 and FIPSv2 */
WOLFSSL_API int wc_RunCast_fips(int);
WOLFSSL_API int wc_GetCastStatus_fips(int);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -220,6 +220,10 @@ WOLFSSL_API int wc_Shake256Hash(const byte*, word32, byte*, word32);
#endif /* !NO_HASH_WRAPPER */
#if (defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))) || \
defined(HAVE_SELFTEST)
enum max_prf {
#ifdef HAVE_FFDHE_8192
MAX_PRF_HALF = 516, /* Maximum half secret len */
@@ -231,8 +235,11 @@ enum max_prf {
MAX_PRF_LABSEED = 128, /* Maximum label + seed len */
MAX_PRF_DIG = 224 /* Maximum digest len */
};
#endif
#if defined(WOLFSSL_HAVE_PRF) && ((defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))) || defined(HAVE_SELFTEST))
#ifdef WOLFSSL_HAVE_PRF
WOLFSSL_API int wc_PRF(byte* result, word32 resLen, const byte* secret,
word32 secLen, const byte* seed, word32 seedLen, int hash,
void* heap, int devId);

View File

@@ -189,6 +189,38 @@ WOLFSSL_API int wolfSSL_GetHmacMaxSize(void);
WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap);
#if (!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4))) && \
!defined(HAVE_SELFTEST)
enum max_prf {
#ifdef HAVE_FFDHE_8192
MAX_PRF_HALF = 516, /* Maximum half secret len */
#elif defined(HAVE_FFDHE_6144)
MAX_PRF_HALF = 388, /* Maximum half secret len */
#else
MAX_PRF_HALF = 260, /* Maximum half secret len */
#endif
MAX_PRF_LABSEED = 128, /* Maximum label + seed len */
MAX_PRF_DIG = 224 /* Maximum digest len */
};
#endif
#if defined(WOLFSSL_HAVE_PRF) && ((!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4))) && \
!defined(HAVE_SELFTEST))
WOLFSSL_API int wc_PRF(byte* result, word32 resLen, const byte* secret,
word32 secLen, const byte* seed, word32 seedLen, int hash,
void* heap, int devId);
WOLFSSL_API int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
word32 secLen, const byte* label, word32 labLen,
const byte* seed, word32 seedLen, void* heap, int devId);
WOLFSSL_API int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret,
word32 secLen, const byte* label, word32 labLen,
const byte* seed, word32 seedLen, int useAtLeastSha256,
int hash_type, void* heap, int devId);
#endif /* WOLFSSL_HAVE_PRF */
#ifdef HAVE_HKDF
WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
@@ -202,8 +234,42 @@ WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
const byte* info, word32 infoSz,
byte* out, word32 outSz);
#if (!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4))) && \
!defined(HAVE_SELFTEST)
enum {
/*
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE
*/
MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE
};
WOLFSSL_API int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
byte* ikm, int ikmLen, int digest);
WOLFSSL_API int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
const byte* prk, word32 prkLen,
const byte* protocol, word32 protocolLen,
const byte* label, word32 labelLen,
const byte* info, word32 infoLen,
int digest);
#endif /* HAVE_FIPS */
#endif /* HAVE_HKDF */
#ifdef WOLFSSL_WOLFSSH
WOLFSSL_API int wc_SSH_KDF(byte hashId, byte keyId,
byte* key, word32 keySz,
const byte* k, word32 kSz,
const byte* h, word32 hSz,
const byte* sessionId, word32 sessionIdSz);
#endif /* WOLFSSL_WOLFSSH */
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@@ -153,3 +153,11 @@ endif
if BUILD_FIPS_RAND
nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h
endif
if BUILD_FIPS_V3
nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h
endif
if BUILD_FIPS_V4
nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h
endif

View File

@@ -194,9 +194,13 @@ struct WC_RNG {
#define RNG WC_RNG
#endif
#ifndef WC_RNG_SEED_CB
WOLFSSL_LOCAL
int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
#else
WOLFSSL_API
int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
#endif
#ifdef HAVE_WNR
@@ -235,7 +239,10 @@ WOLFSSL_API int wc_FreeRng(WC_RNG*);
#define wc_FreeRng(rng) (void)NOT_COMPILED_IN
#endif
#ifdef WC_RNG_SEED_CB
typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz);
WOLFSSL_API int wc_SetSeed_Cb(wc_RngSeed_Cb cb);
#endif
#ifdef HAVE_HASHDRBG
WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,