Merge pull request #4584 from ethanlooney/nxp_se050_curve25519

Added curve25519 support for NXP SE050
This commit is contained in:
Daniele Lacamera
2021-12-02 02:47:36 -08:00
committed by GitHub
9 changed files with 396 additions and 65 deletions

View File

@@ -43,6 +43,9 @@
#if defined(FREESCALE_LTC_ECC)
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#ifdef WOLF_CRYPTO_CB
#include <wolfssl/wolfcrypt/cryptocb.h>
@@ -227,6 +230,9 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
}
#endif
#ifdef WOLFSSL_SE050
ret = se050_curve25519_create_key(key, keysize);
#else
ret = wc_curve25519_make_priv(rng, keysize, key->k);
if (ret == 0) {
key->privSet = 1;
@@ -234,6 +240,7 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
(int)sizeof(key->k), key->k);
key->pubSet = (ret == 0);
}
#endif
return ret;
}
@@ -251,8 +258,8 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
curve25519_key* public_key,
byte* out, word32* outlen, int endian)
{
int ret;
ECPoint o;
int ret = 0;
/* sanity check */
if (private_key == NULL || public_key == NULL ||
@@ -261,7 +268,11 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
}
/* make sure we have a populated private and public key */
if (!private_key->privSet || !public_key->pubSet) {
if (!public_key->pubSet
#ifndef WOLFSSL_SE050
|| !private_key->privSet
#endif
) {
return ECC_BAD_ARG_E;
}
@@ -270,8 +281,6 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
return ECC_BAD_ARG_E;
}
XMEMSET(&o, 0, sizeof(o));
#ifdef WOLF_CRYPTO_CB
if (private_key->devId != INVALID_DEVID) {
ret = wc_CryptoCb_Curve25519(private_key, public_key, out, outlen,
@@ -282,17 +291,28 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
}
#endif
#ifdef FREESCALE_LTC_ECC
/* input point P on Curve25519 */
ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
kLTC_Curve25519);
#else
SAVE_VECTOR_REGISTERS(return _svr_ret;);
XMEMSET(&o, 0, sizeof(o));
ret = curve25519(o.point, private_key->k, public_key->p.point);
RESTORE_VECTOR_REGISTERS();
#ifdef FREESCALE_LTC_ECC
/* input point P on Curve25519 */
ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
kLTC_Curve25519);
#else
#ifdef WOLFSSL_SE050
if (!private_key->privSet) {
/* use NXP SE050 is private key is not set */
ret = se050_curve25519_shared_secret(private_key, public_key, &o);
}
else
#endif
{
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = curve25519(o.point, private_key->k, public_key->p.point);
RESTORE_VECTOR_REGISTERS();
}
#endif
if (ret != 0) {
ForceZero(&o, sizeof(o));
return ret;
@@ -575,6 +595,11 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
return ECC_BAD_ARG_E;
}
#ifdef WOLFSSL_SE050
/* release NXP resources if set */
se050_curve25519_free_key(key);
#endif
/* import private scalar with endianess */
curve25519_copy_point(key->k, priv, endian);
key->privSet = 1;
@@ -622,6 +647,10 @@ void wc_curve25519_free(curve25519_key* key)
if (key == NULL)
return;
#ifdef WOLFSSL_SE050
se050_curve25519_free_key(key);
#endif
key->dp = NULL;
ForceZero(key->k, sizeof(key->k));
XMEMSET(&key->p, 0, sizeof(key->p));

View File

@@ -171,6 +171,10 @@ ECC Curve Sizes:
#include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#define GEN_MEM_ERR MP_MEM
#elif defined(USE_FAST_MATH)
@@ -5258,9 +5262,15 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
}
#elif defined(WOLFSSL_KCAPI_ECC)
err = KcapiEcc_Sign(key, in, inlen, out, outlen);
if (err != MP_OKAY) {
return err;
}
(void)rng;
#elif defined(WOLFSSL_SE050)
err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key);
if (err != MP_OKAY) {
return err;
}
(void)rng;
#endif

View File

@@ -44,6 +44,9 @@
#ifdef FREESCALE_LTC_ECC
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#ifdef WOLF_CRYPTO_CB
#include <wolfssl/wolfcrypt/cryptocb.h>
@@ -827,10 +830,6 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
fe_init();
#endif
#ifdef WOLFSSL_SE050
se050_ed25519_create_key(key);
#endif
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
return ed25519_hash_init(key, &key->sha);
#else /* !WOLFSSL_ED25519_PERSISTENT_SHA */

View File

@@ -35,6 +35,7 @@
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
@@ -126,6 +127,7 @@ int se050_allocate_key(int keyType)
case SE050_AES_KEY:
case SE050_ECC_KEY:
case SE050_ED25519_KEY:
case SE050_CURVE25519_KEY:
case SE050_ANY_KEY:
keyId = keyId_allocator++;
break;
@@ -481,6 +483,23 @@ static int se050_map_curve(int curve_id, int keySize,
return ret;
}
static sss_algorithm_t se050_map_hash_alg(int hashLen)
{
sss_algorithm_t algorithm = kAlgorithm_None;
if (hashLen == 20) {
algorithm = kAlgorithm_SSS_SHA1;
} else if (hashLen == 28) {
algorithm = kAlgorithm_SSS_SHA224;
} else if (hashLen == 32) {
algorithm = kAlgorithm_SSS_SHA256;
} else if (hashLen == 48) {
algorithm = kAlgorithm_SSS_SHA384;
} else if (hashLen == 64) {
algorithm = kAlgorithm_SSS_SHA512;
}
return algorithm;
}
int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out,
word32 *outLen, struct ecc_key* key)
{
@@ -489,7 +508,7 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out,
sss_asymmetric_t ctx_asymm;
sss_key_store_t host_keystore;
sss_object_t newKey;
sss_algorithm_t algorithm = kAlgorithm_None;
sss_algorithm_t algorithm;
int keySize;
int keySizeBits;
@@ -515,18 +534,12 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out,
if (inLen > (word32)keySize)
inLen = (word32)keySize;
if (inLen == 20)
algorithm = kAlgorithm_SSS_SHA1;
else if (inLen == 28)
algorithm = kAlgorithm_SSS_SHA224;
else if (inLen == 32)
algorithm = kAlgorithm_SSS_SHA256;
else if (inLen == 48)
algorithm = kAlgorithm_SSS_SHA384;
else if (inLen == 64)
algorithm = kAlgorithm_SSS_SHA512;
else {
/* not supported curve key size */
algorithm = se050_map_hash_alg(inLen);
if (algorithm == kAlgorithm_None) {
inLen = keySize; /* try key size */
algorithm = se050_map_hash_alg(inLen);
}
if (algorithm == kAlgorithm_None) {
return ECC_CURVE_OID_E;
}
@@ -553,8 +566,8 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out,
if (status == kStatus_SSS_Success) {
byte sigBuf[ECC_MAX_SIG_SIZE];
size_t sigSz = sizeof(sigBuf);
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in,
inLen, sigBuf, &sigSz);
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, inLen,
sigBuf, &sigSz);
if (status == kStatus_SSS_Success) {
/* SE050 returns ASN.1 encoded signature */
word32 rLen = keySize, sLen = keySize;
@@ -596,7 +609,7 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* sigRS,
sss_asymmetric_t ctx_asymm;
sss_object_t newKey;
sss_key_store_t host_keystore;
sss_algorithm_t algorithm = kAlgorithm_None;
sss_algorithm_t algorithm;
int keyId;
int keySize;
int keySizeBits;
@@ -625,18 +638,12 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* sigRS,
if (hashLen > (word32)keySize)
hashLen = (word32)keySize;
if (hashLen == 20)
algorithm = kAlgorithm_SSS_SHA1;
else if (hashLen == 28)
algorithm = kAlgorithm_SSS_SHA224;
else if (hashLen == 32)
algorithm = kAlgorithm_SSS_SHA256;
else if (hashLen == 48)
algorithm = kAlgorithm_SSS_SHA384;
else if (hashLen == 64)
algorithm = kAlgorithm_SSS_SHA512;
else {
/* not supported curve key size */
algorithm = se050_map_hash_alg(hashLen);
if (algorithm == kAlgorithm_None) {
hashLen = keySize; /* try key size */
algorithm = se050_map_hash_alg(hashLen);
}
if (algorithm == kAlgorithm_None) {
return ECC_CURVE_OID_E;
}
@@ -814,7 +821,7 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize)
if (status == kStatus_SSS_Success) {
keyId = se050_allocate_key(SE050_ECC_KEY);
status = sss_key_object_allocate_handle(&keyPair, keyId,
kSSS_KeyPart_Pair, curveType, keySizeBits,
kSSS_KeyPart_Pair, curveType, keySize,
kKeyObject_Mode_Transient);
}
if (status == kStatus_SSS_Success) {
@@ -914,7 +921,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
if (status == kStatus_SSS_Success) {
keyId = public_key->keyId;
if (keyId <= 0) {
byte derBuf[256];
byte derBuf[SE050_ECC_DER_MAX];
word32 derSz;
ret = wc_EccPublicKeyToDer(public_key, derBuf,
@@ -1167,7 +1174,6 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
return ret;
}
int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen,
const byte* msg, word32 msgLen, struct ed25519_key* key, int* res)
{
@@ -1268,4 +1274,265 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen,
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
int se050_curve25519_create_key(curve25519_key* key, int keySize)
{
int ret;
sss_status_t status = kStatus_SSS_Success;
sss_object_t keyPair;
sss_key_store_t host_keystore;
uint8_t derBuf[SE050_ECC_DER_MAX];
size_t derSz = sizeof(derBuf);
int keyId;
int keyCreated = 0;
#ifdef SE050_DEBUG
printf("se050_curve25519_create_key: key %p, keySize %d\n",
key, keySize);
#endif
if (cfg_se050_i2c_pi == NULL) {
return WC_HW_E;
}
if (wolfSSL_CryptHwMutexLock() != 0) {
return BAD_MUTEX_E;
}
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
if (status == kStatus_SSS_Success) {
status = sss_key_store_allocate(&host_keystore,
SE050_KEYSTOREID_CURVE25519);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&keyPair, &host_keystore);
}
if (status == kStatus_SSS_Success) {
keyId = se050_allocate_key(SE050_CURVE25519_KEY);
status = sss_key_object_allocate_handle(&keyPair, keyId,
kSSS_KeyPart_Pair, kSSS_CipherType_EC_MONTGOMERY, keySize,
kKeyObject_Mode_None);
}
if (status == kStatus_SSS_Success) {
keyCreated = 1;
status = sss_key_store_generate_key(&host_keystore, &keyPair,
keySize * 8, NULL);
}
if (status == kStatus_SSS_Success) {
size_t derSzBits = derSz * 8;
status = sss_key_store_get_key(&host_keystore, &keyPair,
derBuf, &derSz, &derSzBits);
(void)derSzBits; /* not used */
}
if (status == kStatus_SSS_Success) {
word32 idx = 0;
ret = wc_Curve25519PublicKeyDecode(derBuf, &idx, key, (word32)derSz);
if (ret == 0) {
key->p.point[CURVE25519_KEYSIZE-1] &= ~0x80; /* clear MSB */
}
else {
status = kStatus_SSS_Fail;
}
}
if (status == kStatus_SSS_Success) {
key->keyId = keyId;
ret = 0;
}
else {
if (keyCreated) {
sss_key_store_erase_key(&host_keystore, &keyPair);
sss_key_object_free(&keyPair);
}
ret = WC_HW_E;
}
wolfSSL_CryptHwMutexUnLock();
#ifdef SE050_DEBUG
printf("se050_curve25519_create_key: key %p, ret %d, keyId %d\n",
key, ret, key->keyId);
#endif
return ret;
}
int se050_curve25519_shared_secret(curve25519_key* private_key,
curve25519_key* public_key, ECPoint* out)
{
int ret;
sss_status_t status = kStatus_SSS_Success;
sss_key_store_t host_keystore;
sss_object_t ref_private_key;
sss_object_t ref_public_key;
sss_object_t deriveKey;
sss_derive_key_t ctx_derive_key;
int keyId;
int keySize = CURVE25519_KEYSIZE;
int keyCreated = 0;
int deriveKeyCreated = 0;
#ifdef SE050_DEBUG
printf("se050_curve25519_shared_secret: priv %p, pub %p, out %p (%d)\n",
private_key, public_key, out, out->pointSz);
#endif
if (cfg_se050_i2c_pi == NULL) {
return WC_HW_E;
}
if (private_key->keyId <= 0) {
return BAD_FUNC_ARG;
}
if (wolfSSL_CryptHwMutexLock() != 0) {
return BAD_MUTEX_E;
}
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
if (status == kStatus_SSS_Success) {
status = sss_key_store_allocate(&host_keystore,
SE050_KEYSTOREID_CURVE25519);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&ref_private_key, &host_keystore);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_get_handle(&ref_private_key, private_key->keyId);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&ref_public_key, &host_keystore);
}
if (status == kStatus_SSS_Success) {
keyId = public_key->keyId;
if (keyId <= 0) {
byte derBuf[SE050_ECC_DER_MAX];
word32 derSz;
ret = wc_Curve25519PublicKeyToDer(public_key, derBuf,
(word32)sizeof(derBuf), 1);
if (ret >= 0) {
derSz = ret;
ret = 0;
}
else {
status = kStatus_SSS_Fail;
}
if (status == kStatus_SSS_Success) {
keyId = se050_allocate_key(SE050_CURVE25519_KEY);
status = sss_key_object_allocate_handle(&ref_public_key,
keyId, kSSS_KeyPart_Public, kSSS_CipherType_EC_MONTGOMERY,
keySize, kKeyObject_Mode_Transient);
}
if (status == kStatus_SSS_Success) {
keyCreated = 1;
status = sss_key_store_set_key(&host_keystore, &ref_public_key,
derBuf, derSz, keySize * 8, NULL, 0);
}
}
else {
status = sss_key_object_get_handle(&ref_public_key, keyId);
}
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&deriveKey, &host_keystore);
}
if (status == kStatus_SSS_Success) {
int keyIdAes = se050_allocate_key(SE050_AES_KEY);
deriveKeyCreated = 1;
status = sss_key_object_allocate_handle(&deriveKey,
keyIdAes,
kSSS_KeyPart_Default,
kSSS_CipherType_Binary,
keySize,
kKeyObject_Mode_Transient);
}
if (status == kStatus_SSS_Success) {
status = sss_derive_key_context_init(&ctx_derive_key, cfg_se050_i2c_pi,
&ref_private_key, kAlgorithm_SSS_ECDH,
kMode_SSS_ComputeSharedSecret);
if (status == kStatus_SSS_Success) {
status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key,
&deriveKey);
}
if (status == kStatus_SSS_Success) {
size_t outlenSz = sizeof(out->point);
size_t outlenSzBits = outlenSz * 8;
/* derived key export */
status = sss_key_store_get_key(&host_keystore, &deriveKey,
out->point, &outlenSz, &outlenSzBits);
out->pointSz = (word32)outlenSz;
(void)outlenSzBits; /* not used */
}
sss_derive_key_context_free(&ctx_derive_key);
}
if (deriveKeyCreated) {
sss_key_store_erase_key(&host_keystore, &deriveKey);
sss_key_object_free(&deriveKey);
}
if (status == kStatus_SSS_Success) {
public_key->keyId = keyId;
ret = 0;
}
else {
if (keyCreated) {
sss_key_store_erase_key(&host_keystore, &public_key);
sss_key_object_free(&public_key);
}
if (ret == 0)
ret = WC_HW_E;
}
wolfSSL_CryptHwMutexUnLock();
#ifdef SE050_DEBUG
printf("se050_curve25519_shared_secret: ret %d, outlen %d\n",
ret, out->pointSz);
#endif
return ret;
}
void se050_curve25519_free_key(struct curve25519_key* key)
{
sss_status_t status;
sss_object_t newKey;
sss_key_store_t host_keystore;
#ifdef SE050_DEBUG
printf("se050_curve25519_free_key: %p, id %d\n", key, key->keyId);
#endif
if (cfg_se050_i2c_pi == NULL) {
return;
}
if (key->keyId <= 0) {
return;
}
if (wolfSSL_CryptHwMutexLock() != 0) {
return;
}
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
if (status == kStatus_SSS_Success) {
status = sss_key_store_allocate(&host_keystore,
SE050_KEYSTOREID_CURVE25519);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&newKey, &host_keystore);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_get_handle(&newKey, key->keyId);
}
if (status == kStatus_SSS_Success) {
sss_key_object_free(&newKey);
key->keyId = -1;
}
wolfSSL_CryptHwMutexUnLock();
}
#endif /* HAVE_CURVE25519 */
#endif /* WOLFSSL_SE050 */

View File

@@ -145,7 +145,9 @@ where 0 <= L < 2^64.
#ifdef WOLFSSL_DEVCRYPTO_HASH
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#if defined(USE_INTEL_SPEEDUP)
@@ -587,7 +589,6 @@ static int InitSha256(wc_Sha256* sha256)
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
{
if (sha256 == NULL) {
@@ -1418,7 +1419,6 @@ static int InitSha256(wc_Sha256* sha256)
}
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
{
if (sha224 == NULL) {

View File

@@ -47,10 +47,6 @@
#include <wolfssl/wolfcrypt/cryptocb.h>
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
#define USE_SLOW_SHA512
@@ -151,6 +147,10 @@
#include <wolfcrypt/src/misc.c>
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#if defined(USE_INTEL_SPEEDUP)
#if defined(__GNUC__) && ((__GNUC__ < 4) || \