Compare commits

...

66 Commits

Author SHA1 Message Date
John Safranek
1e0affb6f0 When the ECC PCT verify result is 0, the PCT fails. 2021-04-26 18:11:22 -07:00
John Safranek
7ba8196a3d Add missed step in DH key pair generation. 2021-04-20 14:00:47 -07:00
John Safranek
eeb57fb099 Add missing settings for the Windows 10 FIPS build. 2021-04-16 14:40:24 -07:00
John Safranek
f91af1a588 In the RSA PCT, initialize the plain output pointer. 2021-04-16 12:08:29 -07:00
John Safranek
6bb50db271 Update visibility on a SP math function for DH. 2021-04-16 12:01:41 -07:00
John Safranek
78ed928c8b Fixes:
1. When enabling FIPSv5 in configure, enable WOLFSSL_WOLFSSH.
2. Appropriate size selection of DH private keys.
2021-04-16 11:58:23 -07:00
John Safranek
962c64a78d Add sign/verify PCT to ECC. 2021-04-14 10:53:02 -07:00
John Safranek
b7ec8d0faa Add sign/verify PCT to RSA key gen. 2021-04-14 08:59:28 -07:00
John Safranek
1a4e45df3c Restore the PCTs to ECC and DH. 2021-04-12 09:37:24 -07:00
John Safranek
294a8e35f1 Fix some Windows build warnings. 2021-04-09 11:07:23 -07:00
John Safranek
93cdc0924b Check to see if a pointer is nonnull that is expected to be. 2021-04-09 10:54:36 -07:00
John Safranek
5d31723172 Modify ffdhe to not return addresses. 2021-04-09 09:31:13 -07:00
John Safranek
995488dcc1 Update WIN10 user_settings.h for new FIPS build. 2021-04-06 12:08:11 -07:00
John Safranek
5da43f4b24 When building for FIPS, the unit test will run all the CASTs up front. 2021-04-06 12:08:08 -07:00
John Safranek
9cdee9bc78 Add kdf.c to the Windows builds. 2021-04-05 11:15:09 -07:00
John Safranek
1b267628b8 Remove the unused ECDSA PCT tests in the CAST list. 2021-04-05 10:29:53 -07:00
John Safranek
9aa140f566 Remove the unused RSA PCT test in the CAST list. 2021-04-05 10:12:12 -07:00
John Safranek
d40e9f78cd Restore the HKDF code to hmac.c. For compatibility between FIPS builds. 2021-04-02 15:03:09 -07:00
John Safranek
0a210bcc1d Merge branch 'master' into fipsv3 2021-04-01 08:16:46 -07:00
John Safranek
273bfc38ff Remove redundant pairwise test from DH and ECC. 2021-04-01 08:14:19 -07:00
John Safranek
4d4039c052 Remove RDSEED from the intel asm build. 2021-03-31 14:25:57 -07:00
John Safranek
ea960a8600 Add missing verify curves into configure. Copy the kdf files when building for FIPSv5. 2021-03-31 08:42:45 -07:00
John Safranek
e4fdb63fed Skip the small key DH test for SP and FFDHE builds. 2021-03-29 14:40:40 -07:00
John Safranek
89273bdff8 Move the PCT down to where it used to be located as CheckKeyPair. 2021-03-26 15:11:51 -07:00
John Safranek
4124640a8d Update the BUILD_FIPS_V4 flag to V5. Consolidate the Makefile include for the flavors of FIPS. 2021-03-26 14:56:55 -07:00
John Safranek
f1a97904c5 Move the KDF functions into their own source file. 2021-03-26 14:17:18 -07:00
John Safranek
4781bf4e1f Add 'static' to the test vector arrays for the SSH KDF test. 2021-03-26 11:26:09 -07:00
John Safranek
804e9f1e82 Change visibility of wc_GenerateSeed() to API. 2021-03-26 11:25:14 -07:00
John Safranek
a57be5a8e5 Rename the PCT error codes to remove 'FIPS' since they can be enabled without FIPS. 2021-03-26 10:49:52 -07:00
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
46 changed files with 2578 additions and 957 deletions

View File

@@ -291,6 +291,7 @@
<ClCompile Include="..\..\wolfcrypt\src\integer.c" />
<ClCompile Include="..\..\src\internal.c" />
<ClCompile Include="..\..\src\wolfio.c" />
<ClCompile Include="..\..\wolfcrypt\src\kdf.c" />
<ClCompile Include="..\..\src\keys.c" />
<ClCompile Include="..\..\wolfcrypt\src\logging.c" />
<ClCompile Include="..\..\wolfcrypt\src\md5.c" />

View File

@@ -1,6 +1,9 @@
#ifndef _WIN_USER_SETTINGS_H_
#define _WIN_USER_SETTINGS_H_
#undef HAVE_FIPS_VERSION
#define HAVE_FIPS_VERSION 5
/* For FIPS Ready, uncomment the following: */
/* #define WOLFSSL_FIPS_READY */
#ifdef WOLFSSL_FIPS_READY
@@ -54,6 +57,40 @@
#define HAVE_INTEL_RDSEED
#define FORCE_FAILURE_RDSEED
#endif /* FIPS v2 */
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
#undef WOLFSSL_AESNI /* Comment out if using PAA */
#undef HAVE_INTEL_RDSEED
#undef FORCE_FAILURE_RDSEED
#define NO_DES
#define NO_DES3
#define NO_MD5
#define NO_OLD_TLS
#define WOLFSSL_TLS13
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES
#define GCM_TABLE_4BIT
#define WOLFSSL_NO_SHAKE256
#define WOLFSSL_VALIDATE_ECC_KEYGEN
#define WOLFSSL_ECDSA_SET_K
#define WOLFSSL_WOLFSSH
#define WOLFSSL_PUBLIC_MP
#define WC_RNG_SEED_CB
#define TFM_ECC256
#define ECC_USER_CURVES
#define HAVE_ECC192
#define HAVE_ECC224
#define HAVE_ECC256
#define HAVE_ECC384
#define HAVE_ECC521
#define HAVE_FFDHE_2048
#define HAVE_FFDHE_3072
#define HAVE_FFDHE_4096
#define HAVE_FFDHE_6144
#define HAVE_FFDHE_8192
#define FP_MAX_BITS 16384
#endif /* FIPS v5 */
#else
/* Enables blinding mode, to prevent timing attacks */
#define WC_RSA_BLINDING

View File

@@ -260,6 +260,7 @@
<ClCompile Include="..\..\wolfcrypt\src\integer.c" />
<ClCompile Include="..\..\src\internal.c" />
<ClCompile Include="..\..\src\wolfio.c" />
<ClCompile Include="..\..\wolfcrypt\src\kdf.c" />
<ClCompile Include="..\..\src\keys.c" />
<ClCompile Include="..\..\wolfcrypt\src\logging.c" />
<ClCompile Include="..\..\wolfcrypt\src\md5.c" />
@@ -276,6 +277,7 @@
<ClCompile Include="..\..\wolfcrypt\src\signature.c" />
<ClCompile Include="..\..\src\ssl.c" />
<ClCompile Include="..\..\src\tls.c" />
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\wolfcrypt\src\wc_encrypt.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_first.c" />
<ClCompile Include="..\..\wolfcrypt\src\wolfcrypt_last.c" />

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)])],
@@ -1517,7 +1533,7 @@ then
if test "$ENABLED_INTELASM" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_INTEL_RDSEED -DUSE_INTEL_SPEEDUP"
AM_CFLAGS="$AM_CFLAGS -DUSE_INTEL_SPEEDUP"
ENABLED_AESNI=yes
fi
fi
@@ -1755,7 +1771,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
@@ -3028,13 +3044,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"
# 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_ECC192 -DHAVE_ECC224 -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"],
@@ -3060,29 +3106,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
@@ -3114,22 +3192,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
@@ -3143,6 +3211,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],
@@ -6039,6 +6114,9 @@ AS_IF([test "x$ENABLED_NULL_CIPHER" = "xno" && \
[AM_CFLAGS="-DHAVE_NULL_CIPHER $AM_CFLAGS"
ENABLED_NULL_CIPHER=yes])
# FIPSv5 requires the wolfSSH option.
AS_IF([test "x$FIPS_VERSION" = "xv5"],[ENABLED_WOLFSSH="yes"])
# wolfSSH and WPA Supplicant both need Public MP, only enable once.
# This will let you know if you enabled wolfSSH but have any of the prereqs
# disabled. Some of these options, disabling them adds things to the FLAGS and
@@ -6054,6 +6132,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
@@ -6264,7 +6344,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_V5],[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

@@ -3880,6 +3880,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 kdf )
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

@@ -269,6 +269,7 @@ mkdir -p $RPM_BUILD_ROOT/
%{_includedir}/wolfssl/wolfcrypt/hmac.h
%{_includedir}/wolfssl/wolfcrypt/idea.h
%{_includedir}/wolfssl/wolfcrypt/integer.h
%{_includedir}/wolfssl/wolfcrypt/kdf.h
%{_includedir}/wolfssl/wolfcrypt/logging.h
%{_includedir}/wolfssl/wolfcrypt/md2.h
%{_includedir}/wolfssl/wolfcrypt/md4.h
@@ -305,6 +306,8 @@ mkdir -p $RPM_BUILD_ROOT/
%{_libdir}/pkgconfig/wolfssl.pc
%changelog
* Thu Mar 25 2021 John Safranek <john@wolfssl.com>
- Add new header kdf.h
* Mon Aug 17 2020 John Safranek <john@wolfssl.com>
- Add a missing header.
- Update for release.

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,154 @@ 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_V5
# 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
src_libwolfssl_la_SOURCES += wolfcrypt/src/kdf.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 +256,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 +282,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_V5
endif BUILD_FIPS
@@ -168,9 +293,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 +310,17 @@ src_libwolfssl_la_SOURCES += \
if !BUILD_FIPS_RAND
if !BUILD_FIPS_V2
if !BUILD_FIPS_V5
src_libwolfssl_la_SOURCES += wolfcrypt/src/kdf.c
endif !BUILD_FIPS_V5
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 +329,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 +348,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 +363,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 +387,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 +399,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 +432,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 +459,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 +508,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 +568,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)
@@ -22087,7 +22087,6 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
int ret = 0;
word16 length;
#ifdef HAVE_FFDHE
const DhParams* params = NULL;
word16 group = 0;
#endif
@@ -22253,31 +22252,26 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
switch (ssl->options.dhKeySz) {
#ifdef HAVE_FFDHE_2048
case 2048/8:
params = wc_Dh_ffdhe2048_Get();
group = WOLFSSL_FFDHE_2048;
break;
#endif
#ifdef HAVE_FFDHE_3072
case 3072/8:
params = wc_Dh_ffdhe3072_Get();
group = WOLFSSL_FFDHE_3072;
break;
#endif
#ifdef HAVE_FFDHE_4096
case 4096/8:
params = wc_Dh_ffdhe4096_Get();
group = WOLFSSL_FFDHE_4096;
break;
#endif
#ifdef HAVE_FFDHE_6144
case 6144/8:
params = wc_Dh_ffdhe6144_Get();
group = WOLFSSL_FFDHE_6144;
break;
#endif
#ifdef HAVE_FFDHE_8192
case 8192/8:
params = wc_Dh_ffdhe8192_Get();
group = WOLFSSL_FFDHE_8192;
break;
#endif
@@ -22285,11 +22279,10 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
break;
}
if (params == NULL || params->g_len != ssl->buffers.serverDH_G.length ||
(XMEMCMP(ssl->buffers.serverDH_G.buffer, params->g,
params->g_len) != 0) ||
(XMEMCMP(ssl->buffers.serverDH_P.buffer, params->p,
params->p_len) != 0)) {
if (!wc_DhCmpNamedKey(group, 1,
ssl->buffers.serverDH_P.buffer, ssl->buffers.serverDH_P.length,
ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length,
NULL, 0)) {
WOLFSSL_MSG("Server not using FFDHE parameters");
#ifdef WOLFSSL_REQUIRE_FFDHE
SendAlert(ssl, alert_fatal, handshake_failure);
@@ -24076,6 +24069,18 @@ int SendClientKeyExchange(WOLFSSL* ssl)
goto exit_scke;
}
#ifdef HAVE_FFDHE
if (ssl->namedGroup) {
ret = wc_DhSetNamedKey(ssl->buffers.serverDH_Key,
ssl->namedGroup);
if (ret != 0) {
goto exit_scke;
}
ssl->buffers.sig.length =
wc_DhGetNamedKeyMinSize(ssl->namedGroup);
}
else
#endif
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
!defined(WOLFSSL_OLD_PRIME_CHECK)
if (ssl->options.dhDoKeyTest &&
@@ -24221,8 +24226,9 @@ int SendClientKeyExchange(WOLFSSL* ssl)
/* for DH, encSecret is Yc, agree is pre-master */
ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
args->output + OPAQUE16_LEN, &args->length);
ssl->buffers.sig.buffer,
(word32*)&ssl->buffers.sig.length,
args->output + OPAQUE16_LEN, &args->length);
break;
}
#endif /* !NO_DH && !NO_PSK */
@@ -26111,6 +26117,63 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#if !defined(NO_RSA)
case diffie_hellman_kea:
#endif
#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
if (ssl->namedGroup) {
word32 pSz = 0;
wc_DhGetNamedKeyParamSize(ssl->namedGroup, &pSz,
NULL, NULL);
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
/* Free'd in SSL_ResourceFree and
* FreeHandshakeResources */
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
ssl->buffers.serverDH_Pub.length = pSz;
}
ssl->options.dhKeySz =(word16)pSz;
pSz = wc_DhGetNamedKeyMinSize(ssl->namedGroup);
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
/* Free'd in SSL_ResourceFree and
* FreeHandshakeResources */
ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
pSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
ssl->buffers.serverDH_Priv.length = pSz;
}
ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
(void**)&ssl->buffers.serverDH_Key);
if (ret != 0) {
goto exit_sske;
}
ret = wc_DhSetNamedKey(ssl->buffers.serverDH_Key,
ssl->namedGroup);
if (ret != 0) {
goto exit_sske;
}
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
ssl->options.dhKeyTested = 1;
#endif
ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
ssl->buffers.serverDH_Priv.buffer,
(word32*)&ssl->buffers.serverDH_Priv.length,
ssl->buffers.serverDH_Pub.buffer,
(word32*)&ssl->buffers.serverDH_Pub.length);
break;
}
else
#endif
{
/* Allocate DH key buffers and generate key */
if (ssl->buffers.serverDH_P.buffer == NULL ||
@@ -26121,25 +26184,25 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
ssl->buffers.serverDH_P.length,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
ssl->buffers.serverDH_Pub.length =
ssl->buffers.serverDH_P.length + OPAQUE16_LEN;
ssl->buffers.serverDH_P.length;
}
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */
ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
ssl->buffers.serverDH_P.length,
ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
ssl->buffers.serverDH_Priv.length =
ssl->buffers.serverDH_P.length + OPAQUE16_LEN;
ssl->buffers.serverDH_P.length;
}
ssl->options.dhKeySz =

View File

@@ -2221,57 +2221,23 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
/* Static DH Key */
if (ksInfo && ksInfo->dh_key_bits != 0 && keys->dhKey) {
DhKey dhKey;
const DhParams* params;
word32 privKeySz;
word32 privKeySz = 0, p_len = 0;
byte privKey[52]; /* max for TLS */
keyBuf = keys->dhKey;
/* get DH params */
switch (ksInfo->named_group) {
#ifdef HAVE_FFDHE_2048
case WOLFSSL_FFDHE_2048:
params = wc_Dh_ffdhe2048_Get();
privKeySz = 29;
break;
#endif
#ifdef HAVE_FFDHE_3072
case WOLFSSL_FFDHE_3072:
params = wc_Dh_ffdhe3072_Get();
privKeySz = 34;
break;
#endif
#ifdef HAVE_FFDHE_4096
case WOLFSSL_FFDHE_4096:
params = wc_Dh_ffdhe4096_Get();
privKeySz = 39;
break;
#endif
#ifdef HAVE_FFDHE_6144
case WOLFSSL_FFDHE_6144:
params = wc_Dh_ffdhe6144_Get();
privKeySz = 46;
break;
#endif
#ifdef HAVE_FFDHE_8192
case WOLFSSL_FFDHE_8192:
params = wc_Dh_ffdhe8192_Get();
privKeySz = 52;
break;
#endif
default:
return BAD_FUNC_ARG;
}
ret = wc_InitDhKey(&dhKey);
if (ret == 0) {
ret = wc_DhSetKey(&dhKey,
(byte*)params->p, params->p_len,
(byte*)params->g, params->g_len);
ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group);
if (ret == 0) {
ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey,
keyBuf->length);
}
if (ret == 0) {
privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group);
ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group,
&p_len, NULL, NULL);
}
if (ret == 0) {
ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL,
NULL);
@@ -2295,13 +2261,13 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
wc_FreeDhKey(&dhKey);
/* left-padded with zeros up to the size of the prime */
if (params->p_len > session->sslServer->arrays->preMasterSz) {
word32 diff = params->p_len - session->sslServer->arrays->preMasterSz;
if (p_len > session->sslServer->arrays->preMasterSz) {
word32 diff = p_len - session->sslServer->arrays->preMasterSz;
XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff,
session->sslServer->arrays->preMasterSecret,
session->sslServer->arrays->preMasterSz);
XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff);
session->sslServer->arrays->preMasterSz = params->p_len;
session->sslServer->arrays->preMasterSz = p_len;
}
}
}

View File

@@ -37,6 +37,7 @@
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/coding.h>
#include <wolfssl/wolfcrypt/kdf.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else

166
src/tls.c
View File

@@ -32,7 +32,9 @@
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/kdf.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
@@ -4178,7 +4180,7 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
SupportedCurve* serverGroup;
SupportedCurve* clientGroup;
SupportedCurve* group;
const DhParams* params = NULL;
word32 p_len;
int found = 0;
extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
@@ -4226,39 +4228,11 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
if (serverGroup->name != group->name)
continue;
switch (serverGroup->name) {
#ifdef HAVE_FFDHE_2048
case WOLFSSL_FFDHE_2048:
params = wc_Dh_ffdhe2048_Get();
break;
#endif
#ifdef HAVE_FFDHE_3072
case WOLFSSL_FFDHE_3072:
params = wc_Dh_ffdhe3072_Get();
break;
#endif
#ifdef HAVE_FFDHE_4096
case WOLFSSL_FFDHE_4096:
params = wc_Dh_ffdhe4096_Get();
break;
#endif
#ifdef HAVE_FFDHE_6144
case WOLFSSL_FFDHE_6144:
params = wc_Dh_ffdhe6144_Get();
break;
#endif
#ifdef HAVE_FFDHE_8192
case WOLFSSL_FFDHE_8192:
params = wc_Dh_ffdhe8192_Get();
break;
#endif
default:
break;
}
if (params == NULL)
wc_DhGetNamedKeyParamSize(serverGroup->name, &p_len, NULL, NULL);
if (p_len == 0)
return BAD_FUNC_ARG;
if (params->p_len >= ssl->options.minDhKeySz &&
params->p_len <= ssl->options.maxDhKeySz) {
if (p_len >= ssl->options.minDhKeySz &&
p_len <= ssl->options.maxDhKeySz) {
break;
}
}
@@ -4268,15 +4242,26 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
}
if (serverGroup) {
ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p;
ssl->buffers.serverDH_P.length = params->p_len;
ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g;
ssl->buffers.serverDH_G.length = params->g_len;
word32 pSz, gSz;
ret = wc_DhGetNamedKeyParamSize(serverGroup->name, &pSz, &gSz, NULL);
ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
ssl->buffers.serverDH_P.length = pSz;
ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz,
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
ssl->buffers.serverDH_G.length = gSz;
wc_DhCopyNamedKey(serverGroup->name,
ssl->buffers.serverDH_P.buffer, &pSz,
ssl->buffers.serverDH_G.buffer, &gSz,
NULL, NULL);
ssl->namedGroup = serverGroup->name;
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
ssl->options.dhDoKeyTest = 0;
#endif
ssl->buffers.weOwnDH = 1;
ssl->options.haveDH = 1;
}
@@ -6667,52 +6652,21 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
{
int ret;
#ifndef NO_DH
byte* keyData;
byte* keyData = NULL;
void* key = NULL;
word32 keySz;
word32 dataSz;
const DhParams* params;
word32 p_len;
#ifdef WOLFSSL_SMALL_STACK
DhKey* dhKey = NULL;
#else
DhKey dhKey[1];
#endif
/* TODO: [TLS13] The key size should come from wolfcrypt. */
/* Pick the parameters from the named group. */
switch (kse->group) {
#ifdef HAVE_FFDHE_2048
case WOLFSSL_FFDHE_2048:
params = wc_Dh_ffdhe2048_Get();
keySz = 29;
break;
#endif
#ifdef HAVE_FFDHE_3072
case WOLFSSL_FFDHE_3072:
params = wc_Dh_ffdhe3072_Get();
keySz = 34;
break;
#endif
#ifdef HAVE_FFDHE_4096
case WOLFSSL_FFDHE_4096:
params = wc_Dh_ffdhe4096_Get();
keySz = 39;
break;
#endif
#ifdef HAVE_FFDHE_6144
case WOLFSSL_FFDHE_6144:
params = wc_Dh_ffdhe6144_Get();
keySz = 46;
break;
#endif
#ifdef HAVE_FFDHE_8192
case WOLFSSL_FFDHE_8192:
params = wc_Dh_ffdhe8192_Get();
keySz = 52;
break;
#endif
default:
return BAD_FUNC_ARG;
keySz = wc_DhGetNamedKeyMinSize(kse->group);
if (keySz == 0) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_SMALL_STACK
@@ -6730,13 +6684,22 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
}
/* Allocate space for the public key */
dataSz = params->p_len;
ret = wc_DhGetNamedKeyParamSize(kse->group, &p_len, NULL, NULL);
if (ret != 0) {
goto end;
}
dataSz = p_len;
keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (keyData == NULL) {
ret = MEMORY_E;
goto end;
}
/* Allocate space for the private key */
keySz = wc_DhGetNamedKeyMinSize(kse->group);
if (keySz == 0) {
ret = WC_KEY_SIZE_E;
goto end;
}
key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
if (key == NULL) {
ret = MEMORY_E;
@@ -6744,8 +6707,7 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
}
/* Set key */
ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
params->g_len);
ret = wc_DhSetNamedKey(dhKey, kse->group);
if (ret != 0)
goto end;
@@ -6775,14 +6737,14 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
if (ret != 0)
goto end;
if (params->p_len != dataSz) {
if (p_len != dataSz) {
/* Zero pad the front of the public key to match prime "p" size */
XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz);
XMEMSET(keyData, 0, params->p_len - dataSz);
XMEMMOVE(keyData + p_len - dataSz, keyData, dataSz);
XMEMSET(keyData, 0, p_len - dataSz);
}
kse->pubKey = keyData;
kse->pubKeyLen = params->p_len;
kse->pubKeyLen = p_len;
kse->key = key;
kse->keyLen = keySz;
@@ -7239,43 +7201,13 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
{
#ifndef NO_DH
int ret;
const DhParams* params;
word32 pSz;
#ifdef WOLFSSL_SMALL_STACK
DhKey* dhKey = NULL;
#else
DhKey dhKey[1];
#endif
switch (keyShareEntry->group) {
#ifdef HAVE_FFDHE_2048
case WOLFSSL_FFDHE_2048:
params = wc_Dh_ffdhe2048_Get();
break;
#endif
#ifdef HAVE_FFDHE_3072
case WOLFSSL_FFDHE_3072:
params = wc_Dh_ffdhe3072_Get();
break;
#endif
#ifdef HAVE_FFDHE_4096
case WOLFSSL_FFDHE_4096:
params = wc_Dh_ffdhe4096_Get();
break;
#endif
#ifdef HAVE_FFDHE_6144
case WOLFSSL_FFDHE_6144:
params = wc_Dh_ffdhe6144_Get();
break;
#endif
#ifdef HAVE_FFDHE_8192
case WOLFSSL_FFDHE_8192:
params = wc_Dh_ffdhe8192_Get();
break;
#endif
default:
return PEER_KEY_ERROR;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Peer DH Key");
WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
@@ -7296,8 +7228,7 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
}
/* Set key */
ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
params->g_len);
ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group);
if (ret != 0) {
wc_FreeDhKey(dhKey);
#ifdef WOLFSSL_SMALL_STACK
@@ -7305,6 +7236,7 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
#endif
return ret;
}
pSz = wc_DhGetNamedKeyMinSize(keyShareEntry->group);
ret = wc_DhCheckPubKey(dhKey, keyShareEntry->ke, keyShareEntry->keLen);
if (ret != 0) {
@@ -7329,15 +7261,15 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
/* RFC 8446 Section 7.4.1:
* ... left-padded with zeros up to the size of the prime. ...
*/
if (params->p_len > ssl->arrays->preMasterSz) {
word32 diff = params->p_len - ssl->arrays->preMasterSz;
if (pSz > ssl->arrays->preMasterSz) {
word32 diff = pSz - ssl->arrays->preMasterSz;
XMEMMOVE(ssl->arrays->preMasterSecret + diff,
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
XMEMSET(ssl->arrays->preMasterSecret, 0, diff);
ssl->arrays->preMasterSz = params->p_len;
ssl->arrays->preMasterSz = pSz;
}
ssl->options.dhKeySz = (word16)params->p_len;
ssl->options.dhKeySz = pSz;
wc_FreeDhKey(dhKey);
#ifdef WOLFSSL_SMALL_STACK

View File

@@ -93,6 +93,7 @@
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/dh.h>
#include <wolfssl/wolfcrypt/kdf.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
@@ -139,137 +140,6 @@
*/
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
/* 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.
* mac 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)
{
int ret;
int hash = 0;
int len = 0;
switch (mac) {
#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_TLS13_SHA512
case sha512_mac:
hash = WC_SHA512;
len = WC_SHA512_DIGEST_SIZE;
break;
#endif
default:
break;
}
/* 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(hash, 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.
*/
static int 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_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 */
if (info != NULL && infoLen > 0) {
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;
}
/* 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 +233,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 +305,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 +714,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 +726,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 +815,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 +848,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 +872,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 +932,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

@@ -405,7 +405,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
@@ -14702,7 +14703,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;
@@ -15363,7 +15365,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)
@@ -15473,7 +15476,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
@@ -15951,7 +15955,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) {
@@ -16021,7 +16026,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

@@ -30,6 +30,7 @@
#include <stdio.h>
#include <tests/unit.h>
#include <wolfssl/wolfcrypt/fips_test.h>
int myoptind = 0;
@@ -64,6 +65,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");
@@ -73,6 +77,51 @@ int unit_test(int argc, char** argv)
ChangeToWolfRoot();
#endif
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 5)
if (wc_RunCast_fips(FIPS_CAST_AES_CBC) != 0) {
err_sys("AES-CBC CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_AES_GCM) != 0) {
err_sys("AES-GCM CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_HMAC_SHA1) != 0) {
err_sys("HMAC-SHA1 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_256) != 0) {
err_sys("HMAC-SHA2-256 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_512) != 0) {
err_sys("HMAC-SHA2-512 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_HMAC_SHA3_256) != 0) {
err_sys("HMAC-SHA3-256 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_DRBG) != 0) {
err_sys("Hash_DRBG CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_RSA_SIGN_PKCS1v15) != 0) {
err_sys("RSA sign CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_ECC_PRIMITIVE_Z) != 0) {
err_sys("ECC Primitive Z CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_DH_PRIMITIVE_Z) != 0) {
err_sys("DH Primitive Z CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_ECDSA) != 0) {
err_sys("ECDSA CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_KDF_TLS12) != 0) {
err_sys("KDF TLSv1.2 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_KDF_TLS13) != 0) {
err_sys("KDF TLSv1.3 CAST failed");
}
if (wc_RunCast_fips(FIPS_CAST_KDF_SSH) != 0) {
err_sys("KDF SSHv2.0 CAST failed");
}
#endif
ApiTest();
if ( (ret = HashTest()) != 0){

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();
@@ -5059,8 +5062,8 @@ void bench_dh(int doAsync)
word32 pubSz2 = BENCH_DH_KEY_SIZE;
word32 privSz2 = BENCH_DH_PRIV_SIZE;
word32 agreeSz[BENCH_MAX_PENDING];
#ifdef HAVE_FFDHE_2048
const DhParams *params = NULL;
#if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072)
int paramName = 0;
#endif
DECLARE_ARRAY(pub, byte, BENCH_MAX_PENDING, BENCH_DH_KEY_SIZE, HEAP_HINT);
@@ -5099,13 +5102,13 @@ void bench_dh(int doAsync)
}
#ifdef HAVE_FFDHE_2048
else if (use_ffdhe == 2048) {
params = wc_Dh_ffdhe2048_Get();
paramName = WC_FFDHE_2048;
dhKeySz = 2048;
}
#endif
#ifdef HAVE_FFDHE_3072
else if (use_ffdhe == 3072) {
params = wc_Dh_ffdhe3072_Get();
paramName = WC_FFDHE_3072;
dhKeySz = 3072;
}
#endif
@@ -5132,9 +5135,8 @@ void bench_dh(int doAsync)
#endif
}
#if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072)
else if (params != NULL) {
ret = wc_DhSetKey(&dhKey[i], params->p, params->p_len, params->g,
params->g_len);
else if (paramName != 0) {
ret = wc_DhSetNamedKey(&dhKey[i], paramName);
}
#endif
if (ret != 0) {

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

@@ -148,6 +148,7 @@ static const byte dh_ffdhe2048_q[] = {
};
#endif /* HAVE_FFDHE_Q */
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* wc_Dh_ffdhe2048_Get(void)
{
static const DhParams ffdhe2048 = {
@@ -160,6 +161,7 @@ const DhParams* wc_Dh_ffdhe2048_Get(void)
return &ffdhe2048;
}
#endif
#endif
#ifdef HAVE_FFDHE_3072
static const byte dh_ffdhe3072_p[] = {
@@ -266,6 +268,7 @@ static const byte dh_ffdhe3072_q[] = {
};
#endif /* HAVE_FFDHE_Q */
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* wc_Dh_ffdhe3072_Get(void)
{
static const DhParams ffdhe3072 = {
@@ -278,6 +281,7 @@ const DhParams* wc_Dh_ffdhe3072_Get(void)
return &ffdhe3072;
}
#endif
#endif
#ifdef HAVE_FFDHE_4096
static const byte dh_ffdhe4096_p[] = {
@@ -416,6 +420,7 @@ static const byte dh_ffdhe4096_q[] = {
};
#endif /* HAVE_FFDHE_Q */
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* wc_Dh_ffdhe4096_Get(void)
{
static const DhParams ffdhe4096 = {
@@ -428,6 +433,7 @@ const DhParams* wc_Dh_ffdhe4096_Get(void)
return &ffdhe4096;
}
#endif
#endif
#ifdef HAVE_FFDHE_6144
static const byte dh_ffdhe6144_p[] = {
@@ -630,6 +636,7 @@ static const byte dh_ffdhe6144_q[] = {
};
#endif /* HAVE_FFDHE_Q */
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* wc_Dh_ffdhe6144_Get(void)
{
static const DhParams ffdhe6144 = {
@@ -642,6 +649,7 @@ const DhParams* wc_Dh_ffdhe6144_Get(void)
return &ffdhe6144;
}
#endif
#endif
#ifdef HAVE_FFDHE_8192
static const byte dh_ffdhe8192_p[] = {
@@ -908,6 +916,7 @@ static const byte dh_ffdhe8192_q[] = {
};
#endif /* HAVE_FFDHE_Q */
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* wc_Dh_ffdhe8192_Get(void)
{
static const DhParams ffdhe8192 = {
@@ -920,6 +929,7 @@ const DhParams* wc_Dh_ffdhe8192_Get(void)
return &ffdhe8192;
}
#endif
#endif
int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
{
@@ -929,6 +939,7 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
return BAD_FUNC_ARG;
key->heap = heap; /* for XMALLOC/XFREE in future */
key->trustedGroup = 0;
#ifdef WOLFSSL_DH_EXTRA
if (mp_init_multi(&key->p, &key->g, &key->q, &key->pub, &key->priv, NULL) != MP_OKAY)
@@ -944,6 +955,7 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
#else
(void)devId;
#endif
key->trustedGroup = 0;
return ret;
}
@@ -973,6 +985,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
@@ -1034,8 +1052,8 @@ static int CheckDhLN(int modLen, int divLen)
/* Create DH private key
*
* Based on NIST FIPS 186-4,
* "B.1.1 Key Pair Generation Using Extra Random Bits"
* Based on NIST SP 800-56Ar3
* "5.6.1.1.3 Key Pair Generation Using Extra Random Bits"
*
* dh - pointer to initialized DhKey structure, needs to have dh->q
* rng - pointer to initialized WC_RNG structure
@@ -1066,13 +1084,15 @@ 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;
}
/* generate extra 64 bits so that bias from mod function is negligible */
cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
cSz = *privSz + (64 / WOLFSSL_BIT_SIZE);
cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (cBuf == NULL) {
return MEMORY_E;
@@ -1124,18 +1144,24 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
ForceZero(cBuf, cSz);
XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
/* tmpQ = q - 1 */
/* tmpQ: M = min(2^N,q) - 1 */
if (err == MP_OKAY)
err = mp_copy(&key->q, tmpQ);
err = mp_2expt(tmpQ, *privSz * 8);
if (err == MP_OKAY) {
if (mp_cmp(tmpQ, &key->q) == MP_GT) {
err = mp_copy(&key->q, tmpQ);
}
}
if (err == MP_OKAY)
err = mp_sub_d(tmpQ, 1, tmpQ);
/* x = c mod (q-1), tmpX holds c */
/* x = c mod (M), tmpX holds c */
if (err == MP_OKAY)
err = mp_mod(tmpX, tmpQ, tmpX);
/* x = c mod (q-1) + 1 */
/* x = c mod (M) + 1 */
if (err == MP_OKAY)
err = mp_add_d(tmpX, 1, tmpX);
@@ -1173,7 +1199,7 @@ static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
#ifndef WOLFSSL_NO_DH186
if (mp_iszero(&key->q) == MP_NO) {
/* q param available, use NIST FIPS 186-4, "B.1.1 Key Pair
/* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair
* Generation Using Extra Random Bits" */
ret = GeneratePrivateDh186(key, rng, priv, privSz);
@@ -1325,7 +1351,14 @@ 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);
return ret;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
@@ -1390,18 +1423,20 @@ static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
/* 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 +1493,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 +1510,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 +1576,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 +1595,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);
}
@@ -1705,19 +1751,11 @@ int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
}
/* Performs a Pairwise Consistency Test on an FFC key pair. */
/* Check DH Keys for pair-wise consistency per process in
* SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
*
* key DH key group parameters.
* pub Public Key.
* pubSz Public Key size.
* priv Private Key.
* privSz Private Key size.
*
* returns 0 on success or error code
*/
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
const byte* priv, word32 privSz)
* SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. */
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;
@@ -1825,6 +1863,24 @@ int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
}
/* Check DH Keys for pair-wise consistency per process in
* SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
*
* key DH key group parameters.
* pub Public Key.
* pubSz Public Key size.
* priv Private Key.
* privSz Private Key size.
*
* returns 0 on success or error code
*/
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
const byte* priv, word32 privSz)
{
return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz);
}
int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
byte* priv, word32* privSz, byte* pub, word32* pubSz)
{
@@ -2289,6 +2345,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) {
@@ -2313,7 +2371,7 @@ int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
word32 gSz, const byte* q, word32 qSz)
{
return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL);
}
@@ -2321,10 +2379,364 @@ int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
word32 gSz)
{
/* This should not have trusted set. */
return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
}
int wc_DhSetNamedKey(DhKey* key, int name)
{
const byte* p = NULL;
const byte* g = NULL;
const byte* q = NULL;
word32 pSz = 0, gSz = 0, qSz = 0;
switch (name) {
#ifdef HAVE_FFDHE_2048
case WC_FFDHE_2048:
p = dh_ffdhe2048_p;
pSz = sizeof(dh_ffdhe2048_p);
g = dh_ffdhe2048_g;
gSz = sizeof(dh_ffdhe2048_g);
#ifdef HAVE_FFDHE_Q
q = dh_ffdhe2048_q;
qSz = sizeof(dh_ffdhe2048_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_2048 */
#ifdef HAVE_FFDHE_3072
case WC_FFDHE_3072:
p = dh_ffdhe3072_p;
pSz = sizeof(dh_ffdhe3072_p);
g = dh_ffdhe3072_g;
gSz = sizeof(dh_ffdhe3072_g);
#ifdef HAVE_FFDHE_Q
q = dh_ffdhe3072_q;
qSz = sizeof(dh_ffdhe3072_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_3072 */
#ifdef HAVE_FFDHE_4096
case WC_FFDHE_4096:
p = dh_ffdhe4096_p;
pSz = sizeof(dh_ffdhe4096_p);
g = dh_ffdhe4096_g;
gSz = sizeof(dh_ffdhe4096_g);
#ifdef HAVE_FFDHE_Q
q = dh_ffdhe4096_q;
qSz = sizeof(dh_ffdhe4096_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_4096 */
#ifdef HAVE_FFDHE_6144
case WC_FFDHE_6144:
p = dh_ffdhe6144_p;
pSz = sizeof(dh_ffdhe6144_p);
g = dh_ffdhe6144_g;
gSz = sizeof(dh_ffdhe6144_g);
#ifdef HAVE_FFDHE_Q
q = dh_ffdhe6144_q;
qSz = sizeof(dh_ffdhe6144_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_6144 */
#ifdef HAVE_FFDHE_8192
case WC_FFDHE_8192:
p = dh_ffdhe8192_p;
pSz = sizeof(dh_ffdhe8192_p);
g = dh_ffdhe8192_g;
gSz = sizeof(dh_ffdhe8192_g);
#ifdef HAVE_FFDHE_Q
q = dh_ffdhe8192_q;
qSz = sizeof(dh_ffdhe8192_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_8192 */
default:
break;
}
return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
}
word32 wc_DhGetNamedKeyMinSize(int name)
{
int size;
switch (name) {
#ifdef HAVE_FFDHE_2048
case WC_FFDHE_2048:
size = 29;
break;
#endif /* HAVE_FFDHE_2048 */
#ifdef HAVE_FFDHE_3072
case WC_FFDHE_3072:
size = 34;
break;
#endif /* HAVE_FFDHE_3072 */
#ifdef HAVE_FFDHE_4096
case WC_FFDHE_4096:
size = 39;
break;
#endif /* HAVE_FFDHE_4096 */
#ifdef HAVE_FFDHE_6144
case WC_FFDHE_6144:
size = 46;
break;
#endif /* HAVE_FFDHE_6144 */
#ifdef HAVE_FFDHE_8192
case WC_FFDHE_8192:
size = 52;
break;
#endif /* HAVE_FFDHE_8192 */
default:
size = 0;
}
return size;
}
/* Returns 1: params match
* 0: params differ */
int wc_DhCmpNamedKey(int name, int noQ,
const byte* p, word32 pSz,
const byte* g, word32 gSz,
const byte* q, word32 qSz)
{
const byte* pCmp = NULL;
const byte* qCmp = NULL;
const byte* gCmp = NULL;
word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0;
int cmp = 0, goodName = 1;
switch (name) {
#ifdef HAVE_FFDHE_2048
case WC_FFDHE_2048:
pCmp = dh_ffdhe2048_p;
pCmpSz = sizeof(dh_ffdhe2048_p);
gCmp = dh_ffdhe2048_g;
gCmpSz = sizeof(dh_ffdhe2048_g);
#ifdef HAVE_FFDHE_Q
qCmp = dh_ffdhe2048_q;
qCmpSz = sizeof(dh_ffdhe2048_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_2048 */
#ifdef HAVE_FFDHE_3072
case WC_FFDHE_3072:
pCmp = dh_ffdhe3072_p;
pCmpSz = sizeof(dh_ffdhe3072_p);
gCmp = dh_ffdhe3072_g;
gCmpSz = sizeof(dh_ffdhe3072_g);
#ifdef HAVE_FFDHE_Q
qCmp = dh_ffdhe3072_q;
qCmpSz = sizeof(dh_ffdhe3072_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_3072 */
#ifdef HAVE_FFDHE_4096
case WC_FFDHE_4096:
pCmp = dh_ffdhe4096_p;
pCmpSz = sizeof(dh_ffdhe4096_p);
gCmp = dh_ffdhe4096_g;
gCmpSz = sizeof(dh_ffdhe4096_g);
#ifdef HAVE_FFDHE_Q
qCmp = dh_ffdhe4096_q;
qCmpSz = sizeof(dh_ffdhe4096_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_4096 */
#ifdef HAVE_FFDHE_6144
case WC_FFDHE_6144:
pCmp = dh_ffdhe6144_p;
pCmpSz = sizeof(dh_ffdhe6144_p);
gCmp = dh_ffdhe6144_g;
gCmpSz = sizeof(dh_ffdhe6144_g);
#ifdef HAVE_FFDHE_Q
qCmp = dh_ffdhe6144_q;
qCmpSz = sizeof(dh_ffdhe6144_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_6144 */
#ifdef HAVE_FFDHE_8192
case WC_FFDHE_8192:
pCmp = dh_ffdhe8192_p;
pCmpSz = sizeof(dh_ffdhe8192_p);
gCmp = dh_ffdhe8192_g;
gCmpSz = sizeof(dh_ffdhe8192_g);
#ifdef HAVE_FFDHE_Q
qCmp = dh_ffdhe8192_q;
qCmpSz = sizeof(dh_ffdhe8192_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_8192 */
default:
goodName = 0;
}
cmp = goodName && (pSz == pCmpSz) && (gSz == gCmpSz) &&
(noQ || ((qCmp != NULL) && (qSz == qCmpSz) &&
XMEMCMP(q, qCmp, qCmpSz) == 0)) &&
(XMEMCMP(p, pCmp, pCmpSz) == 0) &&
(XMEMCMP(g, gCmp, gCmpSz) == 0);
return cmp;
}
int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q)
{
word32 pSz = 0, gSz = 0, qSz = 0;
switch (name) {
#ifdef HAVE_FFDHE_2048
case WC_FFDHE_2048:
pSz = sizeof(dh_ffdhe2048_p);
gSz = sizeof(dh_ffdhe2048_g);
#ifdef HAVE_FFDHE_Q
qSz = sizeof(dh_ffdhe2048_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_2048 */
#ifdef HAVE_FFDHE_3072
case WC_FFDHE_3072:
pSz = sizeof(dh_ffdhe3072_p);
gSz = sizeof(dh_ffdhe3072_g);
#ifdef HAVE_FFDHE_Q
qSz = sizeof(dh_ffdhe3072_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_3072 */
#ifdef HAVE_FFDHE_4096
case WC_FFDHE_4096:
pSz = sizeof(dh_ffdhe4096_p);
gSz = sizeof(dh_ffdhe4096_g);
#ifdef HAVE_FFDHE_Q
qSz = sizeof(dh_ffdhe4096_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_4096 */
#ifdef HAVE_FFDHE_6144
case WC_FFDHE_6144:
pSz = sizeof(dh_ffdhe6144_p);
gSz = sizeof(dh_ffdhe6144_g);
#ifdef HAVE_FFDHE_Q
qSz = sizeof(dh_ffdhe6144_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_6144 */
#ifdef HAVE_FFDHE_8192
case WC_FFDHE_8192:
pSz = sizeof(dh_ffdhe8192_p);
gSz = sizeof(dh_ffdhe8192_g);
#ifdef HAVE_FFDHE_Q
qSz = sizeof(dh_ffdhe8192_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_8192 */
default:
break;
}
if (p != NULL) *p = pSz;
if (g != NULL) *g = gSz;
if (q != NULL) *q = qSz;
return 0;
}
int wc_DhCopyNamedKey(int name,
byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz)
{
const byte* pC = NULL;
const byte* gC = NULL;
const byte* qC = NULL;
word32 pCSz = 0, gCSz = 0, qCSz = 0;
switch (name) {
#ifdef HAVE_FFDHE_2048
case WC_FFDHE_2048:
pC = dh_ffdhe2048_p;
pCSz = sizeof(dh_ffdhe2048_p);
gC = dh_ffdhe2048_g;
gCSz = sizeof(dh_ffdhe2048_g);
#ifdef HAVE_FFDHE_Q
qC = dh_ffdhe2048_q;
qCSz = sizeof(dh_ffdhe2048_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_2048 */
#ifdef HAVE_FFDHE_3072
case WC_FFDHE_3072:
pC = dh_ffdhe3072_p;
pCSz = sizeof(dh_ffdhe3072_p);
gC = dh_ffdhe3072_g;
gCSz = sizeof(dh_ffdhe3072_g);
#ifdef HAVE_FFDHE_Q
qC = dh_ffdhe3072_q;
qCSz = sizeof(dh_ffdhe3072_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_3072 */
#ifdef HAVE_FFDHE_4096
case WC_FFDHE_4096:
pC = dh_ffdhe4096_p;
pCSz = sizeof(dh_ffdhe4096_p);
gC = dh_ffdhe4096_g;
gCSz = sizeof(dh_ffdhe4096_g);
#ifdef HAVE_FFDHE_Q
qC = dh_ffdhe4096_q;
qCSz = sizeof(dh_ffdhe4096_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_4096 */
#ifdef HAVE_FFDHE_6144
case WC_FFDHE_6144:
pC = dh_ffdhe6144_p;
pCSz = sizeof(dh_ffdhe6144_p);
gC = dh_ffdhe6144_g;
gCSz = sizeof(dh_ffdhe6144_g);
#ifdef HAVE_FFDHE_Q
qC = dh_ffdhe6144_q;
qCSz = sizeof(dh_ffdhe6144_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_6144 */
#ifdef HAVE_FFDHE_8192
case WC_FFDHE_8192:
pC = dh_ffdhe8192_p;
pCSz = sizeof(dh_ffdhe8192_p);
gC = dh_ffdhe8192_g;
gCSz = sizeof(dh_ffdhe8192_g);
#ifdef HAVE_FFDHE_Q
qC = dh_ffdhe8192_q;
qCSz = sizeof(dh_ffdhe8192_q);
#endif /* HAVE_FFDHE_Q */
break;
#endif /* HAVE_FFDHE_8192 */
default:
break;
}
if (p != NULL && pC != NULL)
XMEMCPY(p, pC, pCSz);
if (pSz != NULL)
*pSz = pCSz;
if (g != NULL && gC != NULL)
XMEMCPY(g, gC, gCSz);
if (gSz != NULL)
*gSz = gCSz;
if (q != NULL && qC != NULL)
XMEMCPY(q, qC, qCSz);
if (qSz != NULL)
*qSz = qCSz;
return 0;
}
#ifdef WOLFSSL_KEY_GEN
/* modulus_size in bits */

View File

@@ -128,7 +128,7 @@ ECC Curve Sizes:
#endif
#ifdef HAVE_ECC_ENCRYPT
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/kdf.h>
#include <wolfssl/wolfcrypt/aes.h>
#endif
@@ -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);
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
#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);
@@ -4422,13 +4427,6 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
}
#endif
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
/* validate the public key, order * pubkey = point at infinity */
if (err == MP_OKAY)
err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime,
curve->order);
#endif /* WOLFSSL_VALIDATE_KEYGEN */
if (err != MP_OKAY) {
/* clean up if failed */
#ifndef ALT_ECC_SIZE
@@ -4491,8 +4489,8 @@ int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
}
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
int flags)
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
int curve_id, int flags)
{
int err;
@@ -4702,6 +4700,24 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
return err;
}
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
int flags)
{
int err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
if (err == MP_OKAY) {
err = _ecc_validate_public_key(key, 0, 0);
}
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
if (err == MP_OKAY) {
err = _ecc_pairwise_consistency_test(key, rng);
}
#endif
return err;
}
WOLFSSL_ABI
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
{
@@ -5336,8 +5352,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
else
#endif
{
err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
key->dp->id);
err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
WC_ECC_FLAG_NONE);
}
if (err != MP_OKAY) break;
@@ -7618,6 +7634,70 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
/* Performs a Pairwise Consistency Test on an ECC key pair. */
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
{
int err = 0;
int flags = key->flags;
if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0)
flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
if (flags & WC_ECC_FLAG_COFACTOR) {
err = ecc_check_privkey_gen_helper(key);
}
if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
byte* sig;
byte* digest;
word32 sigLen, digestLen;
int dynRng = 0, res = 0;
sigLen = wc_ecc_sig_size(key);
digestLen = WC_SHA256_DIGEST_SIZE;
sig = (byte*)XMALLOC(sigLen + digestLen, NULL, DYNAMIC_TYPE_ECC);
if (sig == NULL)
return MEMORY_E;
digest = sig + sigLen;
if (rng == NULL) {
dynRng = 1;
rng = wc_rng_new(NULL, 0, NULL);
if (rng == NULL) {
XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
return MEMORY_E;
}
}
err = wc_RNG_GenerateBlock(rng, digest, digestLen);
if (!err)
err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
rng, key);
if (!err)
err = wc_ecc_verify_hash(sig, sigLen,
digest, WC_SHA256_DIGEST_SIZE, &res, key);
if (res == 0)
err = ECC_PCT_E;
if (dynRng) {
wc_rng_free(rng);
}
ForceZero(sig, sigLen + digestLen);
XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
}
if (err != 0)
err = ECC_PCT_E;
return err;
}
#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || WOLFSSL_VALIDATE_ECC_IMPORT */
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
/* validate order * pubkey = point at infinity, 0 on success */
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
@@ -7697,8 +7777,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 +7863,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 +7893,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 +7906,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 +7948,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,
@@ -8329,7 +8432,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
if ((pub != NULL) && (ret == MP_OKAY))
/* public key needed to perform key validation */
ret = ecc_check_privkey_gen_helper(key);
ret = _ecc_validate_public_key(key, 1, 1);
#endif
return ret;

View File

@@ -530,6 +530,27 @@ const char* wc_GetErrorString(int error)
case BAD_LENGTH_E:
return "Value of length parameter is invalid.";
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_E:
return "wolfcrypt DHE Pairwise Consistency Test Failure";
case ECC_PCT_E:
return "wolfcrypt ECDHE Pairwise Consistency Test Failure";
default:
return "unknown error number";

View File

@@ -1423,273 +1423,3 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags)
#endif /* !NO_HASH_WRAPPER */
#ifdef WOLFSSL_HAVE_PRF
#ifdef 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, or SHA-384 */
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
#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 */

734
wolfcrypt/src/kdf.c Normal file
View File

@@ -0,0 +1,734 @@
/* kdf.c
*
* Copyright (C) 2006-2021 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/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifndef NO_KDF
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS
#ifdef USE_WINDOWS_API
#pragma code_seg(".fipsA$m")
#pragma const_seg(".fipsB$m")
#endif
#endif
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/kdf.h>
#ifdef WOLFSSL_HAVE_PRF
#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 */
#if defined(HAVE_HKDF)
/* 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 /* HAVE_HKDF */
#ifdef WOLFSSL_WOLFSSH
/* hash union */
typedef union {
#ifndef NO_MD5
wc_Md5 md5;
#endif
#ifndef NO_SHA
wc_Sha sha;
#endif
#ifdef WOLFSSL_SHA224
wc_Sha224 sha224;
#endif
#ifndef NO_SHA256
wc_Sha256 sha256;
#endif
#ifdef WOLFSSL_SHA384
wc_Sha384 sha384;
#endif
#ifdef WOLFSSL_SHA512
wc_Sha512 sha512;
#endif
#ifdef WOLFSSL_SHA3
wc_Sha3 sha3;
#endif
} _hash;
static
int _HashInit(byte hashId, _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, _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, _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, _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;
_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 /* NO_KDF */

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

@@ -599,112 +599,87 @@ 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. */
/* Check the pair-wise consistency of the RSA key. */
static int _ifc_pairwise_consistency_test(RsaKey* key, WC_RNG* rng)
{
const char* msg = "Everyone gets Friday off.";
byte* sig;
byte* plain;
int ret = 0;
word32 msgLen, plainLen, sigLen;
msgLen = (word32)XSTRLEN(msg);
sigLen = wc_RsaEncryptSize(key);
/* Sign and verify. */
sig = (byte*)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_RSA);
if (sig == NULL) {
return MEMORY_E;
}
XMEMSET(sig, 0, sigLen);
plain = sig;
ret = wc_RsaSSL_Sign((const byte*)msg, msgLen, sig, sigLen, key, rng);
if (ret > 0) {
sigLen = (word32)ret;
ret = wc_RsaSSL_VerifyInline(sig, sigLen, &plain, key);
}
if (ret > 0) {
plainLen = (word32)ret;
ret = (msgLen != plainLen) || (XMEMCMP(plain, msg, msgLen) != 0);
}
if (ret != 0)
ret = RSA_KEY_PAIR_E;
ForceZero(sig, sigLen);
XFREE(sig, NULL, DYNAMIC_TYPE_RSA);
return ret;
}
int wc_CheckRsaKey(RsaKey* key)
{
#if defined(WOLFSSL_CRYPTOCELL)
return 0;
#endif
#ifdef WOLFSSL_SMALL_STACK
mp_int *k = NULL, *tmp = NULL;
mp_int *tmp = NULL;
WC_RNG *rng = NULL;
#else
mp_int k[1], tmp[1];
mp_int tmp[1];
WC_RNG rng[1];
#endif
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
k = (mp_int*)XMALLOC(sizeof(mp_int) * 2, NULL, DYNAMIC_TYPE_RSA);
if (k == NULL)
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (rng != NULL)
tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_RSA);
if (rng == NULL || tmp == NULL) {
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
return MEMORY_E;
tmp = k + 1;
}
#endif
if (mp_init_multi(k, tmp, NULL, NULL, NULL, NULL) != MP_OKAY)
ret = MP_INIT_E;
ret = wc_InitRng(rng);
if (ret == 0) {
if (mp_init(tmp) != MP_OKAY)
ret = MP_INIT_E;
}
if (ret == 0) {
if (key == NULL)
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
if (mp_set_int(k, 0x2342) != MP_OKAY)
ret = MP_READ_E;
}
#ifdef WOLFSSL_HAVE_SP_RSA
if (ret == 0) {
switch (mp_count_bits(&key->n)) {
#ifndef WOLFSSL_SP_NO_2048
case 2048:
ret = sp_ModExp_2048(k, &key->e, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
if (ret == 0) {
ret = sp_ModExp_2048(tmp, &key->d, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
break;
#endif /* WOLFSSL_SP_NO_2048 */
#ifndef WOLFSSL_SP_NO_3072
case 3072:
ret = sp_ModExp_3072(k, &key->e, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
if (ret == 0) {
ret = sp_ModExp_3072(tmp, &key->d, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
break;
#endif /* WOLFSSL_SP_NO_3072 */
#ifdef WOLFSSL_SP_4096
case 4096:
ret = sp_ModExp_4096(k, &key->e, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
if (ret == 0) {
ret = sp_ModExp_4096(tmp, &key->d, &key->n, tmp);
if (ret != 0)
ret = MP_EXPTMOD_E;
}
break;
#endif /* WOLFSSL_SP_4096 */
default:
/* If using only single precsision math then issue key size
* error, otherwise fall-back to multi-precision math
* calculation */
#if defined(WOLFSSL_SP_MATH)
ret = WC_KEY_SIZE_E;
#else
if (mp_exptmod_nct(k, &key->e, &key->n, tmp) != MP_OKAY)
ret = MP_EXPTMOD_E;
if (ret == 0) {
if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)
ret = MP_EXPTMOD_E;
}
#endif
break;
}
}
#else
if (ret == 0) {
if (mp_exptmod_nct(k, &key->e, &key->n, tmp) != MP_OKAY)
ret = MP_EXPTMOD_E;
}
if (ret == 0) {
if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)
ret = MP_EXPTMOD_E;
}
#endif /* WOLFSSL_HAVE_SP_RSA */
if (ret == 0) {
if (mp_cmp(k, tmp) != MP_EQ)
ret = RSA_KEY_PAIR_E;
}
if (ret == 0)
ret = _ifc_pairwise_consistency_test(key, rng);
/* Check d is less than n. */
if (ret == 0 ) {
@@ -791,9 +766,10 @@ int wc_CheckRsaKey(RsaKey* key)
mp_forcezero(tmp);
mp_clear(tmp);
mp_clear(k);
wc_FreeRng(rng);
#ifdef WOLFSSL_SMALL_STACK
XFREE(k, NULL, DYNAMIC_TYPE_RSA);
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
#endif
return ret;
@@ -4368,10 +4344,10 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
mp_clear(p);
mp_clear(q);
#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK)
#ifndef WOLFSSL_NO_RSA_KEY_CHECK
/* Perform the pair-wise consistency test on the new key. */
if (err == 0)
err = wc_CheckRsaKey(key);
err = _ifc_pairwise_consistency_test(key, rng);
#endif
if (err != 0) {

View File

@@ -2845,7 +2845,7 @@ int sp_set_bit(sp_int* a, int i)
* WOLFSSL_KEY_GEN || OPENSSL_EXTRA || !NO_RSA */
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
defined(WOLFSSL_KEY_GEN)
defined(WOLFSSL_KEY_GEN) || !defined(NO_DH)
/* Exponentiate 2 to the power of e: a = 2^e
* This is done by setting the 'e'th bit.
*
@@ -2870,7 +2870,7 @@ int sp_2expt(sp_int* a, int e)
return err;
}
#endif /* (WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY) ||
* WOLFSSL_KEY_GEN */
* WOLFSSL_KEY_GEN || !NO_DH */
/**********************
* Digit/Long functions

View File

@@ -224,6 +224,7 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\"");
#include <wolfssl/wolfcrypt/poly1305.h>
#include <wolfssl/wolfcrypt/camellia.h>
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/kdf.h>
#include <wolfssl/wolfcrypt/dh.h>
#include <wolfssl/wolfcrypt/dsa.h>
#include <wolfssl/wolfcrypt/srp.h>
@@ -392,6 +393,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 +967,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 +1484,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
@@ -11577,6 +11590,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[] =
@@ -11682,6 +11766,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;
}
@@ -15957,8 +16048,8 @@ static int dh_fips_generate_test(WC_RNG *rng)
0xec, 0x24, 0x5d, 0x78, 0x59, 0xe7, 0x8d, 0xb5,
0x40, 0x52, 0xed, 0x41
};
byte priv[256];
byte pub[256];
byte priv[sizeof q];
byte pub[sizeof p];
word32 privSz = sizeof(priv);
word32 pubSz = sizeof(pub);
@@ -16095,7 +16186,7 @@ static int dh_generate_test(WC_RNG *rng)
DhKey smallKey;
byte p[2] = { 0, 5 };
byte g[2] = { 0, 2 };
#if !defined(WOLFSSL_SP_MATH)
#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_FFDHE)
#ifdef WOLFSSL_DH_CONST
/* the table for constant DH lookup will round to the lowest byte size 21 */
byte priv[21];
@@ -16143,7 +16234,7 @@ static int dh_generate_test(WC_RNG *rng)
ERROR_OUT(-8017, exit_gen_test);
}
#if !defined(WOLFSSL_SP_MATH)
#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_FFDHE)
/* Use API. */
ret = wc_DhGenerateKeyPair(&smallKey, rng, priv, &privSz, pub, &pubSz);
#if defined(WOLFSSL_ASYNC_CRYPT)
@@ -16237,7 +16328,7 @@ static int dh_test_check_pubvalue(void)
#endif
#ifndef WC_NO_RNG
static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params)
static int dh_ffdhe_test(WC_RNG *rng, int name)
{
int ret;
word32 privSz, pubSz, privSz2, pubSz2;
@@ -16277,8 +16368,8 @@ static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params)
pubSz = FFDHE_KEY_SIZE;
pubSz2 = FFDHE_KEY_SIZE;
privSz = FFDHE_KEY_SIZE;
privSz2 = FFDHE_KEY_SIZE;
privSz = wc_DhGetNamedKeyMinSize(name);
privSz2 = privSz;
XMEMSET(key, 0, sizeof *key);
XMEMSET(key2, 0, sizeof *key2);
@@ -16292,13 +16383,12 @@ static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params)
ERROR_OUT(-8052, done);
}
ret = wc_DhSetKey(key, params->p, params->p_len, params->g, params->g_len);
ret = wc_DhSetNamedKey(key, name);
if (ret != 0) {
ERROR_OUT(-8053, done);
}
ret = wc_DhSetKey(key2, params->p, params->p_len, params->g,
params->g_len);
ret = wc_DhSetNamedKey(key2, name);
if (ret != 0) {
ERROR_OUT(-8054, done);
}
@@ -16664,12 +16754,12 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
#ifndef WC_NO_RNG
/* Specialized code for key gen when using FFDHE-2048 and FFDHE-3072. */
#ifdef HAVE_FFDHE_2048
ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe2048_Get());
ret = dh_ffdhe_test(&rng, WC_FFDHE_2048);
if (ret != 0)
ERROR_OUT(-8129, done);
#endif
#ifdef HAVE_FFDHE_3072
ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe3072_Get());
ret = dh_ffdhe_test(&rng, WC_FFDHE_3072);
if (ret != 0)
ERROR_OUT(-8130, done);
#endif
@@ -20117,6 +20207,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 **/
static 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
};
static 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
};
static 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
};
static const byte sshKdfTvSet3a[] = {
0x81, 0xF0, 0x33, 0x0E, 0xF6, 0xF0, 0x53, 0x61,
0xB3, 0x82, 0x3B, 0xFD, 0xED, 0x6E, 0x1D, 0xE9
};
static const byte sshKdfTvSet3b[] = {
0x3F, 0x6F, 0xD2, 0x06, 0x5E, 0xEB, 0x2B, 0x0B,
0x1D, 0x93, 0x19, 0x5A, 0x1F, 0xED, 0x48, 0xA5
};
static const byte sshKdfTvSet3c[] = {
0xC3, 0x54, 0x71, 0x03, 0x4E, 0x6F, 0xD6, 0x54,
0x76, 0x13, 0x17, 0x8E, 0x23, 0x43, 0x5F, 0x21
};
static const byte sshKdfTvSet3d[] = {
0x7E, 0x9D, 0x79, 0x03, 0x20, 0x90, 0xD9, 0x9F,
0x98, 0xB0, 0x15, 0x63, 0x4D, 0xD9, 0xF4, 0x62
};
static 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
};
static 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)
@@ -20695,6 +20946,7 @@ static int ecc_test_sign_vectors(WC_RNG* rng)
if (ret != 0) {
goto done;
}
wc_ecc_set_flags(&key, WC_ECC_FLAG_DEC_SIGN);
ret = wc_ecc_sign_set_k(k, sizeof(k), &key);
if (ret != 0) {
@@ -21061,6 +21313,7 @@ static int ecc_test_make_pub(WC_RNG* rng)
/* make public key for shared secret */
wc_ecc_init_ex(pub, HEAP_HINT, devId);
ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, pub);
wc_ecc_set_flags(key, WC_ECC_FLAG_COFACTOR);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &pub->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
@@ -33768,7 +34021,7 @@ static int mp_test_param(mp_int* a, mp_int* b, mp_int* r, WC_RNG* rng)
return -12766;
#endif
#if defined(WOLFSSL_KEY_GEN)
#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH)
ret = sp_2expt(NULL, 1);
if (ret != MP_VAL)
return -12767;

View File

@@ -314,6 +314,7 @@
<ClCompile Include="wolfcrypt\src\hmac.c" />
<ClCompile Include="wolfcrypt\src\idea.c" />
<ClCompile Include="wolfcrypt\src\integer.c" />
<ClCompile Include="wolfcrypt\src\kdf.c" />
<ClCompile Include="wolfcrypt\src\logging.c" />
<ClCompile Include="wolfcrypt\src\md2.c" />
<ClCompile Include="wolfcrypt\src\md4.c" />

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
@@ -82,6 +83,15 @@ struct DhKey {
#define WC_DH_TYPE_DEFINED
#endif
enum {
WC_FFDHE_2048 = 256,
WC_FFDHE_3072 = 257,
WC_FFDHE_4096 = 258,
WC_FFDHE_6144 = 259,
WC_FFDHE_8192 = 260,
};
#ifdef HAVE_PUBLIC_FFDHE
#ifdef HAVE_FFDHE_2048
WOLFSSL_API const DhParams* wc_Dh_ffdhe2048_Get(void);
#endif
@@ -97,6 +107,7 @@ WOLFSSL_API const DhParams* wc_Dh_ffdhe6144_Get(void);
#ifdef HAVE_FFDHE_8192
WOLFSSL_API const DhParams* wc_Dh_ffdhe8192_Get(void);
#endif
#endif
WOLFSSL_API int wc_InitDhKey(DhKey* key);
WOLFSSL_API int wc_InitDhKey_ex(DhKey* key, void* heap, int devId);
@@ -115,6 +126,16 @@ WOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g
word32 gSz);
WOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz,
const byte* g, word32 gSz, const byte* q, word32 qSz);
WOLFSSL_API int wc_DhSetNamedKey(DhKey* key, int name);
WOLFSSL_API int wc_DhGetNamedKeyParamSize(int name,
word32* p, word32* g, word32* q);
WOLFSSL_API word32 wc_DhGetNamedKeyMinSize(int name);
WOLFSSL_API int wc_DhCmpNamedKey(int name, int noQ,
const byte* p, word32 pSz,
const byte* g, word32 gSz,
const byte* q, word32 qSz);
WOLFSSL_API int wc_DhCopyNamedKey(int name,
byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz);
#ifdef WOLFSSL_DH_EXTRA
WOLFSSL_API int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,

View File

@@ -373,9 +373,7 @@ typedef struct {
/* ECC Flags */
enum {
WC_ECC_FLAG_NONE = 0x00,
#ifdef HAVE_ECC_CDH
WC_ECC_FLAG_COFACTOR = 0x01,
#endif
WC_ECC_FLAG_DEC_SIGN = 0x02,
};

View File

@@ -238,8 +238,15 @@ enum {
MISSING_IV = -277, /* IV was not set */
MISSING_KEY = -278, /* Key was not set */
BAD_LENGTH_E = -279, /* Value of length parameter is invalid. */
ECDSA_KAT_FIPS_E = -280, /* ECDSA KAT failure */
RSA_PAT_FIPS_E = -281, /* RSA Pairwise failure */
KDF_TLS12_KAT_FIPS_E = -282, /* TLS12 KDF KAT failure */
KDF_TLS13_KAT_FIPS_E = -283, /* TLS13 KDF KAT failure */
KDF_SSH_KAT_FIPS_E = -284, /* SSH KDF KAT failure */
DHE_PCT_E = -285, /* DHE Pairwise Consistency Test failure */
ECC_PCT_E = -286, /* ECDHE Pairwise Consistency Test failure */
WC_LAST_E = -279, /* Update this to indicate last error */
WC_LAST_E = -286, /* 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,38 @@
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_ECC_CDH,
FIPS_CAST_ECC_PRIMITIVE_Z,
FIPS_CAST_DH_PRIMITIVE_Z,
FIPS_CAST_ECDSA,
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 +80,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,31 +220,6 @@ WOLFSSL_API int wc_Shake256Hash(const byte*, word32, byte*, word32);
#endif /* !NO_HASH_WRAPPER */
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 */
};
#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);
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 __cplusplus
} /* extern "C" */
#endif

View File

@@ -30,6 +30,7 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/hash.h \
wolfssl/wolfcrypt/hc128.h \
wolfssl/wolfcrypt/hmac.h \
wolfssl/wolfcrypt/kdf.h \
wolfssl/wolfcrypt/integer.h \
wolfssl/wolfcrypt/md2.h \
wolfssl/wolfcrypt/md4.h \
@@ -146,10 +147,8 @@ if BUILD_SELFTEST
nobase_include_HEADERS+= wolfssl/wolfcrypt/selftest.h
endif
if BUILD_FIPS_V2
if BUILD_FIPS
if !BUILD_FIPS_V1
nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h
endif
if BUILD_FIPS_RAND
nobase_include_HEADERS+= wolfssl/wolfcrypt/fips.h
endif

108
wolfssl/wolfcrypt/kdf.h Normal file
View File

@@ -0,0 +1,108 @@
/* kdf.h
*
* Copyright (C) 2006-2021 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
*/
/*!
\file wolfssl/wolfcrypt/kdf.h
*/
#ifndef NO_KDF
#ifndef WOLF_CRYPT_KDF_H
#define WOLF_CRYPT_KDF_H
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
#include <wolfssl/wolfcrypt/fips.h>
#endif
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef __cplusplus
extern "C" {
#endif
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 */
};
#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);
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
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_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
#endif /* WOLF_CRYPT_KDF_H */
#endif /* NO_KDF */

View File

@@ -194,9 +194,7 @@ struct WC_RNG {
#define RNG WC_RNG
#endif
WOLFSSL_LOCAL
int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
WOLFSSL_API int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
#ifdef HAVE_WNR
@@ -235,7 +233,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,