Merge pull request #1311 from ejohnstown/rsakeygen

RSA Key Generation (FIPS 186-4)
This commit is contained in:
Chris Conlon
2018-01-15 13:26:44 -07:00
committed by GitHub
16 changed files with 461 additions and 45 deletions

2
.gitignore vendored
View File

@@ -38,7 +38,9 @@ tags
cyassl-config
wolfssl-config
cyassl.sublime*
fips.h
fips.c
fipsv2.c
fips_test.c
fips
src/async.c

View File

@@ -18,6 +18,8 @@ if test -e .git; then
# touch fips files for non fips distribution
touch ./ctaocrypt/src/fips.c
touch ./ctaocrypt/src/fips_test.c
touch ./wolfcrypt/src/fipsv2.c
touch ./wolfssl/wolfcrypt/fips.h
# touch async crypt files
touch ./wolfcrypt/src/async.c

View File

@@ -1917,8 +1917,10 @@ AC_ARG_ENABLE([fips],
[ ENABLED_FIPS=no ]
)
if test "x$ENABLED_FIPS" = "xyes"
if test "x$ENABLED_FIPS" != "xno"
then
FIPS_VERSION=$ENABLED_FIPS
ENABLED_FIPS=yes
# requires thread local storage
if test "$thread_ls_on" = "no"
then
@@ -1944,6 +1946,19 @@ then
ENABLED_DES3="yes"
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS"
# Add the FIPS flag.
AS_IF([test "x$FIPS_VERSION" = "xv2"],
[AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS_VERSION=2 -DWOLFSSL_KEY_GEN"
ENABLED_KEYGEN="yes"
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"])])
])
else
if test "x$ENABLED_FORTRESS" = "xyes"
then
@@ -1952,6 +1967,7 @@ else
fi
AM_CONDITIONAL([BUILD_FIPS], [test "x$ENABLED_FIPS" = "xyes"])
AM_CONDITIONAL([BUILD_FIPS_V2], [test "x$FIPS_VERSION" = "xv2"])
# set sha224 default

View File

@@ -45,6 +45,7 @@
#ifdef WOLFSSL_KEY_GEN
#define MakeRsaKey wc_MakeRsaKey
#define RsaKeyToDer wc_RsaKeyToDer
#define CheckProbablePrime wc_CheckProbablePrime
#endif
#ifdef WOLFSSL_ASYNC_CRYPT

View File

@@ -33,8 +33,16 @@ src_libwolfssl_la_SOURCES += \
ctaocrypt/src/sha256.c
if BUILD_RSA
if BUILD_FIPS_V2
src_libwolfssl_la_SOURCES += wolfcrypt/src/rsa.c
else
src_libwolfssl_la_SOURCES += ctaocrypt/src/rsa.c
endif
endif
if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif
if BUILD_AES
src_libwolfssl_la_SOURCES += ctaocrypt/src/aes.c
@@ -53,6 +61,7 @@ src_libwolfssl_la_SOURCES += ctaocrypt/src/sha512.c
endif
src_libwolfssl_la_SOURCES += ctaocrypt/src/fips.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/fipsv2.c
src_libwolfssl_la_SOURCES += ctaocrypt/src/fips_test.c
# fips last file
@@ -87,10 +96,12 @@ if BUILD_RSA
if BUILD_FAST_RSA
src_libwolfssl_la_SOURCES += wolfcrypt/user-crypto/src/rsa.c
else
if !BUILD_FIPS_V2
src_libwolfssl_la_SOURCES += wolfcrypt/src/rsa.c
endif
endif
endif
endif
if BUILD_SP
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp.c
endif
@@ -218,9 +229,11 @@ if BUILD_SLOWMATH
src_libwolfssl_la_SOURCES += wolfcrypt/src/integer.c
endif
if !BUILD_FIPS
if BUILD_ECC
src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c
endif
endif
if BUILD_CURVE25519
src_libwolfssl_la_SOURCES += wolfcrypt/src/curve25519.c

View File

@@ -93,6 +93,16 @@ ECC Curve Sizes:
#endif
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS
#ifdef USE_WINDOWS_API
#pragma code_seg(".fipsA$e2")
#pragma const_seg(".fipsB$e2")
#endif
#endif
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
@@ -3786,10 +3796,10 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
Free an ECC key from memory
key The key you wish to free
*/
void wc_ecc_free(ecc_key* key)
int wc_ecc_free(ecc_key* key)
{
if (key == NULL) {
return;
return 0;
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
@@ -3808,6 +3818,7 @@ void wc_ecc_free(ecc_key* key)
mp_forcezero(&key->k);
#endif /* WOLFSSL_ATECC508A */
return 0;
}
#ifdef ECC_SHAMIR

View File

@@ -443,6 +443,9 @@ const char* wc_GetErrorString(int error)
case PSS_SALTLEN_E:
return "PSS - Length of salt is too big for hash algorithm";
case PRIME_GEN_E:
return "Unable to find a prime for RSA key";
default:
return "unknown error number";

View File

@@ -29,6 +29,18 @@
#ifndef NO_RSA
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS
#ifdef USE_WINDOWS_API
#pragma code_seg(".fipsA$e")
#pragma const_seg(".fipsB$e")
#endif
#endif
#include <wolfssl/wolfcrypt/rsa.h>
#ifdef WOLFSSL_HAVE_SP_RSA
@@ -54,7 +66,10 @@ RSA Key Size Configuration:
*/
#ifdef HAVE_FIPS
/* If building for old FIPS. */
#if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
int wc_InitRsaKey(RsaKey* key, void* ptr)
{
if (key == NULL) {
@@ -64,6 +79,7 @@ int wc_InitRsaKey(RsaKey* key, void* ptr)
return InitRsaKey_fips(key, ptr);
}
int wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)
{
(void)devId;
@@ -73,6 +89,7 @@ int wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)
return InitRsaKey_fips(key, ptr);
}
int wc_FreeRsaKey(RsaKey* key)
{
return FreeRsaKey_fips(key);
@@ -154,6 +171,8 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
/* not specified as fips so not needing _fips */
return RsaFlattenPublicKey(key, a, aSz, b, bSz);
}
#ifdef WOLFSSL_KEY_GEN
int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
{
@@ -167,7 +186,7 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
* wc_RsaPublicKeyDecode
*/
#else /* else build without fips */
#else /* else build without fips, or for new fips */
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/logging.h>
@@ -2099,17 +2118,267 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
return 0;
}
static int RsaGetValue(mp_int* in, byte* out, word32* outSz)
{
word32 sz;
int ret = 0;
if (in == NULL || out == NULL || outSz == NULL)
return BAD_FUNC_ARG;
sz = (word32)mp_unsigned_bin_size(in);
if (sz > *outSz)
ret = RSA_BUFFER_E;
if (ret == 0)
ret = mp_to_unsigned_bin(in, out);
if (ret == MP_OKAY)
*outSz = sz;
return ret;
}
int wc_RsaExportKey(RsaKey* key,
byte* e, word32* eSz, byte* n, word32* nSz,
byte* d, word32* dSz, byte* p, word32* pSz,
byte* q, word32* qSz)
{
int ret = BAD_FUNC_ARG;
if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz)
ret = 0;
if (ret == 0)
ret = RsaGetValue(&key->e, e, eSz);
if (ret == 0)
ret = RsaGetValue(&key->n, n, nSz);
if (ret == 0)
ret = RsaGetValue(&key->d, d, dSz);
if (ret == 0)
ret = RsaGetValue(&key->p, p, pSz);
if (ret == 0)
ret = RsaGetValue(&key->q, q, qSz);
return ret;
}
#ifdef WOLFSSL_KEY_GEN
/* Check that |p-q| > 2^((size/2)-100) */
static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size)
{
mp_int c, d;
int ret;
if (p == NULL || q == NULL)
return BAD_FUNC_ARG;
ret = mp_init_multi(&c, &d, NULL, NULL, NULL, NULL);
/* c = 2^((size/2)-100) */
if (ret == 0)
ret = mp_2expt(&c, (size/2)-100);
/* d = |p-q| */
if (ret == 0)
ret = mp_sub(p, q, &d);
if (ret == 0)
ret = mp_abs(&d, &d);
/* compare */
if (ret == 0)
ret = mp_cmp(&d, &c);
if (ret == MP_GT)
ret = MP_OKAY;
mp_clear(&d);
mp_clear(&c);
return ret;
}
/* The lower_bound value is floor(2^(0.5) * 2^((nlen/2)-1)) where nlen is 4096.
* This number was calculated using a small test tool written with a common
* large number math library. Other values of nlen may be checked with a subset
* of lower_bound. */
static const byte lower_bound[] = {
0xB5, 0x04, 0xF3, 0x33, 0xF9, 0xDE, 0x64, 0x84,
0x59, 0x7D, 0x89, 0xB3, 0x75, 0x4A, 0xBE, 0x9F,
0x1D, 0x6F, 0x60, 0xBA, 0x89, 0x3B, 0xA8, 0x4C,
0xED, 0x17, 0xAC, 0x85, 0x83, 0x33, 0x99, 0x15,
/* 512 */
0x4A, 0xFC, 0x83, 0x04, 0x3A, 0xB8, 0xA2, 0xC3,
0xA8, 0xB1, 0xFE, 0x6F, 0xDC, 0x83, 0xDB, 0x39,
0x0F, 0x74, 0xA8, 0x5E, 0x43, 0x9C, 0x7B, 0x4A,
0x78, 0x04, 0x87, 0x36, 0x3D, 0xFA, 0x27, 0x68,
/* 1024 */
0xD2, 0x20, 0x2E, 0x87, 0x42, 0xAF, 0x1F, 0x4E,
0x53, 0x05, 0x9C, 0x60, 0x11, 0xBC, 0x33, 0x7B,
0xCA, 0xB1, 0xBC, 0x91, 0x16, 0x88, 0x45, 0x8A,
0x46, 0x0A, 0xBC, 0x72, 0x2F, 0x7C, 0x4E, 0x33,
0xC6, 0xD5, 0xA8, 0xA3, 0x8B, 0xB7, 0xE9, 0xDC,
0xCB, 0x2A, 0x63, 0x43, 0x31, 0xF3, 0xC8, 0x4D,
0xF5, 0x2F, 0x12, 0x0F, 0x83, 0x6E, 0x58, 0x2E,
0xEA, 0xA4, 0xA0, 0x89, 0x90, 0x40, 0xCA, 0x4A,
/* 2048 */
0x81, 0x39, 0x4A, 0xB6, 0xD8, 0xFD, 0x0E, 0xFD,
0xF4, 0xD3, 0xA0, 0x2C, 0xEB, 0xC9, 0x3E, 0x0C,
0x42, 0x64, 0xDA, 0xBC, 0xD5, 0x28, 0xB6, 0x51,
0xB8, 0xCF, 0x34, 0x1B, 0x6F, 0x82, 0x36, 0xC7,
0x01, 0x04, 0xDC, 0x01, 0xFE, 0x32, 0x35, 0x2F,
0x33, 0x2A, 0x5E, 0x9F, 0x7B, 0xDA, 0x1E, 0xBF,
0xF6, 0xA1, 0xBE, 0x3F, 0xCA, 0x22, 0x13, 0x07,
0xDE, 0xA0, 0x62, 0x41, 0xF7, 0xAA, 0x81, 0xC2,
/* 3072 */
0xC1, 0xFC, 0xBD, 0xDE, 0xA2, 0xF7, 0xDC, 0x33,
0x18, 0x83, 0x8A, 0x2E, 0xAF, 0xF5, 0xF3, 0xB2,
0xD2, 0x4F, 0x4A, 0x76, 0x3F, 0xAC, 0xB8, 0x82,
0xFD, 0xFE, 0x17, 0x0F, 0xD3, 0xB1, 0xF7, 0x80,
0xF9, 0xAC, 0xCE, 0x41, 0x79, 0x7F, 0x28, 0x05,
0xC2, 0x46, 0x78, 0x5E, 0x92, 0x95, 0x70, 0x23,
0x5F, 0xCF, 0x8F, 0x7B, 0xCA, 0x3E, 0xA3, 0x3B,
0x4D, 0x7C, 0x60, 0xA5, 0xE6, 0x33, 0xE3, 0xE1
/* 4096 */
};
static INLINE int RsaSizeCheck(int size)
{
switch (size) {
case 1024:
case 2048:
case 3072:
case 4096:
return 1;
}
return 0;
}
static int wc_CheckProbablePrime_ex(mp_int* p, mp_int* q, mp_int* e, int nlen,
int* isPrime)
{
int ret;
mp_int tmp1, tmp2;
mp_int* prime;
if (p == NULL || e == NULL || isPrime == NULL)
return BAD_FUNC_ARG;
if (!RsaSizeCheck(nlen))
return BAD_FUNC_ARG;
*isPrime = MP_NO;
if (q != NULL) {
/* 5.4 - check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */
ret = wc_CompareDiffPQ(p, q, nlen);
if (ret != MP_OKAY) goto notOkay;
prime = q;
}
else
prime = p;
ret = mp_init_multi(&tmp1, &tmp2, NULL, NULL, NULL, NULL);
if (ret != MP_OKAY) goto notOkay;
/* 4.4,5.5 - Check that prime >= (2^(1/2))(2^((nlen/2)-1))
* This is a comparison against lowerBound */
ret = mp_read_unsigned_bin(&tmp1, lower_bound, nlen/16);
if (ret != MP_OKAY) goto notOkay;
ret = mp_cmp(prime, &tmp1);
if (ret == MP_LT) goto exit;
/* 4.5,5.6 - Check that GCD(p-1, e) == 1 */
ret = mp_sub_d(prime, 1, &tmp1); /* tmp1 = prime-1 */
if (ret != MP_OKAY) goto notOkay;
ret = mp_gcd(&tmp1, e, &tmp2); /* tmp2 = gcd(prime-1, e) */
if (ret != MP_OKAY) goto notOkay;
ret = mp_cmp_d(&tmp2, 1);
if (ret != MP_EQ) goto exit; /* e divides p-1 */
/* 4.5.1,5.6.1 - Check primality of p with 8 iterations */
ret = mp_prime_is_prime(prime, 8, isPrime);
/* Performs some divides by a table of primes, and then does M-R,
* it sets isPrime as a side-effect. */
if (ret != MP_OKAY) goto notOkay;
exit:
ret = MP_OKAY;
notOkay:
mp_clear(&tmp1);
mp_clear(&tmp2);
return ret;
}
int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz,
const byte* qRaw, word32 qRawSz,
const byte* eRaw, word32 eRawSz,
int nlen, int* isPrime)
{
mp_int p, q, e;
mp_int* Q = NULL;
int ret;
if (pRaw == NULL || pRawSz == 0 ||
eRaw == NULL || eRawSz == 0 ||
isPrime == NULL) {
return BAD_FUNC_ARG;
}
if ((qRaw != NULL && qRawSz == 0) || (qRaw == NULL && qRawSz != 0))
return BAD_FUNC_ARG;
ret = mp_init_multi(&p, &q, &e, NULL, NULL, NULL);
if (ret == MP_OKAY)
ret = mp_read_unsigned_bin(&p, pRaw, pRawSz);
if (ret == MP_OKAY) {
if (qRaw != NULL) {
ret = mp_read_unsigned_bin(&q, qRaw, qRawSz);
if (ret == MP_OKAY)
Q = &q;
}
}
if (ret == MP_OKAY)
ret = mp_read_unsigned_bin(&e, eRaw, eRawSz);
if (ret == MP_OKAY)
ret = wc_CheckProbablePrime_ex(&p, Q, &e, nlen, isPrime);
ret = (ret == MP_OKAY) ? 0 : PRIME_GEN_E;
mp_clear(&p);
mp_clear(&q);
mp_clear(&e);
return ret;
}
/* Make an RSA key for size bits, with e specified, 65537 is a good e */
int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
{
mp_int p, q, tmp1, tmp2, tmp3;
int err;
int err, i, failCount, primeSz, isPrime;
byte* buf = NULL;
if (key == NULL || rng == NULL)
return BAD_FUNC_ARG;
if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
if (!RsaSizeCheck(size))
return BAD_FUNC_ARG;
if (e < 3 || (e & 1) == 0)
@@ -2134,35 +2403,89 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
}
#endif
if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
return err;
err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL);
err = mp_set_int(&tmp3, e);
if (err == MP_OKAY)
err = mp_set_int(&tmp3, e);
/* The failCount value comes from NIST FIPS 186-4, section B.3.3,
* process steps 4.7 and 5.8. */
failCount = 5 * (size / 2);
primeSz = size / 16; /* size is the size of n in bits.
primeSz is in bytes. */
/* allocate buffer to work with */
if (err == MP_OKAY) {
buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA);
if (buf == NULL)
err = MEMORY_E;
}
/* make p */
if (err == MP_OKAY) {
isPrime = 0;
i = 0;
do {
err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
#ifdef SHOW_GEN
printf(".");
fflush(stdout);
#endif
/* generate value */
err = wc_RNG_GenerateBlock(rng, buf, primeSz);
if (err == 0) {
/* prime lower bound has the MSB set, set it in candidate */
buf[0] |= 0x80;
/* make candidate odd */
buf[primeSz-1] |= 0x01;
/* load value */
err = mp_read_unsigned_bin(&p, buf, primeSz);
}
if (err == MP_OKAY)
err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
err = wc_CheckProbablePrime_ex(&p, NULL, &tmp3, size, &isPrime);
if (err == MP_OKAY)
err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */
} while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divides p-1 */
i++;
} while (err == MP_OKAY && !isPrime && i < failCount);
}
if (err == MP_OKAY && !isPrime)
err = PRIME_GEN_E;
/* make q */
if (err == MP_OKAY) {
isPrime = 0;
i = 0;
do {
err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
#ifdef SHOW_GEN
printf(".");
fflush(stdout);
#endif
/* generate value */
err = wc_RNG_GenerateBlock(rng, buf, primeSz);
if (err == 0) {
/* prime lower bound has the MSB set, set it in candidate */
buf[0] |= 0x80;
/* make candidate odd */
buf[primeSz-1] |= 0x01;
/* load value */
err = mp_read_unsigned_bin(&q, buf, primeSz);
}
if (err == MP_OKAY)
err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */
err = wc_CheckProbablePrime_ex(&p, &q, &tmp3, size, &isPrime);
if (err == MP_OKAY)
err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */
} while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divides q-1 */
i++;
} while (err == MP_OKAY && !isPrime && i < failCount);
}
if (err == MP_OKAY && !isPrime)
err = PRIME_GEN_E;
if (buf) {
ForceZero(buf, primeSz);
XFREE(buf, key->heap, DYNAMIC_TYPE_RSA);
}
if (err == MP_OKAY)
@@ -2172,35 +2495,32 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
if (err == MP_OKAY)
err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */
err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
if (err == MP_OKAY)
err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */
err = mp_sub_d(&q, 1, &tmp2); /* tmp2 = q-1 */
if (err == MP_OKAY)
err = mp_lcm(&tmp1, &tmp2, &tmp3); /* tmp3 = lcm(p-1, q-1),last loop */
/* make key */
if (err == MP_OKAY)
err = mp_set_int(&key->e, (mp_digit)e); /* key->e = e */
if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */
err = mp_invmod(&key->e, &tmp1, &key->d);
err = mp_invmod(&key->e, &tmp3, &key->d);
if (err == MP_OKAY)
err = mp_mul(&p, &q, &key->n); /* key->n = pq */
if (err == MP_OKAY)
err = mp_sub_d(&p, 1, &tmp1);
err = mp_mod(&key->d, &tmp1, &key->dP); /* key->dP = d mod(p-1) */
if (err == MP_OKAY)
err = mp_sub_d(&q, 1, &tmp2);
err = mp_mod(&key->d, &tmp2, &key->dQ); /* key->dQ = d mod(q-1) */
if (err == MP_OKAY)
err = mp_mod(&key->d, &tmp1, &key->dP);
if (err == MP_OKAY)
err = mp_mod(&key->d, &tmp2, &key->dQ);
if (err == MP_OKAY)
err = mp_invmod(&q, &p, &key->u);
err = mp_invmod(&q, &p, &key->u); /* key->u = 1/q mod p */
if (err == MP_OKAY)
err = mp_copy(&p, &key->p);
@@ -2211,11 +2531,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
if (err == MP_OKAY)
key->type = RSA_PRIVATE;
mp_clear(&tmp3);
mp_clear(&tmp2);
mp_clear(&tmp1);
mp_clear(&q);
mp_clear(&tmp2);
mp_clear(&tmp3);
mp_clear(&p);
mp_clear(&q);
if (err != MP_OKAY) {
wc_FreeRsaKey(key);

View File

@@ -2455,6 +2455,12 @@ int mp_mul_2d(fp_int *a, int b, fp_int *c)
return MP_OKAY;
}
int mp_2expt(fp_int* a, int b)
{
fp_2expt(a, b);
return MP_OKAY;
}
int mp_div(fp_int * a, fp_int * b, fp_int * c, fp_int * d)
{
return fp_div(a, b, c, d);
@@ -3394,6 +3400,13 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
int mp_abs(mp_int* a, mp_int* b)
{
fp_abs(a, b);
return FP_OKAY;
}
int mp_lshd (mp_int * a, int b)
{
fp_lshd(a, b);

View File

@@ -7558,7 +7558,8 @@ static int rsa_flatten_test(RsaKey* key)
* -101 = USER_CRYPTO_ERROR
*/
if (ret == 0)
#elif defined(HAVE_FIPS)
#elif defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
if (ret != 0)
#else
if (ret != RSA_BUFFER_E)
@@ -8358,7 +8359,8 @@ int rsa_test(void)
#ifndef WC_NO_RSA_OAEP
/* OAEP padding testing */
#if !defined(HAVE_FAST_RSA) && !defined(HAVE_USER_RSA) && \
!defined(HAVE_FIPS)
(!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
#ifndef NO_SHA
XMEMSET(plain, 0, plainSz);
@@ -8704,11 +8706,17 @@ int rsa_test(void)
#ifdef WOLFSSL_KEY_GEN
{
int derSz = 0;
int keySz = 1024;
#ifdef HAVE_FIPS
keySz = 2048;
#endif /* HAVE_FIPS */
ret = wc_InitRsaKey(&genKey, HEAP_HINT);
if (ret != 0) {
ERROR_OUT(-5550, exit_rsa);
}
ret = wc_MakeRsaKey(&genKey, 1024, WC_RSA_EXPONENT, &rng);
ret = wc_MakeRsaKey(&genKey, keySz, WC_RSA_EXPONENT, &rng);
if (ret != 0) {
ERROR_OUT(-5551, exit_rsa);
}

View File

@@ -30,7 +30,8 @@
#include <wolfssl/wolfcrypt/integer.h>
/* fips declare of RsaPrivateKeyDecode @wc_fips */
#if defined(HAVE_FIPS) && !defined(NO_RSA)
#if defined(HAVE_FIPS) && !defined(NO_RSA) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
#include <cyassl/ctaocrypt/rsa.h>
#endif

View File

@@ -27,6 +27,10 @@
#ifdef HAVE_ECC
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
#include <wolfssl/wolfcrypt/fips.h>
#endif /* HAVE_FIPS_VERSION >= 2 */
#include <wolfssl/wolfcrypt/integer.h>
#include <wolfssl/wolfcrypt/random.h>
@@ -387,7 +391,7 @@ int wc_ecc_init(ecc_key* key);
WOLFSSL_API
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId);
WOLFSSL_API
void wc_ecc_free(ecc_key* key);
int wc_ecc_free(ecc_key* key);
WOLFSSL_API
int wc_ecc_set_flags(ecc_key* key, word32 flags);
WOLFSSL_API

View File

@@ -195,8 +195,9 @@ enum {
WC_HW_WAIT_E = -249, /* Hardware waiting on resource */
PSS_SALTLEN_E = -250, /* PSS length of salt is to long for hash */
PRIME_GEN_E = -251, /* Failure finding a prime. */
WC_LAST_E = -250, /* Update this to indicate last error */
WC_LAST_E = -251, /* 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

@@ -20,6 +20,7 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/fe_operations.h \
wolfssl/wolfcrypt/ge_operations.h \
wolfssl/wolfcrypt/error-crypt.h \
wolfssl/wolfcrypt/fips.h \
wolfssl/wolfcrypt/fips_test.h \
wolfssl/wolfcrypt/hash.h \
wolfssl/wolfcrypt/hc128.h \

View File

@@ -39,7 +39,8 @@
#include "user_rsa.h"
#else
#ifdef HAVE_FIPS
#if defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
/* for fips @wc_fips */
#include <cyassl/ctaocrypt/rsa.h>
#if defined(CYASSL_KEY_GEN) && !defined(WOLFSSL_KEY_GEN)
@@ -48,7 +49,11 @@
#else
#include <wolfssl/wolfcrypt/integer.h>
#include <wolfssl/wolfcrypt/random.h>
#endif /* HAVE_FIPS */
#endif /* HAVE_FIPS && HAVE_FIPS_VERION 1 */
#if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
#include <wolfssl/wolfcrypt/fips.h>
#endif
/* header file needed for OAEP padding */
#include <wolfssl/wolfcrypt/hash.h>
@@ -62,7 +67,8 @@
#endif
/* avoid redefinition of structs */
#if !defined(HAVE_FIPS)
#if !defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
@@ -180,7 +186,9 @@ WOLFSSL_API int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inLen,
WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key);
#ifndef HAVE_FIPS /* to avoid asn duplicate symbols @wc_fips */
#if !defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
/* to avoid asn duplicate symbols @wc_fips */
WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
RsaKey*, word32);
WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
@@ -222,10 +230,20 @@ WOLFSSL_API int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen,
#endif /* HAVE_FIPS*/
WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*,
word32*);
WOLFSSL_API int wc_RsaExportKey(RsaKey* key,
byte* e, word32* eSz,
byte* n, word32* nSz,
byte* d, word32* dSz,
byte* p, word32* pSz,
byte* q, word32* qSz);
#ifdef WOLFSSL_KEY_GEN
WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen);
WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng);
WOLFSSL_API int wc_CheckProbablePrime(const byte* p, word32 pSz,
const byte* q, word32 qSz,
const byte* e, word32 eSz,
int nlen, int* isPrime);
#endif
#endif /* HAVE_USER_RSA */

View File

@@ -672,6 +672,7 @@ MP_API int mp_mod(mp_int *a, mp_int *b, mp_int *c);
MP_API int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
MP_API int mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y);
MP_API int mp_mul_2d(mp_int *a, int b, mp_int *c);
MP_API int mp_2expt(mp_int* a, int b);
MP_API int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
@@ -736,6 +737,7 @@ MP_API int mp_cnt_lsb(fp_int *a);
MP_API int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);
MP_API int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c);
MP_API int mp_lshd (mp_int * a, int b);
MP_API int mp_abs(mp_int* a, mp_int* b);
WOLFSSL_API word32 CheckRunTimeFastMath(void);