Added CryptoCell-310 support

- SHA-256
- AES CBC
- CryptoCell 310 RNG
- RSA sign/verify and RSA key gen
- RSA encrypt/decrypt, decrypt inline
- ECC sign/verify/shared secret
- ECC key import/export and key gen pairs
- Hardware RNG and RTC of nRF52840 for benchmark timing source
- readme doc
This commit is contained in:
David Garske
2019-03-27 20:44:38 -07:00
committed by Tesfa Mael
parent 378f5c0d4b
commit 6c65550eab
23 changed files with 2059 additions and 50 deletions

View File

@@ -3375,7 +3375,9 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen)
{
int err;
#if defined(WOLFSSL_CRYPTOCELL)
CRYS_ECDH_TempData_t tempBuff;
#endif
if (private_key == NULL || public_key == NULL || out == NULL ||
outlen == NULL) {
return BAD_FUNC_ARG;
@@ -3416,9 +3418,21 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
else {
err = NOT_COMPILED_IN;
}
#elif defined(WOLFSSL_CRYPTOCELL)
/* generate a secret*/
err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
&private_key->ctx.privKey,
out,
outlen,
&tempBuff);
if (err != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
return err;
}
#else
err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
#endif /* WOLFSSL_ATECC508A */
@@ -3426,7 +3440,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
}
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
byte* out, word32* outlen, ecc_curve_spec* curve)
@@ -3689,11 +3703,11 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
return err;
}
#endif /* !WOLFSSL_ATECC508A */
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
#endif /* HAVE_ECC_DHE */
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
/* return 1 if point is at infinity, 0 if not, < 0 on error */
int wc_ecc_point_is_at_infinity(ecc_point* p)
{
@@ -3757,7 +3771,7 @@ static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
#endif /* !WC_NO_RNG */
}
#endif /* WOLFSSL_SP_MATH */
#endif /* !WOLFSSL_ATECC508A */
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
static WC_INLINE void wc_ecc_reset(ecc_key* key)
{
@@ -3926,12 +3940,18 @@ int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
{
int err;
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
#ifndef WOLFSSL_SP_MATH
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
#endif
#endif /* !WOLFSSL_ATECC508A */
#if defined(WOLFSSL_CRYPTOCELL)
const CRYS_ECPKI_Domain_t* pDomain;
CRYS_ECPKI_KG_TempData_t tempBuff;
CRYS_ECPKI_KG_FipsContext_t fipsCtx;
byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
word32 raw_size = (word32) (key->dp->size)*2 + 1;
#endif
if (key == NULL || rng == NULL) {
return BAD_FUNC_ARG;
}
@@ -4000,6 +4020,45 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
else {
err = NOT_COMPILED_IN;
}
#elif defined(WOLFSSL_CRYPTOCELL)
pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
/* generate first key pair */
err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
wc_rndGenVectFunc,
pDomain,
&key->ctx.privKey,
&key->ctx.pubKey,
&tempBuff,
&fipsCtx);
if (err != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
return err;
}
key->type = ECC_PRIVATEKEY;
err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
CRYS_EC_PointUncompressed,
&ucompressed_key[0],
&raw_size);
if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
err = mp_read_unsigned_bin(key->pubkey.x,
&ucompressed_key[1], key->dp->size);
err = mp_read_unsigned_bin(key->pubkey.y,
&ucompressed_key[1+key->dp->size],key->dp->size);
}
raw_size = key->dp->size;
err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
ucompressed_key,
&raw_size);
if (err == SA_SILIB_RET_OK) {
err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size);
}
#else
#ifdef WOLFSSL_HAVE_SP_ECC
@@ -4233,15 +4292,21 @@ int wc_ecc_set_flags(ecc_key* key, word32 flags)
#ifndef NO_ASN
#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || \
defined(WOLFSSL_CRYPTOCELL)
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
ecc_key* key)
{
int err;
#ifdef PLUTON_CRYPTO_ECC
if (key->devId != INVALID_DEVID) /* use hardware */
#endif
#if defined(WOLFSSL_CRYPTOCELL)
CRYS_ECDSA_SignUserContext_t sigCtxTemp;
word32 raw_sig_size = *outlen;
word32 msgLenInBytes = inlen;
CRYS_ECPKI_HASH_OpMode_t hash_mode;
#endif
{
word32 keysize = (word32)key->dp->size;
@@ -4286,6 +4351,34 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
return BAD_COND_E;
}
}
#elif defined(WOLFSSL_CRYPTOCELL)
hash_mode = cc310_hashModeECC(msgLenInBytes);
if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
hash_mode = cc310_hashModeECC(keysize);
hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
}
/* truncate if hash is longer than key size */
if (msgLenInBytes > keysize) {
msgLenInBytes = keysize;
}
/* create signature from an input buffer using a private key*/
err = CRYS_ECDSA_Sign(&wc_rndState,
wc_rndGenVectFunc,
&sigCtxTemp,
&key->ctx.privKey,
hash_mode,
(byte*)in,
msgLenInBytes,
out,
&raw_sig_size);
if (err != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
return err;
}
#endif
/* Load R and S */
@@ -4312,7 +4405,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
return err;
}
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
/**
Sign a message digest
@@ -4381,7 +4474,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
}
/* hardware crypto */
#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)
err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
#else
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
@@ -4446,7 +4539,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
}
#endif /* !NO_ASN */
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
/**
Sign a message digest
in The message digest to sign
@@ -4781,7 +4874,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
return err;
}
#endif /* WOLFSSL_ATECC508A */
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/
#endif /* HAVE_ECC_SIGN */
#ifdef WOLFSSL_CUSTOM_CURVES
@@ -4843,7 +4936,7 @@ int wc_ecc_free(ecc_key* key)
return 0;
}
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A)
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
#ifdef ECC_SHAMIR
/** Computes kA*A + kB*B = C using Shamir's Trick
@@ -5146,7 +5239,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
}
#endif /* ECC_SHAMIR */
#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A */
#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/
#ifdef HAVE_ECC_VERIFY
@@ -5308,6 +5401,11 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
word32 keySz;
#ifdef WOLFSSL_ATECC508A
byte sigRS[ATECC_KEY_SIZE*2];
#elif defined(WOLFSSL_CRYPTOCELL)
byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
word32 msgLenInBytes = hashlen;
CRYS_ECPKI_HASH_OpMode_t hash_mode;
#elif !defined(WOLFSSL_SP_MATH)
int did_init = 0;
ecc_point *mG = NULL, *mQ = NULL;
@@ -5377,7 +5475,44 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
return err;
}
(void)hashlen;
#elif defined(WOLFSSL_CRYPTOCELL)
/* Extract R and S */
err = mp_to_unsigned_bin(r, &sigRS[0]);
if (err != MP_OKAY) {
return err;
}
err = mp_to_unsigned_bin(s, &sigRS[keySz]);
if (err != MP_OKAY) {
return err;
}
hash_mode = cc310_hashModeECC(msgLenInBytes);
if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
hash_mode = cc310_hashModeECC(keySz);
hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
}
/* truncate if hash is longer than key size */
if (msgLenInBytes > keySz) {
msgLenInBytes = keySz;
}
/* verify the signature using the public key */
err = CRYS_ECDSA_Verify(&sigCtxTemp,
&key->ctx.pubKey,
hash_mode,
&sigRS[0],
keySz*2,
(byte*)hash,
msgLenInBytes);
if (err != SA_SILIB_RET_OK) {
WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
return err;
}
/* valid signature if we get to this point */
*res = 1;
#else
/* checking if private key with no public part */
if (key->type == ECC_PRIVATEKEY_ONLY) {
@@ -5954,7 +6089,7 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
#endif /* HAVE_ECC_KEY_EXPORT */
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
/* 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)
@@ -6217,7 +6352,7 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
return err;
}
#endif
#endif /* !WOLFSSL_ATECC508A */
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL*/
/* perform sanity checks on ecc key validity, 0 on success */
@@ -6225,7 +6360,7 @@ int wc_ecc_check_key(ecc_key* key)
{
int err;
#ifndef WOLFSSL_SP_MATH
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
mp_int* b = NULL;
#ifdef USE_ECC_B_PARAM
DECLARE_CURVE_SPECS(curve, 4);
@@ -6240,7 +6375,7 @@ int wc_ecc_check_key(ecc_key* key)
if (key == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_ATECC508A
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_CRYPTOCELL)
err = 0; /* consider key check success on ATECC508A */
@@ -6626,7 +6761,10 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
{
int ret;
word32 idx = 0;
#if defined(WOLFSSL_CRYPTOCELL)
const CRYS_ECPKI_Domain_t* pDomain;
CRYS_ECPKI_BUILD_TempData_t tempBuff;
#endif
if (key == NULL || priv == NULL)
return BAD_FUNC_ARG;
@@ -6652,6 +6790,38 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#ifdef WOLFSSL_ATECC508A
/* Hardware does not support loading private keys */
return NOT_COMPILED_IN;
#elif defined(WOLFSSL_CRYPTOCELL)
pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
if (pub != NULL && pub[0] != '\0') {
/* create public key from external key buffer */
ret = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
(byte*)pub,
pubSz,
&key->ctx.pubKey,
&tempBuff);
if (ret != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
return ret;
}
}
/* import private key */
if (priv != NULL && priv[0] != '\0') {
/* Create private key from external key buffer*/
ret = CRYS_ECPKI_BuildPrivKey(pDomain,
priv,
privSz,
&key->ctx.privKey);
if (ret != SA_SILIB_RET_OK) {
WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
return ret;
}
ret = mp_read_unsigned_bin(&key->k, priv, privSz);
}
#else
@@ -6897,7 +7067,12 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
const char* qy, const char* d, int curve_id, int encType)
{
int err = MP_OKAY;
#if defined(WOLFSSL_CRYPTOCELL)
const CRYS_ECPKI_Domain_t* pDomain;
CRYS_ECPKI_BUILD_TempData_t tempBuff;
byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
word32 keySz = key->dp->size;
#endif
/* if d is NULL, only import as public key using Qx,Qy */
if (key == NULL || qx == NULL || qy == NULL) {
return BAD_FUNC_ARG;
@@ -6960,14 +7135,65 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
}
#elif defined(WOLFSSL_CRYPTOCELL)
if (err == MP_OKAY) {
key_raw[0] = ECC_POINT_UNCOMP;
keySz = key->dp->size;
err = wc_export_int(key->pubkey.x, &key_raw[1], &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
if (err == MP_OKAY)
err = wc_export_int(key->pubkey.y, &key_raw[1+keySz],
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
/* create public key from external key buffer */
err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
key_raw,
keySz*2 + 1,
&key->ctx.pubKey,
&tempBuff);
if (err != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
return err;
}
}
#endif
/* import private key */
if (err == MP_OKAY) {
if (d != NULL) {
if (d != NULL && d[0] != '\0') {
#ifdef WOLFSSL_ATECC508A
/* Hardware doesn't support loading private key */
err = NOT_COMPILED_IN;
#elif defined(WOLFSSL_CRYPTOCELL)
key->type = ECC_PRIVATEKEY;
if (encType == WC_TYPE_HEX_STR)
err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
else
err = mp_read_unsigned_bin(&key->k, (const byte*)d,
key->dp->size);
err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
/* Create private key from external key buffer*/
err = CRYS_ECPKI_BuildPrivKey(pDomain,
key_raw,
keySz,
&key->ctx.privKey);
if (err != SA_SILIB_RET_OK){
WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
return err;
}
#else
key->type = ECC_PRIVATEKEY;
@@ -9148,7 +9374,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef HAVE_COMP_KEY
#ifndef WOLFSSL_ATECC508A
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
#ifndef WOLFSSL_SP_MATH
int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
@@ -9472,7 +9698,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
#endif
}
#endif
#endif /* !WOLFSSL_ATECC508A */
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
/* export public ECC key in ANSI X9.63 format compressed */