New Atmel support (WOLFSSL_ATMEL) and port for ATECC508A (WOLFSSL_ATECC508A). Adds wolfCrypt support for ECC Hardware acceleration using the ATECC508A. Adds new PK callback for ECC shared secret. Fixed missing "wc_InitRng_ex" when using "CUSTOM_RAND_GENERATE_BLOCK". Added ATECC508A RNG block function for P-RNG bypass ability. Added internal "wolfSSL_GetEccPrivateKey" function for getting reference to private key for ECC shared secret (used in test.h for testing PK_CALLBACK mode). Added README.md for using the Atmel ATECC508A port.

This commit is contained in:
David Garske 2016-08-29 10:02:06 -07:00
parent 55b1ced783
commit eaca90db28
17 changed files with 1006 additions and 185 deletions

View File

@ -2966,15 +2966,29 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
}
int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
byte* out, word32* outSz)
byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen,
int side, void* ctx)
{
int ret;
(void)ssl;
(void)pubKeyDer;
(void)pubKeySz;
(void)side;
(void)ctx;
WOLFSSL_ENTER("EccSharedSecret");
ret = wc_ecc_shared_secret(priv_key, pub_key, out, outSz);
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb) {
ret = ssl->ctx->EccSharedSecretCb(ssl, pubKeyDer, pubKeySz,
out, outlen, side, ctx);
}
else
#endif
{
ret = wc_ecc_shared_secret(priv_key, pub_key, out, outlen);
}
/* Handle async pending response */
#if defined(WOLFSSL_ASYNC_CRYPT)
@ -15437,20 +15451,25 @@ int SendClientKeyExchange(WOLFSSL* ssl)
ERROR_OUT(NO_PEER_KEY, exit_scke);
}
/* create private key */
ssl->sigKey = XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->sigKey == NULL) {
ERROR_OUT(MEMORY_E, exit_scke);
}
ssl->sigType = DYNAMIC_TYPE_ECC;
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
/* create private key */
ssl->sigKey = XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->sigKey == NULL) {
ERROR_OUT(MEMORY_E, exit_scke);
}
ssl->sigType = DYNAMIC_TYPE_ECC;
ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_scke;
ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_scke;
}
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey);
}
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey);
break;
#endif /* HAVE_ECC && !NO_PSK */
#ifdef HAVE_NTRU
@ -15463,41 +15482,46 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#ifdef HAVE_ECC
case ecc_diffie_hellman_kea:
{
ecc_key* peerKey;
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
ecc_key* peerKey;
if (ssl->specs.static_ecdh) {
/* TODO: EccDsa is really fixed Ecc change naming */
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) {
if (ssl->specs.static_ecdh) {
/* TODO: EccDsa is really fixed Ecc change naming */
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) {
ERROR_OUT(NO_PEER_KEY, exit_scke);
}
peerKey = ssl->peerEccDsaKey;
}
else {
if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
!ssl->peerEccKey->dp) {
ERROR_OUT(NO_PEER_KEY, exit_scke);
}
peerKey = ssl->peerEccKey;
}
if (peerKey == NULL) {
ERROR_OUT(NO_PEER_KEY, exit_scke);
}
peerKey = ssl->peerEccDsaKey;
}
else {
if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
!ssl->peerEccKey->dp) {
ERROR_OUT(NO_PEER_KEY, exit_scke);
/* create private key */
ssl->sigKey = XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->sigKey == NULL) {
ERROR_OUT(MEMORY_E, exit_scke);
}
peerKey = ssl->peerEccKey;
}
if (peerKey == NULL) {
ERROR_OUT(NO_PEER_KEY, exit_scke);
}
ssl->sigType = DYNAMIC_TYPE_ECC;
/* create private key */
ssl->sigKey = XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->sigKey == NULL) {
ERROR_OUT(MEMORY_E, exit_scke);
ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_scke;
}
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey);
}
ssl->sigType = DYNAMIC_TYPE_ECC;
ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_scke;
}
ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey);
break;
}
#endif /* HAVE_ECC */
@ -15649,21 +15673,20 @@ int SendClientKeyExchange(WOLFSSL* ssl)
output += esSz;
encSz = esSz + OPAQUE16_LEN;
/* Place ECC key in output buffer, leaving room for size */
/* length is used for public key size */
*length = MAX_ENCRYPT_SZ;
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
output + 1, length);
if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
/* Place ECC key in buffer, leaving room for size */
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
output + OPAQUE8_LEN, length);
if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
}
}
*output = (byte)*length; /* place size of key in output buffer */
encSz += *length + 1;
/* Create shared ECC key leaving room at the begining
of buffer for size of shared key. Note sizeof
preMasterSecret is ENCRYPT_LEN currently 512 */
*length = sizeof(ssl->arrays->preMasterSecret) - OPAQUE16_LEN;
break;
}
#endif /* HAVE_ECC && !NO_PSK */
@ -15684,18 +15707,17 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#ifdef HAVE_ECC
case ecc_diffie_hellman_kea:
{
/* precede export with 1 byte length */
*length = MAX_ENCRYPT_SZ;
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
encSecret + 1, length);
if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
/* Place ECC key in buffer, leaving room for size */
ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey,
encSecret + OPAQUE8_LEN, &encSz);
if (ret != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
}
}
encSecret[0] = (byte)*length;
encSz = *length + 1;
*length = sizeof(ssl->arrays->preMasterSecret);
break;
}
#endif /* HAVE_ECC */
@ -15778,10 +15800,22 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#if defined(HAVE_ECC) && !defined(NO_PSK)
case ecdhe_psk_kea:
{
ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey,
ssl->peerEccKey,
/* Create shared ECC key leaving room at the begining
of buffer for size of shared key. */
ssl->arrays->preMasterSz = ENCRYPT_LEN - OPAQUE16_LEN;
ret = EccSharedSecret(ssl,
(ecc_key*)ssl->sigKey, ssl->peerEccKey,
output + OPAQUE8_LEN, length,
ssl->arrays->preMasterSecret + OPAQUE16_LEN,
length);
&ssl->arrays->preMasterSz,
WOLFSSL_CLIENT_END,
#ifdef HAVE_PK_CALLBACKS
ssl->EccSharedSecretCtx
#else
NULL
#endif
);
break;
}
#endif /* HAVE_ECC && !NO_PSK */
@ -15815,8 +15849,20 @@ int SendClientKeyExchange(WOLFSSL* ssl)
ecc_key* peerKey = (ssl->specs.static_ecdh) ?
ssl->peerEccDsaKey : ssl->peerEccKey;
ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, peerKey,
ssl->arrays->preMasterSecret, length);
ssl->arrays->preMasterSz = ENCRYPT_LEN;
ret = EccSharedSecret(ssl,
(ecc_key*)ssl->sigKey, peerKey,
encSecret + OPAQUE8_LEN, &encSz,
ssl->arrays->preMasterSecret,
&ssl->arrays->preMasterSz,
WOLFSSL_CLIENT_END,
#ifdef HAVE_PK_CALLBACKS
ssl->EccSharedSecretCtx
#else
NULL
#endif
);
break;
}
#endif /* HAVE_ECC */
@ -15861,6 +15907,11 @@ int SendClientKeyExchange(WOLFSSL* ssl)
{
byte* pms = ssl->arrays->preMasterSecret;
/* validate args */
if (output == NULL || *length == 0) {
ERROR_OUT(BAD_FUNC_ARG, exit_scke);
}
c16toa((word16)*length, output);
encSz += *length + OPAQUE16_LEN;
c16toa((word16)ssl->arrays->preMasterSz, pms);
@ -15884,10 +15935,19 @@ int SendClientKeyExchange(WOLFSSL* ssl)
{
byte* pms = ssl->arrays->preMasterSecret;
/* validate args */
if (output == NULL || *length > ENCRYPT_LEN) {
ERROR_OUT(BAD_FUNC_ARG, exit_scke);
}
/* place size of public key in output buffer */
*output = (byte)*length;
encSz += *length + OPAQUE8_LEN;
/* Create pre master secret is the concatination of
eccSize + eccSharedKey + pskSize + pskKey */
c16toa((word16)*length, pms);
ssl->arrays->preMasterSz += OPAQUE16_LEN + *length;
c16toa((word16)ssl->arrays->preMasterSz, pms);
ssl->arrays->preMasterSz += OPAQUE16_LEN;
pms += ssl->arrays->preMasterSz;
c16toa((word16)ssl->arrays->psk_keySz, pms);
@ -15910,7 +15970,9 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#ifdef HAVE_ECC
case ecc_diffie_hellman_kea:
{
ssl->arrays->preMasterSz = *length;
/* place size of public key in buffer */
*encSecret = (byte)encSz;
encSz += OPAQUE8_LEN;
break;
}
#endif /* HAVE_ECC */
@ -19839,11 +19901,6 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_ECC
case ecc_diffie_hellman_kea:
{
if (!ssl->specs.static_ecdh &&
ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
}
break;
}
#endif /* HAVE_ECC */
@ -19872,11 +19929,6 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG("No server PSK callback set");
ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
}
if (ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
}
break;
}
#endif /* HAVE_ECC && !NO_PSK */
@ -20093,42 +20145,47 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(BUFFER_ERROR, exit_dcke);
}
if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
if (!ssl->specs.static_ecdh &&
ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
}
if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke);
/* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke);
}
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
}
} else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0;
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
}
}
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
}
} else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0;
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey,
private_key->dp->id)) {
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
}
ssl->peerEccKeyPresent = 1;
}
if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey,
private_key->dp->id)) {
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
}
idx += length;
ssl->peerEccKeyPresent = 1;
ssl->sigLen = sizeof(ssl->arrays->preMasterSecret);
if (ret != 0) {
goto exit_dcke;
}
break;
}
#endif /* HAVE_ECC */
@ -20229,42 +20286,45 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(BUFFER_ERROR, exit_dcke);
}
if (ssl->peerEccKey == NULL) {
/* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->EccSharedSecretCb == NULL)
#endif
{
if (ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
}
if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke);
/* alloc/init on demand */
ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->peerEccKey == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
ERROR_OUT(MEMORY_E, exit_dcke);
}
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
}
}
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0;
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
}
}
} else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKeyPresent = 0;
ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
ssl->devId);
if (ret != 0) {
goto exit_dcke;
if (wc_ecc_import_x963_ex(input + idx, length,
ssl->peerEccKey, ssl->eccTempKey->dp->id)) {
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
}
}
if (wc_ecc_import_x963_ex(input + idx, length,
ssl->peerEccKey, ssl->eccTempKey->dp->id)) {
ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
}
idx += length;
ssl->peerEccKeyPresent = 1;
/* Note sizeof preMasterSecret is ENCRYPT_LEN currently 512 */
ssl->sigLen = sizeof(ssl->arrays->preMasterSecret);
if (ssl->eccTempKeyPresent == 0) {
WOLFSSL_MSG("Ecc ephemeral key not made correctly");
ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
ssl->peerEccKeyPresent = 1;
}
break;
}
@ -20325,9 +20385,21 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
private_key = (ecc_key*)ssl->sigKey;
}
ssl->arrays->preMasterSz = ENCRYPT_LEN;
/* Generate shared secret */
ret = EccSharedSecret(ssl, private_key, ssl->peerEccKey,
ssl->arrays->preMasterSecret, &ssl->sigLen);
ret = EccSharedSecret(ssl,
private_key, ssl->peerEccKey,
input + idx, &length,
ssl->arrays->preMasterSecret,
&ssl->arrays->preMasterSz,
WOLFSSL_SERVER_END,
#ifdef HAVE_PK_CALLBACKS
ssl->EccSharedSecretCtx
#else
NULL
#endif
);
break;
}
#endif /* HAVE_ECC */
@ -20377,12 +20449,21 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#if defined(HAVE_ECC) && !defined(NO_PSK)
case ecdhe_psk_kea:
{
ssl->sigLen = ENCRYPT_LEN - OPAQUE16_LEN;
/* Generate shared secret */
ret = EccSharedSecret(ssl,
ssl->eccTempKey,
ssl->peerEccKey,
ssl->eccTempKey, ssl->peerEccKey,
input + idx, &length,
ssl->arrays->preMasterSecret + OPAQUE16_LEN,
&ssl->sigLen);
&ssl->sigLen,
WOLFSSL_SERVER_END,
#ifdef HAVE_PK_CALLBACKS
ssl->EccSharedSecretCtx
#else
NULL
#endif
);
break;
}
#endif /* HAVE_ECC && !NO_PSK */
@ -20436,7 +20517,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_ECC
case ecc_diffie_hellman_kea:
{
ssl->arrays->preMasterSz = ssl->sigLen;
/* skip past the imported peer key */
idx += length;
break;
}
#endif /* HAVE_ECC */
@ -20483,6 +20565,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
{
byte* pms = ssl->arrays->preMasterSecret;
/* skip past the imported peer key */
idx += length;
/* Add preMasterSecret */
c16toa((word16)ssl->sigLen, pms);
ssl->arrays->preMasterSz += OPAQUE16_LEN + ssl->sigLen;

View File

@ -80,6 +80,8 @@
#elif defined(WOLFSSL_VXWORKS)
#include <sockLib.h>
#include <errno.h>
#elif defined(WOLFSSL_ATMEL)
#include "socket/include/socket.h"
#else
#include <sys/types.h>
#include <errno.h>

View File

@ -958,6 +958,51 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
ssl->options.minEccKeySz = keySz / 8;
return SSL_SUCCESS;
}
/* Gets ECC key for shared secret callback testing
* Client side: returns peer key
* Server side: returns private key
*/
int wolfSSL_GetEccKey(WOLFSSL* ssl, struct ecc_key** key)
{
if (ssl == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
if (ssl->options.side == WOLFSSL_CLIENT_END) {
if (ssl->specs.static_ecdh) {
if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
!ssl->peerEccDsaKey->dp) {
return NO_PEER_KEY;
}
*key = (struct ecc_key*)ssl->peerEccDsaKey;
}
else {
if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
!ssl->peerEccKey->dp) {
return NO_PEER_KEY;
}
*key = (struct ecc_key*)ssl->peerEccKey;
}
}
else if (ssl->options.side == WOLFSSL_SERVER_END) {
if (ssl->specs.static_ecdh) {
if (ssl->sigKey == NULL) {
return NO_PRIVATE_KEY;
}
*key = (struct ecc_key*)ssl->sigKey;
}
else {
if (!ssl->eccTempKeyPresent) {
return NO_PRIVATE_KEY;
}
*key = (struct ecc_key*)ssl->eccTempKey;
}
}
return 0;
}
#endif /* !NO_RSA */
#ifndef NO_RSA
@ -18202,6 +18247,26 @@ void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
return NULL;
}
void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
{
if (ctx)
ctx->EccSharedSecretCb = cb;
}
void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->EccSharedSecretCtx = ctx;
}
void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->EccSharedSecretCtx;
return NULL;
}
#endif /* HAVE_ECC */
#ifndef NO_RSA

View File

@ -2530,7 +2530,8 @@ void bench_ed25519KeySign(void)
}
#elif defined(WOLFSSL_IAR_ARM_TIME) || defined (WOLFSSL_MDK_ARM) || defined(WOLFSSL_USER_CURRTIME)
extern double current_time(int reset);
/* declared above at line 189 */
/* extern double current_time(int reset); */
#elif defined FREERTOS

10
wolfcrypt/src/asn.c Normal file → Executable file
View File

@ -149,10 +149,16 @@ ASN Options:
#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
#include <time.h>
#ifndef XTIME
#define XTIME(t1) 0
#define XTIME(t1) ksdk_time((t1))
#endif
#define XGMTIME(c, t) gmtime((c))
#elif defined(WOLFSSL_ATMEL)
#define XTIME(t1) atmel_get_curr_time_and_date((t1))
#define WOLFSSL_GMTIME
#define USE_WOLF_TM
#define USE_WOLF_TIME_T
#elif defined(IDIRECT_DEV_TIME)
/*Gets the timestamp from cloak software owned by VT iDirect
in place of time() from <time.h> */
@ -224,6 +230,8 @@ ASN Options:
#elif defined(TIME_OVERRIDES)
extern time_t XTIME(time_t * timer);
extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
#elif defined(WOLFSSL_GMTIME)
struct tm* gmtime(const time_t* timer);
#endif

View File

@ -918,6 +918,12 @@ const ecc_set_type ecc_sets[] = {
static oid_cache_t ecc_oid_cache[sizeof(ecc_sets)/sizeof(ecc_set_type)];
#endif
#ifdef HAVE_COMP_KEY
static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
#endif
#ifndef WOLFSSL_ATECC508A
int ecc_map(ecc_point*, mp_int*, mp_digit);
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
mp_int* a, mp_int* modulus, mp_digit mp);
@ -932,9 +938,7 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
int mp_jacobi(mp_int* a, mp_int* n, int* c);
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
#ifdef HAVE_COMP_KEY
static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
#endif
#endif /* WOLFSSL_ATECC508A */
static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
@ -972,6 +976,7 @@ static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
return 0;
}
#ifndef WOLFSSL_ATECC508A
/* helper for either lib */
static int get_digit_count(mp_int* a)
@ -2263,6 +2268,9 @@ int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
return MP_EQ;
}
#endif /* !WOLFSSL_ATECC508A */
/** Returns whether an ECC idx is valid or not
n The idx number to check
return 1 if valid, 0 if not
@ -2295,11 +2303,13 @@ int wc_ecc_is_valid_idx(int n)
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen)
{
int err = 0;
#ifndef WOLFSSL_ATECC508A
word32 x = 0;
ecc_point* result;
mp_int prime;
mp_int a;
int err;
#endif /* !WOLFSSL_ATECC508A */
if (private_key == NULL || public_key == NULL || out == NULL ||
outlen == NULL) {
@ -2340,6 +2350,15 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
}
#endif
#ifdef WOLFSSL_ATECC508A
err = atcatls_ecdh(private_key->slot, public_key->pubkey, out);
if (err != ATCA_SUCCESS) {
err = BAD_COND_E;
}
*outlen = private_key->dp->size;
#else
/* make new point */
result = wc_ecc_new_point_h(private_key->heap);
if (result == NULL) {
@ -2379,9 +2398,13 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
#endif
wc_ecc_del_point_h(result, private_key->heap);
#endif /* WOLFSSL_ATECC508A */
return err;
}
#ifndef WOLFSSL_ATECC508A
/**
Create an ECC shared secret between private key and public point
private_key The private ECC key (heap hint based on private key)
@ -2455,8 +2478,10 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point,
return err;
}
#endif /* !WOLFSSL_ATECC508A */
#endif /* HAVE_ECC_DHE */
#ifndef WOLFSSL_ATECC508A
/* return 1 if point is at infinity, 0 if not, < 0 on error */
int wc_ecc_point_is_at_infinity(ecc_point* p)
{
@ -2469,10 +2494,13 @@ int wc_ecc_point_is_at_infinity(ecc_point* p)
return 0;
}
#endif /* WOLFSSL_ATECC508A */
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
{
int err;
#ifndef WOLFSSL_ATECC508A
ecc_point* base = NULL;
mp_int prime;
mp_int a;
@ -2482,6 +2510,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
#else
byte buf[ECC_MAXSIZE_GEN];
#endif
#endif /* !WOLFSSL_ATECC508A */
if (key == NULL || rng == NULL) {
return BAD_FUNC_ARG;
@ -2510,6 +2539,15 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
}
#endif
#ifdef WOLFSSL_ATECC508A
key->type = ECC_PRIVATEKEY;
err = atcatls_create_key(key->slot, key->pubkey);
if (err != ATCA_SUCCESS) {
err = BAD_COND_E;
}
#else
#ifdef WOLFSSL_SMALL_STACK
buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL)
@ -2628,6 +2666,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
#ifdef WOLFSSL_SMALL_STACK
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#endif /* WOLFSSL_ATECC508A */
return err;
}
@ -2721,6 +2760,13 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
key->dp = NULL;
key->idx = 0;
#ifdef WOLFSSL_ATECC508A
key->slot = atmel_ecc_alloc();
if (key->slot == ATECC_INVALID_SLOT) {
return ECC_BAD_ARG_E;
}
#else
#ifndef USE_FAST_MATH
key->pubkey.x->dp = NULL;
key->pubkey.y->dp = NULL;
@ -2742,6 +2788,8 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
alt_fp_init(key->pubkey.z);
#endif
#endif /* WOLFSSL_ATECC508A */
#ifdef WOLFSSL_HEAP_TEST
key->heap = (void*)WOLFSSL_HEAP_TEST;
#else
@ -2810,16 +2858,61 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
}
#endif
/* is this a private key? */
if (key->type != ECC_PRIVATEKEY)
return ECC_BAD_ARG_E;
/* is the IDX valid ? */
if (wc_ecc_is_valid_idx(key->idx) != 1)
return ECC_BAD_ARG_E;
if ((err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL)) != MP_OKAY) {
return err;
}
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s);
if (err == MP_OKAY) {
/* encoded with DSA header */
err = StoreECC_DSA_Sig(out, outlen, &r, &s);
#ifdef WOLFSSL_ATECC508A
/* Check args */
if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) {
err = ECC_BAD_ARG_E;
goto exit_sign;
}
/* Sign: Result is 32-bytes of R then 32-bytes of S */
err = atcatls_sign(key->slot, in, out);
if (err != ATCA_SUCCESS) {
err = BAD_COND_E;
goto exit_sign;
}
/* Load R and S */
err = mp_read_unsigned_bin(&r, &out[0], ATECC_KEY_SIZE);
if (err != MP_OKAY) {
goto exit_sign;
}
err = mp_read_unsigned_bin(&s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE);
if (err != MP_OKAY) {
goto exit_sign;
}
/* Check for zeros */
if (mp_iszero(&r) || mp_iszero(&s)) {
err = MP_ZERO_E;
goto exit_sign;
}
#else
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s);
if (err != MP_OKAY) {
goto exit_sign;
}
err = StoreECC_DSA_Sig(out, outlen, &r, &s);
#endif /* WOLFSSL_ATECC508A */
exit_sign:
#ifndef USE_FAST_MATH
mp_clear(&r);
mp_clear(&s);
@ -2829,6 +2922,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
}
#endif /* !NO_ASN */
#ifndef WOLFSSL_ATECC508A
/**
Sign a message digest
in The message digest to sign
@ -2937,6 +3032,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
return err;
}
#endif /* !WOLFSSL_ATECC508A */
#endif /* HAVE_ECC_SIGN */
/**
@ -2955,13 +3051,20 @@ void wc_ecc_free(ecc_key* key)
}
#endif
#ifdef WOLFSSL_ATECC508A
atmel_ecc_free(key->slot);
key->slot = -1;
#else
mp_clear(key->pubkey.x);
mp_clear(key->pubkey.y);
mp_clear(key->pubkey.z);
mp_forcezero(&key->k);
#endif /* !WOLFSSL_ATECC508A */
}
#ifndef WOLFSSL_ATECC508A
#ifdef ECC_SHAMIR
/** Computes kA*A + kB*B = C using Shamir's Trick
@ -3187,8 +3290,8 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA,
return err;
}
#endif /* ECC_SHAMIR */
#endif /* !WOLFSSL_ATECC508A */
#ifdef HAVE_ECC_VERIFY
@ -3219,6 +3322,9 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
mp_int r;
mp_int s;
int err;
#ifdef WOLFSSL_ATECC508A
byte sigRS[ATECC_KEY_SIZE*2];
#endif
if (sig == NULL || hash == NULL || stat == NULL || key == NULL) {
return ECC_BAD_ARG_E;
@ -3255,9 +3361,33 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
XMEMSET(&s, 0, sizeof(s));
err = DecodeECC_DSA_Sig(sig, siglen, &r, &s);
if (err != 0) {
goto exit_verify;
}
if (err == MP_OKAY)
err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key);
#ifdef WOLFSSL_ATECC508A
/* Extract R and S */
err = mp_to_unsigned_bin(&r, &sigRS[0]);
if (err != MP_OKAY) {
goto exit_verify;
}
err = mp_to_unsigned_bin(&s, &sigRS[ATECC_KEY_SIZE]);
if (err != MP_OKAY) {
goto exit_verify;
}
err = atcatls_verify(hash, sigRS, key->pubkey, (bool*)stat);
if (err != ATCA_SUCCESS) {
err = BAD_COND_E;
}
#else
err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key);
#endif /* WOLFSSL_ATECC508A */
exit_verify:
#ifndef USE_FAST_MATH
mp_clear(&r);
@ -3268,6 +3398,9 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
}
#endif /* !NO_ASN */
#ifndef WOLFSSL_ATECC508A
/**
Verify an ECC signature
r The signature R component to verify
@ -3442,9 +3575,11 @@ done:
return err;
}
#endif /* !WOLFSSL_ATECC508A */
#endif /* HAVE_ECC_VERIFY */
#ifdef HAVE_ECC_KEY_IMPORT
#ifndef WOLFSSL_ATECC508A
/* import point from der */
int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
ecc_point* point)
@ -3567,6 +3702,7 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
return err;
}
#endif /* !WOLFSSL_ATECC508A */
#endif /* HAVE_ECC_KEY_IMPORT */
#ifdef HAVE_ECC_KEY_EXPORT
@ -3574,13 +3710,15 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
word32* outLen)
{
int ret = MP_OKAY;
word32 numlen;
#ifndef WOLFSSL_ATECC508A
#ifdef WOLFSSL_SMALL_STACK
byte* buf;
#else
byte buf[ECC_BUFSIZE];
#endif
word32 numlen;
int ret = MP_OKAY;
#endif /* !WOLFSSL_ATECC508A */
if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
return ECC_BAD_ARG_E;
@ -3602,6 +3740,12 @@ int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
return BUFFER_E;
}
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
ret = BAD_COND_E;
#else
/* store byte 0x04 */
out[0] = 0x04;
@ -3633,6 +3777,7 @@ done:
#ifdef WOLFSSL_SMALL_STACK
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#endif /* WOLFSSL_ATECC508A */
return ret;
}
@ -3641,13 +3786,15 @@ done:
/* export public ECC key in ANSI X9.63 format */
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
{
word32 numlen;
int ret = MP_OKAY;
#ifndef WOLFSSL_ATECC508A
#ifdef WOLFSSL_SMALL_STACK
byte* buf;
#else
byte buf[ECC_BUFSIZE];
#endif
word32 numlen;
int ret = MP_OKAY;
#endif
/* return length needed only */
if (key != NULL && out == NULL && outLen != NULL) {
@ -3669,6 +3816,12 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
return BUFFER_E;
}
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
ret = BAD_COND_E;
#else
/* store byte 0x04 */
out[0] = 0x04;
@ -3700,6 +3853,7 @@ done:
#ifdef WOLFSSL_SMALL_STACK
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#endif /* WOLFSSL_ATECC508A */
return ret;
}
@ -3722,6 +3876,8 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
#endif /* HAVE_ECC_KEY_EXPORT */
#ifndef WOLFSSL_ATECC508A
/* is ecc point on curve described by dp ? */
static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
{
@ -3815,9 +3971,9 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime)
/* validate privkey * generator == pubkey, 0 on success */
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
{
int err = MP_OKAY;
ecc_point* base = NULL;
ecc_point* res = NULL;
int err;
if (key == NULL)
return BAD_FUNC_ARG;
@ -3863,13 +4019,21 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
/* check privkey generator helper, creates prime needed */
static int ecc_check_privkey_gen_helper(ecc_key* key)
{
int err = MP_OKAY;
#ifndef WOLFSSL_ATECC508A
mp_int prime;
mp_int a;
int err;
#endif /* !WOLFSSL_ATECC508A */
if (key == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
err = BAD_COND_E;
#else
err = mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL);
if (err != MP_OKAY)
return err;
@ -3886,6 +4050,7 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
mp_clear(&prime);
mp_clear(&a);
#endif
#endif /* WOLFSSL_ATECC508A */
return err;
}
@ -3918,18 +4083,28 @@ static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime,
return err;
}
#endif /* !WOLFSSL_ATECC508A */
/* perform sanity checks on ecc key validity, 0 on success */
int wc_ecc_check_key(ecc_key* key)
{
int err = MP_OKAY;
#ifndef WOLFSSL_ATECC508A
mp_int prime; /* used by multiple calls so let's cache */
mp_int a;
mp_int order; /* other callers have, so let's gen here */
int err;
#endif /* !WOLFSSL_ATECC508A */
if (key == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
err = BAD_COND_E;
#else
/* pubkey point cannot be at infinity */
if (wc_ecc_point_is_at_infinity(&key->pubkey))
return ECC_INF_E;
@ -3963,6 +4138,7 @@ int wc_ecc_check_key(ecc_key* key)
mp_clear(&a);
mp_clear(&prime);
#endif
#endif /* WOLFSSL_ATECC508A */
return err;
}
@ -3972,8 +4148,10 @@ int wc_ecc_check_key(ecc_key* key)
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
int curve_id)
{
int err;
int err = MP_OKAY;
#ifndef WOLFSSL_ATECC508A
int compressed = 0;
#endif /* !WOLFSSL_ATECC508A */
if (in == NULL || key == NULL)
return BAD_FUNC_ARG;
@ -3983,6 +4161,12 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
return ECC_BAD_ARG_E;
}
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
err = BAD_COND_E;
#else
/* init key */
#ifdef ALT_ECC_SIZE
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
@ -4107,6 +4291,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
mp_clear(key->pubkey.z);
mp_clear(&key->k);
}
#endif /* WOLFSSL_ATECC508A */
return err;
}
@ -4140,8 +4325,15 @@ int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
*outLen = numlen;
XMEMSET(out, 0, *outLen);
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
return BAD_COND_E;
#else
return mp_to_unsigned_bin(&key->k, out + (numlen -
mp_unsigned_bin_size(&key->k)));
#endif /* WOLFSSL_ATECC508A */
}
#endif /* HAVE_ECC_KEY_EXPORT */
@ -4155,8 +4347,16 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, const byte* pu
key->type = ECC_PRIVATEKEY;
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
return BAD_COND_E;
#else
ret = mp_read_unsigned_bin(&key->k, priv, privSz);
#endif /* WOLFSSL_ATECC508A */
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
if (ret == MP_OKAY)
ret = ecc_check_privkey_gen_helper(key);
@ -4222,7 +4422,7 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
const char* qy, const char* d, int curve_id)
{
int err;
int err = MP_OKAY;
if (key == NULL || qx == NULL || qy == NULL || d == NULL) {
return BAD_FUNC_ARG;
@ -4234,6 +4434,12 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
return err;
}
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
err = BAD_COND_E;
#else
/* init key */
#ifdef ALT_ECC_SIZE
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
@ -4278,6 +4484,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
mp_clear(key->pubkey.z);
mp_clear(&key->k);
}
#endif /* WOLFSSL_ATECC508A */
return err;
}
@ -6373,6 +6580,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef HAVE_COMP_KEY
#ifndef WOLFSSL_ATECC508A
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
* HAC pp. 73 Algorithm 2.149
@ -6664,6 +6872,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
return res;
}
#endif /* !WOLFSSL_ATECC508A */
/* export public ECC key in ANSI X9.63 format compressed */
@ -6685,6 +6894,12 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
return BUFFER_E;
}
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
ret = BAD_COND_E;
#else
/* store first byte */
out[0] = mp_isodd(key->pubkey.y) == MP_YES ? 0x03 : 0x02;
@ -6693,6 +6908,9 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
ret = mp_to_unsigned_bin(key->pubkey.x,
out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
*outLen = 1 + numlen;
#endif /* WOLFSSL_ATECC508A */
return ret;
}

View File

@ -47,7 +47,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/nrf51.c \
wolfcrypt/src/port/arm/armv8-aes.c \
wolfcrypt/src/port/arm/armv8-sha256.c \
wolfssl/wolfcrypt/port/nxp/ksdk_port.c
wolfssl/wolfcrypt/port/nxp/ksdk_port.c \
wolfcrypt/src/port/atmel/atmel.c \
wolfcrypt/src/port/atmel/README.md
if BUILD_CAVIUM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c

View File

@ -0,0 +1,8 @@
# Atmel ATECC508A Port
* Adds wolfCrypt support for ECC Hardware acceleration using the ATECC508A
* The new defines added for this port are: `WOLFSSL_ATMEL` and `WOLFSSL_ATECC508A`.
* Adds new PK callback for Pre Master Secret.
For details see our [wolfSSL Atmel ATECC508A](wolfhttps://wolfssl.com/wolfSSL/wolfssl-atmel.html) page.

244
wolfcrypt/src/port/atmel/atmel.c Executable file
View File

@ -0,0 +1,244 @@
/* atmel.c
*
* Copyright (C) 2006-2016 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#ifdef WOLFSSL_ATMEL
#include <wolfssl/wolfcrypt/memory.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/ssl.h>
#include <wolfssl/internal.h>
#define Aes Aes_Remap
#define Gmac Gmac_Remap
#include "asf.h"
#undef Aes
#undef Gmac
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
static bool mAtcaInitDone = 0;
#ifdef WOLFSSL_ATECC508A
/* List of available key slots */
static int mSlotList[ATECC_MAX_SLOT+1];
/**
* \brief Structure to contain certificate information.
*/
t_atcert atcert = {
.signer_ca_size = 512,
.signer_ca = { 0 },
.signer_ca_pubkey = { 0 },
.end_user_size = 512,
.end_user = { 0 },
.end_user_pubkey = { 0 }
};
static int atmel_init_enc_key(void);
#endif /* WOLFSSL_ATECC508A */
/**
* \brief Generate random number to be used for hash.
*/
int atmel_get_random_number(uint32_t count, uint8_t* rand_out)
{
int ret = 0;
#ifdef WOLFSSL_ATECC508A
uint8_t i = 0;
uint32_t copy_count = 0;
uint8_t rng_buffer[RANDOM_NUM_SIZE];
if (rand_out == NULL) {
return -1;
}
while(i < count) {
ret = atcatls_random(rng_buffer);
if (ret != 0) {
WOLFSSL_MSG("Failed to create random number!");
return -1;
}
copy_count = (count - i > RANDOM_NUM_SIZE) ? RANDOM_NUM_SIZE : count - i;
XMEMCPY(&rand_out[i], rng_buffer, copy_count);
i += copy_count;
}
atcab_printbin_label((const uint8_t*)"\r\nRandom Number", rand_out, count);
#else
// TODO: Use on-board TRNG
#endif
return ret;
}
int atmel_get_random_block(unsigned char* output, unsigned int sz)
{
return atmel_get_random_number((uint32_t)sz, (uint8_t*)output);
}
extern struct rtc_module *_rtc_instance[RTC_INST_NUM];
long atmel_get_curr_time_and_date(long* tm)
{
(void)tm;
/* Get current time */
//struct rtc_calendar_time rtcTime;
//rtc_calendar_get_time(_rtc_instance[0], &rtcTime);
/* Convert rtc_calendar_time to seconds since UTC */
return 0;
}
#ifdef WOLFSSL_ATECC508A
/* Function to allocate new slot number */
int atmel_ecc_alloc(void)
{
int i, slot = -1;
for (i=0; i <= ATECC_MAX_SLOT; i++) {
/* Find free slot */
if (mSlotList[i] == ATECC_INVALID_SLOT) {
mSlotList[i] = i;
slot = i;
break;
}
}
return slot;
}
/* Function to return slot number to avail list */
void atmel_ecc_free(int slot)
{
if (slot >= 0 && slot <= ATECC_MAX_SLOT) {
/* Mark slot of free */
mSlotList[slot] = ATECC_INVALID_SLOT;
}
}
/**
* \brief Give enc key to read pms.
*/
static int atmel_set_enc_key(uint8_t* enckey, int16_t keysize)
{
if (enckey == NULL || keysize != ATECC_KEY_SIZE) {
return -1;
}
XMEMSET(enckey, 0xFF, keysize); // use default values
return SSL_SUCCESS;
}
/**
* \brief Write enc key before.
*/
static int atmel_init_enc_key(void)
{
uint8_t ret = 0;
uint8_t read_key[ATECC_KEY_SIZE] = { 0 };
XMEMSET(read_key, 0xFF, sizeof(read_key));
ret = atcab_write_bytes_slot(0x04, 0, read_key, sizeof(read_key));
if (ret != ATCA_SUCCESS) {
WOLFSSL_MSG("Failed to write key");
return -1;
}
ret = atcatlsfn_set_get_enckey(atmel_set_enc_key);
if (ret != ATCA_SUCCESS) {
WOLFSSL_MSG("Failed to set enckey");
return -1;
}
return ret;
}
static void atmel_show_rev_info(void)
{
#if 0
uint32_t revision = 0;
atcab_info((uint8_t*)&revision);
printf("ATECC508A Revision: %x\n", (unsigned int)revision);
#endif
}
#endif /* WOLFSSL_ATECC508A */
void atmel_init(void)
{
if (!mAtcaInitDone) {
#ifdef WOLFSSL_ATECC508A
int i;
/* Init the free slot list */
for (i=0; i<=ATECC_MAX_SLOT; i++) {
if (i == 0 || i == 2 || i == 7) {
/* ECC Slots (mark avail) */
mSlotList[i] = ATECC_INVALID_SLOT;
}
else {
mSlotList[i] = i;
}
}
/* Initialize the CryptoAuthLib to communicate with ATECC508A */
atcatls_init(&cfg_ateccx08a_i2c_default);
/* Init the I2C pipe encryption key. */
/* Value is generated/stored during pair for the ATECC508A and stored
on micro flash */
/* For this example its a fixed value */
if (atmel_init_enc_key() != ATCA_SUCCESS) {
WOLFSSL_MSG("Failed to initialize transport key");
}
/* show revision information */
atmel_show_rev_info();
/* Configure the ECC508 for use with TLS API funcitons */
#if 0
atcatls_device_provision();
#else
atcatls_config_default();
#endif
#endif /* WOLFSSL_ATECC508A */
mAtcaInitDone = 1;
}
}
#endif /* WOLFSSL_ATMEL */

17
wolfcrypt/src/random.c Normal file → Executable file
View File

@ -1619,6 +1619,23 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
return 0;
}
#elif defined(WOLFSSL_ATMEL)
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
int ret = 0;
(void)os;
if (output == NULL) {
return BUFFER_E;
}
ret = atmel_get_random_number(sz, output);
return ret;
}
#elif defined(NO_DEV_RANDOM)
#error "you need to write an os specific wc_GenerateSeed() here"

View File

@ -39,6 +39,10 @@
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif
#ifdef WOLFSSL_ATMEL
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
#endif
#ifdef _MSC_VER
/* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
#pragma warning(disable: 4996)
@ -50,7 +54,7 @@ static volatile int initRefCount = 0;
/* Used to initialize state for wolfcrypt
return 0 on success
*/
int wolfCrypt_Init()
int wolfCrypt_Init(void)
{
int ret = 0;
@ -77,6 +81,10 @@ int wolfCrypt_Init()
ksdk_port_init();
#endif
#ifdef WOLFSSL_ATMEL
atmel_init();
#endif
#ifdef WOLFSSL_ARMASM
WOLFSSL_MSG("Using ARM hardware acceleration");
#endif

View File

@ -2036,6 +2036,7 @@ struct WOLFSSL_CTX {
#ifdef HAVE_ECC
CallbackEccSign EccSignCb; /* User EccSign Callback handler */
CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */
CallbackEccSharedSecret EccSharedSecretCb; /* User EccVerify Callback handler */
#endif /* HAVE_ECC */
#ifndef NO_RSA
CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler */
@ -2850,6 +2851,7 @@ struct WOLFSSL {
#ifdef HAVE_ECC
void* EccSignCtx; /* Ecc Sign Callback Context */
void* EccVerifyCtx; /* Ecc Verify Callback Context */
void* EccSharedSecretCtx; /* Ecc Pms Callback Context */
#endif /* HAVE_ECC */
#ifndef NO_RSA
void* RsaSignCtx; /* Rsa Sign Callback Context */
@ -3044,7 +3046,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
const byte* out, word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz,
void* ctx);
WOLFSSL_LOCAL int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key,
ecc_key* pub_key, byte* out, word32* outSz);
ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out,
word32* outlen, int side, void* ctx);
#endif /* HAVE_ECC */
#ifdef WOLFSSL_TRUST_PEER_CERT

View File

@ -1043,6 +1043,8 @@ WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, short);
#ifdef HAVE_ECC
WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short);
WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short);
struct ecc_key;
WOLFSSL_API int wolfSSL_GetEccKey(WOLFSSL*, struct ecc_key**);
#endif /* NO_RSA */
WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short);
@ -1341,6 +1343,14 @@ WOLFSSL_API void wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX*, CallbackEccVerify);
WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl);
typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl,
unsigned char* pubKeyDer, unsigned int* pubKeySz,
unsigned char* out, unsigned int* outlen,
int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */
WOLFSSL_API void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX*, CallbackEccSharedSecret);
WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl);
typedef int (*CallbackRsaSign)(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, unsigned int* outSz,

View File

@ -1705,6 +1705,67 @@ static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
return ret;
}
static INLINE int myEccSharedSecret(WOLFSSL* ssl,
unsigned char* pubKeyDer, unsigned int* pubKeySz,
unsigned char* out, unsigned int* outlen,
int side, void* ctx)
{
int ret;
ecc_key* privKey;
ecc_key* pubKey;
ecc_key tmpKey;
(void)ssl;
(void)ctx;
ret = wc_ecc_init(&tmpKey);
if (ret != 0) {
return ret;
}
/* for client: create and export public key */
if (side == WOLFSSL_CLIENT_END) {
WC_RNG rng;
ret = wc_InitRng(&rng);
if (ret == 0) {
ret = wolfSSL_GetEccKey(ssl, &pubKey);
if (ret != 0) {
return ret;
}
privKey = &tmpKey;
ret = wc_ecc_make_key_ex(&rng, 0, privKey, pubKey->dp->id);
if (ret == 0) {
ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
}
wc_FreeRng(&rng);
}
}
/* for server: import public key */
else if (side == WOLFSSL_SERVER_END) {
ret = wolfSSL_GetEccKey(ssl, &privKey);
if (ret != 0) {
return ret;
}
pubKey = &tmpKey;
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, privKey->dp->id);
}
else {
ret = -1;
}
/* generate shared secret and return it */
if (ret == 0) {
ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
}
wc_ecc_free(&tmpKey);
return ret;
}
#endif /* HAVE_ECC */
#ifndef NO_RSA
@ -1834,6 +1895,7 @@ static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
#ifdef HAVE_ECC
wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
#endif /* HAVE_ECC */
#ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);

View File

@ -34,6 +34,11 @@
#include <wolfssl/wolfcrypt/async.h>
#endif
#ifdef WOLFSSL_ATECC508A
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
#endif /* WOLFSSL_ATECC508A */
#ifdef __cplusplus
extern "C" {
#endif
@ -205,7 +210,7 @@ typedef struct alt_fp_int {
int used, sign, size;
fp_digit dp[FP_SIZE_ECC];
} alt_fp_int;
#endif
#endif /* ALT_ECC_SIZE */
/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) =>
(x/z^2, y/z^3, 1) when interpreted as affine */
@ -224,16 +229,21 @@ typedef struct {
/* An ECC Key */
typedef struct {
typedef struct ecc_key {
int type; /* Public or Private */
int idx; /* Index into the ecc_sets[] for the parameters of
this curve if -1, this key is using user supplied
curve in dp */
const ecc_set_type* dp; /* domain parameters, either points to NIST
curves (idx >= 0) or user supplied */
void* heap; /* heap hint */
#ifdef WOLFSSL_ATECC508A
int slot; /* Key Slot Number (-1 unknown) */
byte pubkey[PUB_KEY_SIZE];
#else
ecc_point pubkey; /* public key */
mp_int k; /* private key */
void* heap; /* heap hint */
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
AsyncCryptDev asyncDev;
@ -257,9 +267,11 @@ int wc_ecc_check_key(ecc_key* key);
WOLFSSL_API
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen);
#ifndef WOLFSSL_ATECC508A
WOLFSSL_API
int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point,
byte* out, word32 *outlen);
#endif /* !WOLFSSL_ATECC508A */
#endif /* HAVE_ECC_DHE */
#ifdef HAVE_ECC_SIGN
@ -289,6 +301,11 @@ void wc_ecc_free(ecc_key* key);
WOLFSSL_API
void wc_ecc_fp_free(void);
WOLFSSL_API
int wc_ecc_is_valid_idx(int n);
#ifndef WOLFSSL_ATECC508A
WOLFSSL_API
ecc_point* wc_ecc_new_point(void);
WOLFSSL_API
@ -304,14 +321,14 @@ int wc_ecc_cmp_point(ecc_point* a, ecc_point *b);
WOLFSSL_API
int wc_ecc_point_is_at_infinity(ecc_point *p);
WOLFSSL_API
int wc_ecc_is_valid_idx(int n);
WOLFSSL_API
int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
mp_int* a, mp_int* modulus, int map);
WOLFSSL_LOCAL
int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
mp_int* a, mp_int* modulus, int map, void* heap);
#endif /* !WOLFSSL_ATECC508A */
#ifdef HAVE_ECC_KEY_EXPORT
/* ASN key helpers */
WOLFSSL_API
@ -346,12 +363,16 @@ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
#ifdef HAVE_ECC_KEY_EXPORT
WOLFSSL_API
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen);
#endif /* HAVE_ECC_KEY_EXPORT */
#ifdef HAVE_ECC_KEY_EXPORT
WOLFSSL_API
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point,
byte* out, word32* outLen);
#endif /* HAVE_ECC_KEY_EXPORT */
#ifdef HAVE_ECC_KEY_IMPORT
WOLFSSL_API
int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,

View File

@ -65,7 +65,8 @@ noinst_HEADERS+= \
wolfssl/wolfcrypt/port/ti/ti-hash.h \
wolfssl/wolfcrypt/port/ti/ti-ccm.h \
wolfssl/wolfcrypt/port/nrf51.h \
wolfssl/wolfcrypt/port/nxp/ksdk_port.h
wolfssl/wolfcrypt/port/nxp/ksdk_port.h \
wolfssl/wolfcrypt/port/atmel/atmel.h
if BUILD_CAVIUM
noinst_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h

View File

@ -0,0 +1,66 @@
/* atecc508.h
*
* Copyright (C) 2006-2016 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* 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-1301, USA
*/
#ifndef _ATECC508_H_
#define _ATECC508_H_
#include <stdint.h>
#ifdef WOLFSSL_ATECC508A
#undef SHA_BLOCK_SIZE
#define SHA_BLOCK_SIZE SHA_BLOCK_SIZE_REMAP
#include <cryptoauthlib.h>
#include <tls/atcatls.h>
#include <atcacert/atcacert_client.h>
#include <tls/atcatls_cfg.h>
#undef SHA_BLOCK_SIZE
#endif
/* ATECC508A only supports ECC-256 */
#define ATECC_KEY_SIZE (32)
#define ATECC_MAX_SLOT (0x7) /* Only use 0-7 */
#define ATECC_INVALID_SLOT (-1)
struct WOLFSSL;
struct WOLFSSL_X509_STORE_CTX;
// Cert Structure
typedef struct t_atcert {
uint32_t signer_ca_size;
uint8_t signer_ca[512];
uint8_t signer_ca_pubkey[64];
uint32_t end_user_size;
uint8_t end_user[512];
uint8_t end_user_pubkey[64];
} t_atcert;
extern t_atcert atcert;
/* Amtel port functions */
void atmel_init(void);
int atmel_get_random_number(uint32_t count, uint8_t* rand_out);
long atmel_get_curr_time_and_date(long* tm);
int atmel_ecc_alloc(void);
void atmel_ecc_free(int slot);
#endif /* _ATECC508_H_ */