Minimal implementation of MP when using SP.

--enable-sp-math to include minimal implementation of MP (only with
--enable-sp.)
Add futher functionality for ECC (conditionally compiled):
- check key
- is point on curve
- API to add and double projective points
- API to map from project to affine
- Uncompress point (including sqrt)
Some configuration options will not work with SP math - configure.ac
detects this and errors out.
Change test code to better support SP sizes only.
This commit is contained in:
Sean Parkinson
2018-02-08 15:50:17 +10:00
parent 172989c3c4
commit a3a4f2d59c
17 changed files with 2806 additions and 107 deletions

View File

@ -425,6 +425,39 @@ AC_ARG_ENABLE([haproxy],
[ ENABLED_HAPROXY=no ]
)
# wpa_supplicant support
AC_ARG_ENABLE([wpas],
[AS_HELP_STRING([--enable-wpas],[Enable wpa_supplicant support (default: disabled)])],
[ ENABLED_WPAS=$enableval ],
[ ENABLED_WPAS=no ]
)
# Fortress build
AC_ARG_ENABLE([fortress],
[AS_HELP_STRING([--enable-fortress],[Enable SSL fortress build (default: disabled)])],
[ ENABLED_FORTRESS=$enableval ],
[ ENABLED_FORTRESS=no ]
)
if test "$ENABLED_OPENSSH" = "yes"
then
ENABLED_FORTRESS="yes"
fi
# ssl bump build
AC_ARG_ENABLE([bump],
[AS_HELP_STRING([--enable-bump],[Enable SSL Bump build (default: disabled)])],
[ ENABLED_BUMP=$enableval ],
[ ENABLED_BUMP=no ]
)
# SNIFFER
AC_ARG_ENABLE([sniffer],
[AS_HELP_STRING([--enable-sniffer],[Enable wolfSSL sniffer support (default: disabled)])],
[ ENABLED_SNIFFER=$enableval ],
[ ENABLED_SNIFFER=no ]
)
# signal compatibility build
AC_ARG_ENABLE([signal],
[AS_HELP_STRING([--enable-signal],[Enable signal (default: disabled)])],
@ -453,7 +486,7 @@ AC_ARG_ENABLE([opensslextra],
[ ENABLED_OPENSSLEXTRA=$enableval ],
[ ENABLED_OPENSSLEXTRA=no ]
)
if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_SIGNAL" = "yes"
if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_SIGNAL" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_FORTRESS" = "yes" || test "$ENABLED_BUMP" = "yes" || test "$ENABLED_SNIFFER" = "yes"
then
ENABLED_OPENSSLEXTRA="yes"
fi
@ -506,53 +539,28 @@ fi
AM_CONDITIONAL([BUILD_IPV6], [test "x$ENABLED_IPV6" = "xyes"])
# wpa_supplicant support
AC_ARG_ENABLE([wpas],
[AS_HELP_STRING([--enable-wpas],[Enable wpa_supplicant support (default: disabled)])],
[ ENABLED_WPAS=$enableval ],
[ ENABLED_WPAS=no ]
)
if test "$ENABLED_WPAS" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_SECRET_CALLBACK -DWOLFSSL_STATIC_RSA"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PUBLIC_MP -DWOLFSSL_PUBLIC_ECC_ADD_DBL"
AM_CFLAGS="$AM_CFLAGS -DATOMIC_USER -DHAVE_EX_DATA -DWOLFSSL_KEEP_PEER_CERT"
AM_CFLAGS="$AM_CFLAGS -DHAVE_EXT_CACHE"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_VERIFY_CB -DOPENSSL_EXTRA"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_VERIFY_CB"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DWOLFSSL_DER_LOAD"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KEY_GEN"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WPAS"
fi
# Fortress build
AC_ARG_ENABLE([fortress],
[AS_HELP_STRING([--enable-fortress],[Enable SSL fortress build (default: disabled)])],
[ ENABLED_FORTRESS=$enableval ],
[ ENABLED_FORTRESS=no ]
)
if test "$ENABLED_OPENSSH" = "yes"
then
ENABLED_FORTRESS="yes"
fi
if test "$ENABLED_FORTRESS" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DFORTRESS -DWOLFSSL_ALWAYS_VERIFY_CB -DOPENSSL_EXTRA -DWOLFSSL_AES_COUNTER -DWOLFSSL_AES_DIRECT -DWOLFSSL_DER_LOAD -DWOLFSSL_KEY_GEN"
AM_CFLAGS="$AM_CFLAGS -DFORTRESS -DWOLFSSL_ALWAYS_VERIFY_CB -DWOLFSSL_AES_COUNTER -DWOLFSSL_AES_DIRECT -DWOLFSSL_DER_LOAD -DWOLFSSL_KEY_GEN"
fi
# ssl bump build
AC_ARG_ENABLE([bump],
[AS_HELP_STRING([--enable-bump],[Enable SSL Bump build (default: disabled)])],
[ ENABLED_BUMP=$enableval ],
[ ENABLED_BUMP=no ]
)
if test "$ENABLED_BUMP" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DLARGE_STATIC_BUFFERS -DWOLFSSL_CERT_GEN -DWOLFSSL_KEY_GEN -DHUGE_SESSION_CACHE -DOPENSSL_EXTRA -DFP_MAX_BITS=8192 -DWOLFSSL_DER_LOAD -DWOLFSSL_ALT_NAMES -DWOLFSSL_TEST_CERT"
AM_CFLAGS="$AM_CFLAGS -DLARGE_STATIC_BUFFERS -DWOLFSSL_CERT_GEN -DWOLFSSL_KEY_GEN -DHUGE_SESSION_CACHE -DFP_MAX_BITS=8192 -DWOLFSSL_DER_LOAD -DWOLFSSL_ALT_NAMES -DWOLFSSL_TEST_CERT"
fi
ENABLED_SLOWMATH="yes"
@ -716,13 +724,6 @@ fi
AM_CONDITIONAL([BUILD_PKCALLBACKS], [ test "x$ENABLED_PKCALLBACKS" = "xyes" ])
# SNIFFER
AC_ARG_ENABLE([sniffer],
[AS_HELP_STRING([--enable-sniffer],[Enable wolfSSL sniffer support (default: disabled)])],
[ ENABLED_SNIFFER=$enableval ],
[ ENABLED_SNIFFER=no ]
)
# sniffer doesn't work in maxstrength mode
if test "$ENABLED_SNIFFER" = "yes" && test "$ENABLED_MAXSTRENGTH" = "yes"
then
@ -732,7 +733,7 @@ fi
ENABLED_SNIFFTEST=no
AS_IF([ test "x$ENABLED_SNIFFER" = "xyes" ],
[
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SNIFFER -DOPENSSL_EXTRA"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SNIFFER"
AC_CHECK_HEADERS([pcap/pcap.h],
[ ENABLED_SNIFFTEST=yes ],
[ AC_MSG_WARN([cannot enable sniffer test without having libpcap available.]) ]
@ -2191,7 +2192,6 @@ AC_ARG_ENABLE([ocspstapling],
if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_WPAS" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes"
then
echo "ELLO"
ENABLED_CERTIFICATE_STATUS_REQUEST="yes"
fi
@ -3313,6 +3313,9 @@ AC_ARG_ENABLE([sp],
[ ENABLED_SP=no ],
)
ENABLED_SP_RSA=no
ENABLED_SP_DH=no
ENABLED_SP_ECC=no
for v in `echo $ENABLED_SP | tr "," " "`
do
case $v in
@ -3403,6 +3406,38 @@ if test "$ENABLED_ECC" = "yes" && test "$ENABLED_SP_ECC" = "yes"; then
fi
AM_CONDITIONAL([BUILD_SP], [test "x$ENABLED_SP" = "xyes"])
AC_ARG_ENABLE([sp-math],
[AS_HELP_STRING([--enable-sp-math],[Enable Single Precision math implementation only (default: disabled)])],
[ ENABLED_SP_MATH=$enableval ],
[ ENABLED_SP_MATH=no ],
)
if test "$ENABLED_SP_MATH" = "yes"; then
if test "$ENABLED_SP" = "no"; then
AC_MSG_ERROR([Must have SP enabled: --enable-sp])
fi
if test "$ENABLED_ECCCUSTCURVES" = "yes"; then
AC_MSG_ERROR([Cannot use single precision math and custom curves])
fi
if test "$ENABLED_OPENSSLEXTRA" = "yes"; then
AC_MSG_ERROR([Cannot use single precision math and OpenSSL extra])
fi
if test "$ENABLED_DSA" = "yes"; then
AC_MSG_ERROR([Cannot use single precision math and DSA])
fi
if test "$ENABLED_SRP" = "yes"; then
AC_MSG_ERROR([Cannot use single precision math and SRP])
fi
if test "$ENABLED_SP_RSA" = "no" && test "$ENABLED_RSA" = "yes"; then
AC_MSG_ERROR([Cannot use P256 single precision only math and RSA])
fi
if test "$ENABLED_SP_DH" = "no" && test "$ENABLED_DH" = "yes"; then
AC_MSG_ERROR([Cannot use P256 single precision only math and DH])
fi
fi
if test "$ENABLED_SP_MATH" = "yes"; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_MATH"
fi
# Fast RSA using Intel IPP
ippdir="${srcdir}/IPP"
ipplib="lib" # if autoconf guesses 32bit system changes lib directory
@ -3834,6 +3869,9 @@ then
fi
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_WOLFSCEP"
fi
if test "$ENABLED_SP_MATH" = "yes" && test "$ENABLED_KEYGEN" = "yes"; then
AC_MSG_ERROR([Cannot use single precision math and key generation])
fi
if test "x$ENABLED_PKCS7" = "xyes"
then

View File

@ -2228,10 +2228,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
WOLFSSL_ECC_SECP256R1) != WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
if (wolfSSL_UseKeyShare(sslResume,
WOLFSSL_ECC_SECP384R1) != WOLFSSL_SUCCESS) {
err_sys("unable to use curve secp384r1");
}
#endif
#endif
#ifdef HAVE_FFDHE_2048
if (wolfSSL_UseKeyShare(sslResume, WOLFSSL_FFDHE_2048) != WOLFSSL_SUCCESS) {

View File

@ -104,6 +104,7 @@ endif
endif
if BUILD_SP
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/sp_int.c
endif
if BUILD_AES

View File

@ -21495,7 +21495,8 @@ int wolfSSL_RAND_write_file(const char* fname)
#ifndef WOLFSSL_SMALL_STACK
unsigned char buf[1024];
#else
unsigned char* buf = XMALLOC(1024, NULL, DYNAMIC_TYPE_TMP_BUFFER);
unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL) {
WOLFSSL_MSG("malloc failed");
return SSL_FAILURE;

View File

@ -44,36 +44,70 @@
#ifndef ECC_PRIV_KEY_BUF
#define ECC_PRIV_KEY_BUF 66 /* For non user defined curves. */
#endif
/* ecc key sizes: 14, 16, 20, 24, 28, 30, 32, 40, 48, 64*/
#ifndef KEY14
#define KEY14 14
#endif
#if !defined(KEY16)
#define KEY16 16
#endif
#if !defined(KEY20)
#define KEY20 20
#endif
#if !defined(KEY24)
#define KEY24 24
#endif
#if !defined(KEY28)
#define KEY28 28
#endif
#if !defined(KEY30)
#define KEY30 30
#endif
#if !defined(KEY32)
#define KEY32 32
#endif
#if !defined(KEY40)
#define KEY40 40
#endif
#if !defined(KEY48)
#define KEY48 48
#endif
#if !defined(KEY64)
#define KEY64 64
#ifdef HAVE_ALL_CURVES
/* ecc key sizes: 14, 16, 20, 24, 28, 30, 32, 40, 48, 64*/
#ifndef KEY14
#define KEY14 14
#endif
#if !defined(KEY16)
#define KEY16 16
#endif
#if !defined(KEY20)
#define KEY20 20
#endif
#if !defined(KEY24)
#define KEY24 24
#endif
#if !defined(KEY28)
#define KEY28 28
#endif
#if !defined(KEY30)
#define KEY30 30
#endif
#if !defined(KEY32)
#define KEY32 32
#endif
#if !defined(KEY40)
#define KEY40 40
#endif
#if !defined(KEY48)
#define KEY48 48
#endif
#if !defined(KEY64)
#define KEY64 64
#endif
#else
/* ecc key sizes: 14, 16, 20, 24, 28, 30, 32, 40, 48, 64*/
#ifndef KEY14
#define KEY14 32
#endif
#if !defined(KEY16)
#define KEY16 32
#endif
#if !defined(KEY20)
#define KEY20 32
#endif
#if !defined(KEY24)
#define KEY24 32
#endif
#if !defined(KEY28)
#define KEY28 32
#endif
#if !defined(KEY30)
#define KEY30 32
#endif
#if !defined(KEY32)
#define KEY32 32
#endif
#if !defined(KEY40)
#define KEY40 32
#endif
#if !defined(KEY48)
#define KEY48 32
#endif
#if !defined(KEY64)
#define KEY64 32
#endif
#endif
#if !defined(HAVE_COMP_KEY)
#if !defined(NOCOMP)
@ -11681,7 +11715,6 @@ static int test_wc_ed25519_exportKey (void)
} /* END test_wc_ed25519_exportKey */
/*
* Testing wc_ecc_make_key.
*/
@ -12472,10 +12505,20 @@ static int test_wc_ecc_import_raw (void)
#ifdef HAVE_ECC
ecc_key key;
#ifdef HAVE_ALL_CURVES
const char* qx = "07008ea40b08dbe76432096e80a2494c94982d2d5bcf98e6";
const char* qy = "76fab681d00b414ea636ba215de26d98c41bd7f2e4d65477";
const char* d = "e14f37b3d1374ff8b03f41b9b3fdd2f0ebccf275d660d7f3";
const char* curveName = "SECP192R1";
#else
const char* qx =
"6c450448386596485678dcf46ccf75e80ff292443cddab1ff216d0c72cd9341";
const char* qy =
"9cac72ff8a90e4939e37714bfa07ae4612588535c3fdeab63ceb29b1d80f0d1";
const char* d =
"1e1dd938e15bdd036b0b0e2a6dc62fe7b46dbe042ac42310c6d5db0cda63e807";
const char* curveName = "SECP256R1";
#endif
ret = wc_ecc_init(&key);
@ -13108,8 +13151,8 @@ static int test_wc_ecc_shared_secret_ssh (void)
#if defined(HAVE_ECC) && defined(HAVE_ECC_DHE)
ecc_key key, key2;
WC_RNG rng;
int keySz = 32;
int key2Sz = 24;
int keySz = KEY32;
int key2Sz = KEY24;
byte secret[keySz];
word32 secretLen = keySz;

View File

@ -612,8 +612,10 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
byte* pub, word32* pubSz)
{
int ret = 0;
#ifndef WOLFSSL_SP_MATH
mp_int x;
mp_int y;
#endif
#ifdef WOLFSSL_HAVE_SP_DH
#ifndef WOLFSSL_SP_NO_2048
@ -626,6 +628,7 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
#endif
#endif
#ifndef WOLFSSL_SP_MATH
if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
return MP_INIT_E;
@ -643,6 +646,9 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
mp_clear(&y);
mp_clear(&x);
#else
ret = WC_KEY_SIZE_E;
#endif
return ret;
}
@ -734,6 +740,7 @@ int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
{
int ret = 0;
#ifndef WOLFSSL_SP_MATH
mp_int x;
mp_int y;
@ -767,6 +774,11 @@ int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
mp_clear(&y);
mp_clear(&x);
#else
(void)key;
(void)pub;
(void)pubSz;
#endif
return ret;
}
@ -800,9 +812,11 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
{
int ret = 0;
mp_int x;
mp_int y;
#ifndef WOLFSSL_SP_MATH
mp_int x;
mp_int z;
#endif
if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
@ -842,6 +856,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
#endif
#endif
#ifndef WOLFSSL_SP_MATH
if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
return MP_INIT_E;
@ -863,6 +878,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
mp_clear(&z);
mp_clear(&y);
mp_forcezero(&x);
#endif
return ret;
}

View File

@ -133,7 +133,9 @@ ECC Curve Sizes:
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif
#ifdef USE_FAST_MATH
#ifdef WOLFSSL_SP_MATH
#define GEN_MEM_ERR MP_MEM
#elif defined(USE_FAST_MATH)
#define GEN_MEM_ERR FP_MEM
#else
#define GEN_MEM_ERR MP_MEM
@ -979,12 +981,14 @@ static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
typedef void* ecc_curve_spec;
#else
#ifndef WOLFSSL_SP_MATH
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
mp_int* prime, mp_int* order);
#ifdef ECC_SHAMIR
static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
ecc_point* C, mp_int* a, mp_int* modulus, void* heap);
#endif
#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);
@ -1314,6 +1318,8 @@ static void alt_fp_init(fp_int* a)
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
/**
Add two ECC points
P The point to add
@ -1327,6 +1333,7 @@ static void alt_fp_init(fp_int* a)
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
mp_int* a, mp_int* modulus, mp_digit mp)
{
#ifndef WOLFSSL_SP_MATH
mp_int t1, t2;
#ifdef ALT_ECC_SIZE
mp_int rx, ry, rz;
@ -1589,6 +1596,17 @@ done:
mp_clear(&t2);
return err;
#else
if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
return ECC_BAD_ARG_E;
}
(void)a;
(void)mp;
return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
R->x, R->y, R->z);
#endif
}
/* ### Point doubling in Jacobian coordinate system ###
@ -1621,6 +1639,7 @@ done:
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
mp_int* modulus, mp_digit mp)
{
#ifndef WOLFSSL_SP_MATH
mp_int t1, t2;
#ifdef ALT_ECC_SIZE
mp_int rx, ry, rz;
@ -1857,6 +1876,15 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
mp_clear(&t2);
return err;
#else
if (P == NULL || R == NULL || modulus == NULL)
return ECC_BAD_ARG_E;
(void)a;
(void)mp;
return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
#endif
}
@ -1869,6 +1897,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
*/
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
{
#ifndef WOLFSSL_SP_MATH
mp_int t1, t2;
#ifdef ALT_ECC_SIZE
mp_int rx, ry, rz;
@ -1967,10 +1996,21 @@ done:
mp_clear(&t2);
return err;
#else
if (P == NULL || modulus == NULL)
return ECC_BAD_ARG_E;
(void)mp;
return sp_ecc_map_256(P->x, P->y, P->z);
#endif
}
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
#if !defined(FREESCALE_LTC_ECC)
#if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
/**
Perform a point multiplication
k The scalar to multiply by
@ -1992,6 +2032,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
void* heap)
#endif
{
#ifndef WOLFSSL_SP_MATH
#ifndef ECC_TIMING_RESISTANT
/* size of sliding window, don't change this! */
#define WINSIZE 4
@ -2326,8 +2367,19 @@ exit:
}
return err;
#else
if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
return ECC_BAD_ARG_E;
}
(void)a;
return sp_ecc_mulmod_256(k, G, R, map, heap);
#endif
}
#endif /* !FP_ECC || !WOLFSSL_SP_MATH */
#endif /* !FREESCALE_LTC_ECC */
/** ECC Fixed Point mulmod global
@ -2737,8 +2789,10 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
byte* out, word32* outlen, ecc_curve_spec* curve)
{
int err;
#ifndef WOLFSSL_SP_MATH
ecc_point* result = NULL;
word32 x = 0;
#endif
mp_int* k = &private_key->k;
#ifdef HAVE_ECC_CDH
mp_int k_lcl;
@ -2770,6 +2824,11 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
else
#endif
#endif
#ifdef WOLFSSL_SP_MATH
err = WC_KEY_SIZE_E;
(void)curve;
#else
{
/* make new point */
result = wc_ecc_new_point_h(private_key->heap);
@ -2799,6 +2858,7 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
wc_ecc_del_point_h(result, private_key->heap);
}
#endif
#ifdef HAVE_ECC_CDH
if (k == &k_lcl)
mp_clear(k);
@ -2959,6 +3019,7 @@ int wc_ecc_point_is_at_infinity(ecc_point* p)
return 0;
}
#ifndef WOLFSSL_SP_MATH
/* generate random and ensure its greater than 0 and less than order */
static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
{
@ -3006,6 +3067,7 @@ static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
return err;
}
#endif
#endif /* !WOLFSSL_ATECC508A */
static INLINE void wc_ecc_reset(ecc_key* key)
@ -3033,7 +3095,9 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
{
int err = MP_OKAY;
#ifndef WOLFSSL_ATECC508A
#ifndef WOLFSSL_SP_MATH
ecc_point* base = NULL;
#endif
ecc_point* pub;
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
#endif
@ -3087,6 +3151,9 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
else
#endif
#endif
#ifdef WOLFSSL_SP_MATH
err = WC_KEY_SIZE_E;
#else
{
if (err == MP_OKAY) {
base = wc_ecc_new_point_h(key->heap);
@ -3109,6 +3176,7 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
wc_ecc_del_point_h(base, key->heap);
}
#endif
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
/* validate the public key, order * pubkey = point at infinity */
@ -3220,6 +3288,9 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
else
#endif
#endif
#ifdef WOLFSSL_SP_MATH
err = WC_KEY_SIZE_E;
#else
{
/* setup the key variables */
err = mp_init(&key->k);
@ -3248,6 +3319,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
/* cleanup allocations */
wc_ecc_curve_free(curve);
}
#endif
#endif /* WOLFSSL_ATECC508A */
@ -3613,7 +3685,9 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
ecc_key* key, mp_int *r, mp_int *s)
{
int err;
#ifndef WOLFSSL_SP_MATH
mp_int e;
#endif
DECLARE_CURVE_SPECS(1)
if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
@ -3629,6 +3703,12 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
return ECC_BAD_ARG_E;
}
#ifdef WOLFSSL_SP_MATH
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
else
return WC_KEY_SIZE_E;
#else
#ifdef WOLFSSL_HAVE_SP_ECC
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
defined(WOLFSSL_ASYNC_CRYPT_TEST)
@ -3786,6 +3866,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
mp_clear(&e);
wc_ecc_curve_free(curve);
#endif
return err;
}
@ -3821,6 +3902,7 @@ int wc_ecc_free(ecc_key* key)
return 0;
}
#ifndef WOLFSSL_SP_MATH
#ifdef ECC_SHAMIR
/** Computes kA*A + kB*B = C using Shamir's Trick
@ -4045,6 +4127,7 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA,
}
#endif /* ECC_SHAMIR */
#endif
#ifdef HAVE_ECC_VERIFY
@ -4165,6 +4248,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
{
int err;
#ifndef WOLFSSL_ATECC508A
#ifndef WOLFSSL_SP_MATH
int did_init = 0;
ecc_point *mG = NULL, *mQ = NULL;
mp_int v;
@ -4173,6 +4257,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
mp_int u2;
mp_int e;
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
#endif
#else
byte sigRS[ATECC_KEY_SIZE*2];
#endif
@ -4232,6 +4317,14 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
}
}
#ifdef WOLFSSL_SP_MATH
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
key->pubkey.z, r, s, res, key->heap);
}
else
return WC_KEY_SIZE_E;
#else
#ifdef WOLFSSL_HAVE_SP_ECC
#ifndef WOLFSSL_SP_NO_256
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
@ -4414,6 +4507,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
wc_ecc_curve_free(curve);
#endif
#endif /* WOLFSSL_ATECC508A */
return err;
@ -4476,6 +4570,7 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
#ifdef HAVE_COMP_KEY
if (err == MP_OKAY && compressed == 1) { /* build y */
#ifndef WOLFSSL_SP_MATH
int did_init = 0;
mp_int t1, t2;
DECLARE_CURVE_SPECS(3)
@ -4528,6 +4623,9 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
}
wc_ecc_curve_free(curve);
#else
sp_ecc_uncompress_256(point->x, in[0], point->y);
#endif
}
#endif
@ -4726,6 +4824,7 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
/* is ecc point on curve described by dp ? */
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
{
#ifndef WOLFSSL_SP_MATH
int err;
mp_int t1, t2;
@ -4802,9 +4901,16 @@ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
mp_clear(&t2);
return err;
#else
(void)a;
(void)b;
(void)prime;
return sp_ecc_is_point_256(ecp->x, ecp->y);
#endif
}
#ifndef WOLFSSL_SP_MATH
/* validate privkey * generator == pubkey, 0 on success */
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
{
@ -4868,6 +4974,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
return err;
}
#endif
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
@ -4905,6 +5012,7 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
#ifndef 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,
mp_int* prime, mp_int* order)
@ -4928,15 +5036,23 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
else
#endif
#endif
#ifndef WOLFSSL_SP_MATH
err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
err = ECC_INF_E;
#else
(void)a;
(void)prime;
err = WC_KEY_SIZE_E;
#endif
}
wc_ecc_del_point_h(inf, key->heap);
return err;
}
#endif
#endif /* !WOLFSSL_ATECC508A */
@ -4945,6 +5061,7 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
int wc_ecc_check_key(ecc_key* key)
{
int err;
#ifndef WOLFSSL_SP_MATH
#ifndef WOLFSSL_ATECC508A
mp_int* b;
#ifdef USE_ECC_B_PARAM
@ -5019,6 +5136,18 @@ int wc_ecc_check_key(ecc_key* key)
#endif
#endif /* WOLFSSL_ATECC508A */
#else
if (key == NULL)
return BAD_FUNC_ARG;
/* pubkey point cannot be at infinity */
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
key->heap);
}
else
err = WC_KEY_SIZE_E;
#endif
return err;
}
@ -5091,6 +5220,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
#ifdef HAVE_COMP_KEY
if (err == MP_OKAY && compressed == 1) { /* build y */
#ifndef WOLFSSL_SP_MATH
mp_int t1, t2;
int did_init = 0;
@ -5146,6 +5276,9 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
}
wc_ecc_curve_free(curve);
#else
sp_ecc_uncompress_256(key->pubkey.x, in[0], key->pubkey.y);
#endif
}
#endif /* HAVE_COMP_KEY */
@ -5651,6 +5784,7 @@ int wc_ecc_sig_size(ecc_key* key)
#endif
#ifndef WOLFSSL_SP_MATH
/** Our FP cache */
typedef struct {
ecc_point* g; /* cached COPY of base point */
@ -5668,6 +5802,7 @@ static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
static volatile int initMutex = 0; /* prevent multiple mutex inits */
static wolfSSL_Mutex ecc_fp_lock;
#endif /* HAVE_THREAD_LS */
#endif /* WOLFSSL_SP_MATH */
/* simple table to help direct the generation of the LUT */
static const struct {
@ -6199,6 +6334,7 @@ static const struct {
#endif
};
#ifndef WOLFSSL_SP_MATH
/* find a hole and free as required, return -1 if no hole found */
static int find_hole(void)
{
@ -6288,7 +6424,9 @@ static int add_entry(int idx, ecc_point *g)
return MP_OKAY;
}
#endif
#ifndef WOLFSSL_SP_MATH
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
*
* The algorithm builds patterns in increasing bit order by first making all
@ -6577,8 +6715,10 @@ done:
return err;
}
#endif
#ifdef ECC_SHAMIR
#ifndef WOLFSSL_SP_MATH
/* perform a fixed point ECC mulmod */
static int accel_fp_mul2add(int idx1, int idx2,
mp_int* kA, mp_int* kB,
@ -6939,6 +7079,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
return err;
}
#endif
#endif /* ECC_SHAMIR */
/** ECC Fixed Point mulmod global
@ -6954,6 +7095,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
mp_int* modulus, int map, void* heap)
{
#ifndef WOLFSSL_SP_MATH
int idx, err = MP_OKAY;
mp_digit mp;
mp_int mu;
@ -7030,8 +7172,16 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
mp_clear(&mu);
return err;
#else
if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
return ECC_BAD_ARG_E;
}
return sp_ecc_mulmod_256(k, G, R, map, heap);
#endif
}
#ifndef WOLFSSL_SP_MATH
/* helper function for freeing the cache ...
must be called with the cache mutex locked */
static void wc_ecc_fp_free_cache(void)
@ -7051,10 +7201,12 @@ static void wc_ecc_fp_free_cache(void)
}
}
}
#endif
/** Free the Fixed Point cache */
void wc_ecc_fp_free(void)
{
#ifndef WOLFSSL_SP_MATH
#ifndef HAVE_THREAD_LS
if (initMutex == 0) {
wc_InitMutex(&ecc_fp_lock);
@ -7072,6 +7224,7 @@ void wc_ecc_fp_free(void)
initMutex = 0;
}
#endif /* HAVE_THREAD_LS */
#endif
}
@ -7661,6 +7814,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef HAVE_COMP_KEY
#ifndef WOLFSSL_ATECC508A
#ifndef WOLFSSL_SP_MATH
int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
@ -7963,6 +8117,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
return res;
}
#endif
#endif /* !WOLFSSL_ATECC508A */

View File

@ -45,6 +45,8 @@
#ifndef USE_FAST_MATH
#ifndef WOLFSSL_SP_MATH
#include <wolfssl/wolfcrypt/integer.h>
#if defined(FREESCALE_LTC_TFM)
@ -4953,6 +4955,8 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
#endif /* WOLFSSL_SP_MATH */
#endif /* USE_FAST_MATH */
#endif /* NO_BIG_INT */

View File

@ -1198,12 +1198,14 @@ static int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out,
static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
#ifndef WOLFSSL_SP_MATH
mp_int tmp;
#ifdef WC_RSA_BLINDING
mp_int rnd, rndi;
#endif
int ret = 0;
word32 keyLen, len;
#endif
#ifdef WOLFSSL_HAVE_SP_RSA
#ifndef WOLFSSL_SP_NO_2048
@ -1244,6 +1246,9 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
#endif
#endif /* WOLFSSL_HAVE_SP_RSA */
#ifdef WOLFSSL_SP_MATH
return WC_KEY_SIZE_E;
#else
(void)rng;
if (mp_init(&tmp) != MP_OKAY)
@ -1391,6 +1396,7 @@ done:
}
#endif
return ret;
#endif
}
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)

File diff suppressed because it is too large Load Diff

486
wolfcrypt/src/sp_int.c Normal file
View File

@ -0,0 +1,486 @@
/* sp_int.c
*
* Copyright (C) 2006-2017 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
*/
/* Implementation by Sean Parkinson. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#ifdef WOLFSSL_SP_MATH
#include <wolfssl/wolfcrypt/sp_int.h>
/* Initialize the big number to be zero.
*
* a SP integer.
* returns MP_OKAY always.
*/
int sp_init(sp_int* a)
{
a->used = 0;
a->size = SP_INT_DIGITS;
return MP_OKAY;
}
/* Initialize up to six big numbers to be zero.
*
* a SP integer.
* b SP integer.
* c SP integer.
* d SP integer.
* e SP integer.
* f SP integer.
* returns MP_OKAY always.
*/
int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, sp_int* e,
sp_int* f)
{
if (a != NULL) {
a->used = 0;
a->size = SP_INT_DIGITS;
}
if (b != NULL) {
b->used = 0;
b->size = SP_INT_DIGITS;
}
if (c != NULL) {
c->used = 0;
c->size = SP_INT_DIGITS;
}
if (d != NULL) {
d->used = 0;
d->size = SP_INT_DIGITS;
}
if (e != NULL) {
e->used = 0;
e->size = SP_INT_DIGITS;
}
if (f != NULL) {
f->used = 0;
f->size = SP_INT_DIGITS;
}
return MP_OKAY;
}
/* Clear the data from the big number and set to zero.
*
* a SP integer.
*/
void sp_clear(sp_int* a)
{
int i;
for (i=0; i<a->used; i++)
a->dp[i] = 0;
a->used = 0;
}
/* Calculate the number of 8-bit values required to represent the big number.
*
* a SP integer.
* returns the count.
*/
int sp_unsigned_bin_size(sp_int* a)
{
int size = sp_count_bits(a);
return (size + 7) / 8;
}
/* Convert a number as an array of bytes in big-endian format to a big number.
*
* a SP integer.
* in Array of bytes.
* inSz Number of data bytes in array.
* returns MP_OKAY always.
*/
int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz)
{
int i, j = 0, s = 0;
a->dp[0] = 0;
for (i = inSz-1; i >= 0; i--) {
a->dp[j] |= ((sp_int_digit)in[i]) << s;
if (s == DIGIT_BIT - 8) {
a->dp[++j] = 0;
s = 0;
}
else if (s > DIGIT_BIT - 8) {
s = DIGIT_BIT - s;
if (j + 1 >= a->size)
break;
a->dp[++j] = in[i] >> s;
s = 8 - s;
}
else
s += 8;
}
a->used = j + 1;
if (a->dp[j] == 0)
a->used--;
for (j++; j < a->size; j++)
a->dp[j] = 0;
return MP_OKAY;
}
/* Convert a number as string in big-endian format to a big number.
* Only supports base-16 (hexadecimal).
* Negative values not supported.
*
* a SP integer.
* in NUL terminated string.
* radix Number of values in a digit.
* returns BAD_FUNC_ARG when radix not supported or value is negative, MP_VAL
* when a character is not valid and MP_OKAY otherwise.
*/
int sp_read_radix(sp_int* a, const char* in, int radix)
{
int i, j, k;
char ch;
if (radix != 16)
return BAD_FUNC_ARG;
if (*in == '-') {
return BAD_FUNC_ARG;
}
j = 0;
k = 0;
a->dp[0] = 0;
for (i = (int)(XSTRLEN(in) - 1); i >= 0; i--) {
ch = in[i];
if (ch >= '0' && ch <= '9')
ch -= '0';
else if (ch >= 'A' && ch <= 'F')
ch -= 'A' - 10;
else if (ch >= 'a' && ch <= 'f')
ch -= 'a' - 10;
else
return MP_VAL;
a->dp[k] |= ((sp_int_digit)ch) << j;
j += 4;
if (j == DIGIT_BIT && k < SP_INT_DIGITS)
a->dp[++k] = 0;
j &= DIGIT_BIT - 1;
}
a->used = k + 1;
if (a->dp[k] == 0)
a->used--;
for (k++; k < a->size; k++)
a->dp[k] = 0;
return MP_OKAY;
}
/* Compare two big numbers.
*
* a SP integer.
* b SP integer.
* returns MP_GT if a is greater than b, MP_LT if a is less than b and MP_EQ
* when a equals b.
*/
int sp_cmp(sp_int* a, sp_int* b)
{
int i;
if (a->used > b->used)
return MP_GT;
else if (a->used < b->used)
return MP_LT;
for (i = a->used - 1; i >= 0; i--) {
if (a->dp[i] > b->dp[i])
return MP_GT;
else if (a->dp[i] < b->dp[i])
return MP_LT;
}
return MP_EQ;
}
/* Count the number of bits in the big number.
*
* a SP integer.
* returns the number of bits.
*/
int sp_count_bits(sp_int* a)
{
int r = 0;
sp_int_digit d;
r = a->used - 1;
while (r >= 0 && a->dp[r] == 0)
r--;
if (r < 0)
r = 0;
else {
d = a->dp[r];
r *= DIGIT_BIT;
while (d != 0) {
r++;
d >>= 1;
}
}
return r;
}
/* Determine if the most significant byte of the encoded big number as the top
* bit set.
*
* a SP integer.
* returns 1 when the top bit is set and 0 otherwise.
*/
int sp_leading_bit(sp_int* a)
{
int bit = 0;
sp_int_digit d;
if (a->used > 0) {
d = a->dp[a->used - 1];
while (d > (sp_int_digit)0xff)
d >>= 8;
bit = d >> 7;
}
return bit;
}
/* Convert the big number to an array of bytes in big-endian format.
* The array must be large enough for encoded number - use mp_unsigned_bin_size
* to calculate the number of bytes required.
*
* a SP integer.
* returns MP_OKAY always.
*/
int sp_to_unsigned_bin(sp_int* a, byte* out)
{
int i, j, b;
j = sp_unsigned_bin_size(a) - 1;
for (i=0; j>=0; i++) {
for (b = 0; b < SP_WORD_SIZE; b += 8) {
out[j--] = a->dp[i] >> b;
if (j < 0)
break;
}
}
return MP_OKAY;
}
/* Ensure the data in the big number is zeroed.
*
* a SP integer.
*/
void sp_forcezero(sp_int* a)
{
ForceZero(a->dp, a->used * sizeof(sp_int_digit));
a->used = 0;
}
/* Copy value of big number a into b.
*
* a SP integer.
* b SP integer.
* returns MP_OKAY always.
*/
int sp_copy(sp_int* a, sp_int* b)
{
if (a != b) {
XMEMCPY(b->dp, a->dp, a->used * sizeof(sp_int_digit));
b->used = a->used;
}
return MP_OKAY;
}
/* Set the big number to be the value of the digit.
*
* a SP integer.
* d Digit to be set.
* returns MP_OKAY always.
*/
int sp_set(sp_int* a, sp_int_digit d)
{
a->dp[0] = d;
a->used = 1;
return MP_OKAY;
}
/* Checks whether the value of the big number is zero.
*
* a SP integer.
* returns 1 when value is zero and 0 otherwise.
*/
int sp_iszero(sp_int* a)
{
return a->used == 0;
}
/* Recalculate the number of digits used.
*
* a SP integer.
*/
void sp_clamp(sp_int* a)
{
int i;
for (i = a->used - 1; i >= 0 && a->dp[i] == 0; i--) {
}
a->used = i + 1;
}
/* Grow big number to be able to hold l digits.
* This function does nothing as the number of digits is fixed.
*
* a SP integer.
* l Number of digits.
* retuns MP_MEM if the number of digits requested is more than available and
* MP_OKAY otherwise.
*/
int sp_grow(sp_int* a, int l)
{
if (l > a->size)
return MP_MEM;
(void)a;
(void)l;
return MP_OKAY;
}
#if defined(USE_FAST_MATH) || !defined(NO_BIG_INT)
/* Clear all data in the big number and sets value to zero.
*
* a SP integer.
*/
void sp_zero(sp_int* a)
{
XMEMSET(a->dp, 0, a->size);
a->used = 0;
}
/* Add a one digit number to the big number.
*
* a SP integer.
* d Digit to add.
* r SP integer - result.
* returns MP_OKAY always.
*/
int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r)
{
int i = 0;
r->dp[0] = a->dp[0] + d;
if (r->dp[i] < a->dp[i]) {
for (; i < a->used; i++) {
r->dp[i] = a->dp[i] + 1;
if (r->dp[i] != 0)
break;
}
if (i == a->used && r->dp[i] == 0) {
a->used++;
a->dp[i] = 1;
}
}
for (; i < a->used; i++)
r->dp[i] = a->dp[i];
return MP_OKAY;
}
/* Left shift the big number by a number of digits.
* WIll chop off digits overflowing maximum size.
*
* a SP integer.
* s Number of digits to shift.
* returns MP_OKAY always.
*/
int sp_lshd(sp_int* a, int s)
{
if (a->used + s > a->size)
a->used = a->size - s;
XMEMMOVE(a->dp + s, a->dp, a->used * SP_INT_DIGITS);
a->used += s;
return MP_OKAY;
}
#endif
#ifndef NO_PWDBASED
int sp_add(sp_int* a, sp_int* b, sp_int* r)
{
int i;
sp_digit c = 0;
for (i = 0; i < a->used && i < b->used; i++) {
r->dp[i] = a->dp[i] + b->dp[i] + c;
if (c == 0)
c = r->dp[i] < a->dp[i];
else
c = r->dp[i] <= a->dp[i];
}
for (; i < a->used; i++) {
r->dp[i] = a->dp[i] + c;
c = r->dp[i] == 0;
}
for (; i < b->used; i++) {
r->dp[i] = b->dp[i] + c;
c = r->dp[i] == 0;
}
r->dp[i] = c;
a->used = i + c;
return MP_OKAY;
}
#endif
#if !defined(USE_FAST_MATH)
/* Returns the run time settings.
*
* returns the settings value.
*/
word32 CheckRunTimeSettings(void)
{
return CTC_SETTINGS;
}
#endif
#endif

View File

@ -9640,6 +9640,7 @@ static int dh_generate_test(WC_RNG *rng)
DhKey smallKey;
byte p[2] = { 0, 5 };
byte g[2] = { 0, 2 };
#ifndef WOLFSSL_SP_MATH
#ifdef WOLFSSL_DH_CONST
/* the table for constant DH lookup will round to the lowest byte size 21 */
byte priv[21];
@ -9650,6 +9651,7 @@ static int dh_generate_test(WC_RNG *rng)
#endif
word32 privSz = sizeof(priv);
word32 pubSz = sizeof(pub);
#endif
ret = wc_InitDhKey_ex(&smallKey, HEAP_HINT, devId);
if (ret != 0)
@ -9681,6 +9683,7 @@ static int dh_generate_test(WC_RNG *rng)
ERROR_OUT(-5706, exit_gen_test);
}
#ifndef WOLFSSL_SP_MATH
/* Use API. */
ret = wc_DhGenerateKeyPair(&smallKey, rng, priv, &privSz, pub, &pubSz);
#if defined(WOLFSSL_ASYNC_CRYPT)
@ -9689,6 +9692,10 @@ static int dh_generate_test(WC_RNG *rng)
if (ret != 0) {
ret = -5707;
}
#else
(void)rng;
ret = 0;
#endif
exit_gen_test:
wc_FreeDhKey(&smallKey);
@ -14087,7 +14094,9 @@ static int ecc_test_cert_gen(WC_RNG* rng)
}
bytes = fread(der, 1, FOURK_BUF, file);
fclose(file);
#ifdef ENABLE_ECC384_CERT_GEN_TEST
(void)eccCaKey384File;
#endif
#endif /* USE_CERT_BUFFERS_256 */
#endif /* ENABLE_ECC384_CERT_GEN_TEST */
@ -14165,8 +14174,10 @@ static int ecc_test_cert_gen(WC_RNG* rng)
sizeof_ca_ecc_cert_der_256);
#else
ret = wc_SetIssuer(&myCert, eccCaCertFile);
#ifdef ENABLE_ECC384_CERT_GEN_TEST
(void)eccCaCert384File;
#endif
#endif
#endif /* ENABLE_ECC384_CERT_GEN_TEST */
if (ret < 0) {
ERROR_OUT(-6731, exit);

View File

@ -91,5 +91,6 @@ endif
if BUILD_SP
nobase_include_HEADERS+= wolfssl/wolfcrypt/sp.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/sp_int.h
endif

View File

@ -33,7 +33,9 @@
may not be faster on all
*/
#include <wolfssl/wolfcrypt/types.h> /* will set MP_xxBIT if not default */
#ifdef USE_FAST_MATH
#ifdef WOLFSSL_SP_MATH
#include <wolfssl/wolfcrypt/sp_int.h>
#elif defined(USE_FAST_MATH)
#include <wolfssl/wolfcrypt/tfm.h>
#else

View File

@ -1310,7 +1310,7 @@ extern void uITRON4_free(void *p) ;
/* user can specify what curves they want with ECC_USER_CURVES otherwise
* all curves are on by default for now */
#ifndef ECC_USER_CURVES
#ifndef HAVE_ALL_CURVES
#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_ALL_CURVES)
#define HAVE_ALL_CURVES
#endif
#endif
@ -1326,6 +1326,10 @@ extern void uITRON4_free(void *p) ;
#undef HAVE_ECC_VERIFY
#define HAVE_ECC_VERIFY
#endif
#ifndef NO_ECC_CHECK_KEY
#undef HAVE_ECC_CHECK_KEY
#define HAVE_ECC_CHECK_KEY
#endif
#ifndef NO_ECC_DHE
#undef HAVE_ECC_DHE
#define HAVE_ECC_DHE

View File

@ -31,35 +31,10 @@
#include <stdint.h>
#include <wolfssl/wolfcrypt/integer.h>
#include <wolfssl/wolfcrypt/sp_int.h>
#include <wolfssl/wolfcrypt/ecc.h>
#if defined(NO_64BIT) || !defined(HAVE___UINT128_T)
#define SP_WORD_SIZE 32
#else
#define SP_WORD_SIZE 64
#endif
#if !defined(WOLFSSL_X86_64_BUILD) || !defined(USE_INTEL_SPEEDUP)
#if SP_WORD_SIZE == 32
typedef int32_t sp_digit;
#elif SP_WORD_SIZE == 64
typedef int64_t sp_digit;
typedef long int128_t __attribute__ ((mode(TI)));
#else
#error Word size not defined
#endif
#else
#if SP_WORD_SIZE == 32
typedef uint32_t sp_digit;
#elif SP_WORD_SIZE == 64
typedef uint64_t sp_digit;
typedef unsigned long uint128_t __attribute__ ((mode(TI)));
typedef long int128_t __attribute__ ((mode(TI)));
#else
#error Word size not defined
#endif
#endif
#if defined(_MSC_VER)
#define SP_NOINLINE __declspec(noinline)
#elif defined(__GNUC__)
@ -68,6 +43,7 @@
#define 5P_NOINLINE
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -110,6 +86,15 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
mp_int* rm, mp_int* sm, void* heap);
int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY,
mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap);
int sp_ecc_is_point_256(mp_int* pX, mp_int* pY);
int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap);
int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
mp_int* qX, mp_int* qY, mp_int* qZ,
mp_int* rX, mp_int* rY, mp_int* rZ);
int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,
mp_int* rX, mp_int* rY, mp_int* rZ);
int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ);
int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym);
#endif /*ifdef WOLFSSL_HAVE_SP_ECC */

165
wolfssl/wolfcrypt/sp_int.h Normal file
View File

@ -0,0 +1,165 @@
/* sp_int.h
*
* Copyright (C) 2006-2017 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
*/
#ifndef WOLF_CRYPT_SP_INT_H
#define WOLF_CRYPT_SP_INT_H
#include <stdint.h>
#include <limits.h>
#if defined(NO_64BIT) || !defined(HAVE___UINT128_T)
#define SP_WORD_SIZE 32
#else
#define SP_WORD_SIZE 64
#endif
#if !defined(WOLFSSL_X86_64_BUILD) || !defined(USE_INTEL_SPEEDUP)
#if SP_WORD_SIZE == 32
typedef int32_t sp_digit;
typedef uint32_t sp_int_digit;
#elif SP_WORD_SIZE == 64
typedef int64_t sp_digit;
typedef uint64_t sp_int_digit;
typedef long int128_t __attribute__ ((mode(TI)));
#else
#error Word size not defined
#endif
#else
#if SP_WORD_SIZE == 32
typedef uint32_t sp_digit;
typedef uint32_t sp_int_digit;
#elif SP_WORD_SIZE == 64
typedef uint64_t sp_digit;
typedef uint64_t sp_int_digit;
typedef unsigned long uint128_t __attribute__ ((mode(TI)));
typedef long int128_t __attribute__ ((mode(TI)));
#else
#error Word size not defined
#endif
#endif
#ifdef WOLFSSL_SP_MATH
#include <wolfssl/wolfcrypt/random.h>
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
#if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH)
#if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512)
#define SP_INT_DIGITS ((512 + SP_WORD_SIZE) / SP_WORD_SIZE)
#else
#define SP_INT_DIGITS ((256 + SP_WORD_SIZE) / SP_WORD_SIZE)
#endif
#elif !defined(WOLFSSL_SP_NO_3072)
#define SP_INT_DIGITS ((2048 + SP_WORD_SIZE) / SP_WORD_SIZE)
#else
#define SP_INT_DIGITS ((3072 + SP_WORD_SIZE) / SP_WORD_SIZE)
#endif
#define sp_isodd(a) (a->used != 0 && (a->dp[0] & 1))
typedef struct sp_int {
sp_int_digit dp[SP_INT_DIGITS];
int size;
int used;
} sp_int;
WOLFSSL_LOCAL int sp_init(sp_int* a);
WOLFSSL_LOCAL int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d,
sp_int* e, sp_int* f);
WOLFSSL_LOCAL void sp_clear(sp_int* a);
WOLFSSL_LOCAL int sp_unsigned_bin_size(sp_int* a);
WOLFSSL_LOCAL int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz);
WOLFSSL_LOCAL int sp_read_radix(sp_int* a, const char* in, int radix);
WOLFSSL_LOCAL int sp_cmp(sp_int* a, sp_int* b);
WOLFSSL_LOCAL int sp_count_bits(sp_int* a);
WOLFSSL_LOCAL int sp_leading_bit(sp_int* a);
WOLFSSL_LOCAL int sp_to_unsigned_bin(sp_int* a, byte* in);
WOLFSSL_LOCAL void sp_forcezero(sp_int* a);
WOLFSSL_LOCAL int sp_copy(sp_int* a, sp_int* b);
WOLFSSL_LOCAL int sp_set(sp_int* a, sp_int_digit d);
WOLFSSL_LOCAL int sp_iszero(sp_int* a);
WOLFSSL_LOCAL void sp_clamp(sp_int* a);
WOLFSSL_LOCAL int sp_grow(sp_int* a, int l);
WOLFSSL_LOCAL void sp_zero(sp_int* a);
WOLFSSL_LOCAL int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r);
WOLFSSL_LOCAL int sp_lshd(sp_int* a, int s);
WOLFSSL_LOCAL int sp_add(sp_int* a, sp_int* b, sp_int* r);
typedef sp_int mp_int;
typedef sp_digit mp_digit;
#define MP_OKAY 0
#define MP_NO 0
#define MP_YES 1
#define MP_RADIX_HEX 16
#define MP_GT 1
#define MP_EQ 0
#define MP_LT -1
#define MP_MEM -2
#define MP_VAL -3
#define DIGIT_BIT SP_WORD_SIZE
#define CheckFastMathSettings() 1
#define mp_free(a)
#define mp_init sp_init
#define mp_init_multi sp_init_multi
#define mp_clear sp_clear
#define mp_read_unsigned_bin sp_read_unsigned_bin
#define mp_unsigned_bin_size sp_unsigned_bin_size
#define mp_read_radix sp_read_radix
#define mp_cmp sp_cmp
#define mp_count_bits sp_count_bits
#define mp_leading_bit sp_leading_bit
#define mp_to_unsigned_bin sp_to_unsigned_bin
#define mp_forcezero sp_forcezero
#define mp_copy sp_copy
#define mp_set sp_set
#define mp_iszero sp_iszero
#define mp_clamp sp_clamp
#define mp_grow sp_grow
#define mp_zero sp_zero
#define mp_add_d sp_add_d
#define mp_lshd sp_lshd
#define mp_add sp_add
#define mp_isodd sp_isodd
#define MP_INT_DEFINED
#include <wolfssl/wolfcrypt/wolfmath.h>
#endif
#endif /* WOLF_CRYPT_SP_H */