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:
parent
55b1ced783
commit
eaca90db28
391
src/internal.c
391
src/internal.c
@ -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;
|
||||
|
2
src/io.c
2
src/io.c
@ -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>
|
||||
|
65
src/ssl.c
65
src/ssl.c
@ -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
|
||||
|
@ -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
10
wolfcrypt/src/asn.c
Normal file → Executable 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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
8
wolfcrypt/src/port/atmel/README.md
Normal file
8
wolfcrypt/src/port/atmel/README.md
Normal 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
244
wolfcrypt/src/port/atmel/atmel.c
Executable 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
17
wolfcrypt/src/random.c
Normal file → Executable 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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
66
wolfssl/wolfcrypt/port/atmel/atmel.h
Executable file
66
wolfssl/wolfcrypt/port/atmel/atmel.h
Executable 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_ */
|
Loading…
Reference in New Issue
Block a user