forked from wolfSSL/wolfssl
Merge pull request #5573 from embhorn/zd14802
Add WOLFSSL_ATECC_TFLXTLS for Atmel port
This commit is contained in:
@ -21,6 +21,7 @@ Requires the Microchip CryptoAuthLib library. The examples in `wolfcrypt/src/por
|
|||||||
* `WOLFSSL_ATECC_ECDH_ENC`: Enable use of atcab_ecdh_enc() for encrypted ECDH.
|
* `WOLFSSL_ATECC_ECDH_ENC`: Enable use of atcab_ecdh_enc() for encrypted ECDH.
|
||||||
* `WOLFSSL_ATECC_ECDH_IOENC`: Enable use of atcab_ecdh_ioenc() for encrypted ECDH.
|
* `WOLFSSL_ATECC_ECDH_IOENC`: Enable use of atcab_ecdh_ioenc() for encrypted ECDH.
|
||||||
* `WOLFSSL_ATECC_TNGTLS`: Enable support for Microchip Trust&GO module configuration.
|
* `WOLFSSL_ATECC_TNGTLS`: Enable support for Microchip Trust&GO module configuration.
|
||||||
|
* `WOLFSSL_ATECC_TFLXTLS`: Enable support for Microchip TrustFLEX with custom PKI module configuration
|
||||||
* `WOLFSSL_ATECC_DEBUG`: Enable wolfSSL ATECC debug messages.
|
* `WOLFSSL_ATECC_DEBUG`: Enable wolfSSL ATECC debug messages.
|
||||||
* `WOLFSSL_ATMEL`: Enables ASF hooks seeding random data using the `atmel_get_random_number` function.
|
* `WOLFSSL_ATMEL`: Enables ASF hooks seeding random data using the `atmel_get_random_number` function.
|
||||||
* `WOLFSSL_ATMEL_TIME`: Enables the built-in `atmel_get_curr_time_and_date` function get getting time from ASF RTC.
|
* `WOLFSSL_ATMEL_TIME`: Enables the built-in `atmel_get_curr_time_and_date` function get getting time from ASF RTC.
|
||||||
|
@ -37,6 +37,12 @@
|
|||||||
#include "tng/tng_atcacert_client.h"
|
#include "tng/tng_atcacert_client.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_ATECC_TFLXTLS
|
||||||
|
#include "atcacert/atcacert_client.h"
|
||||||
|
#include "tng/cust_def_device.h"
|
||||||
|
#include "tng/cust_def_signer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NO_INLINE
|
#ifdef NO_INLINE
|
||||||
#include <wolfssl/wolfcrypt/misc.h>
|
#include <wolfssl/wolfcrypt/misc.h>
|
||||||
#else
|
#else
|
||||||
@ -98,33 +104,34 @@ static ATCAIfaceCfg cfg_ateccx08a_i2c_pi;
|
|||||||
*/
|
*/
|
||||||
int atmel_get_random_number(uint32_t count, uint8_t* rand_out)
|
int atmel_get_random_number(uint32_t count, uint8_t* rand_out)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
|
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint32_t copy_count = 0;
|
uint32_t copy_count = 0;
|
||||||
uint8_t rng_buffer[RANDOM_NUM_SIZE];
|
uint8_t rng_buffer[RANDOM_NUM_SIZE];
|
||||||
|
|
||||||
if (rand_out == NULL) {
|
if (rand_out == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
ret = atcab_random(rng_buffer);
|
ret = atcab_random(rng_buffer);
|
||||||
if (ret != ATCA_SUCCESS) {
|
if (ret != ATCA_SUCCESS) {
|
||||||
WOLFSSL_MSG("Failed to create random number!");
|
WOLFSSL_MSG("Failed to create random number!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
copy_count = (count - i > RANDOM_NUM_SIZE) ? RANDOM_NUM_SIZE : count - i;
|
copy_count =
|
||||||
XMEMCPY(&rand_out[i], rng_buffer, copy_count);
|
(count - i > RANDOM_NUM_SIZE) ? RANDOM_NUM_SIZE : count - i;
|
||||||
i += copy_count;
|
XMEMCPY(&rand_out[i], rng_buffer, copy_count);
|
||||||
}
|
i += copy_count;
|
||||||
#ifdef ATCAPRINTF
|
}
|
||||||
|
#ifdef ATCAPRINTF
|
||||||
atcab_printbin_label((const char*)"\r\nRandom Number", rand_out, count);
|
atcab_printbin_label((const char*)"\r\nRandom Number", rand_out, count);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/* TODO: Use on-board TRNG */
|
/* TODO: Use on-board TRNG */
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atmel_get_random_block(unsigned char* output, unsigned int sz)
|
int atmel_get_random_block(unsigned char* output, unsigned int sz)
|
||||||
@ -556,10 +563,10 @@ int atmel_init(void)
|
|||||||
/* Value is generated/stored during pair for the ATECC508A and stored
|
/* Value is generated/stored during pair for the ATECC508A and stored
|
||||||
on micro flash */
|
on micro flash */
|
||||||
/* For this example its a fixed value */
|
/* For this example its a fixed value */
|
||||||
if (atmel_init_enc_key() != 0) {
|
if (atmel_init_enc_key() != 0) {
|
||||||
WOLFSSL_MSG("Failed to initialize transport key");
|
WOLFSSL_MSG("Failed to initialize transport key");
|
||||||
return WC_HW_E;
|
return WC_HW_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mAtcaInitDone = 1;
|
mAtcaInitDone = 1;
|
||||||
@ -658,7 +665,8 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
|||||||
uint8_t* qy = &peerKey[ATECC_PUBKEY_SIZE/2];
|
uint8_t* qy = &peerKey[ATECC_PUBKEY_SIZE/2];
|
||||||
word32 qxLen = ATECC_PUBKEY_SIZE/2, qyLen = ATECC_PUBKEY_SIZE/2;
|
word32 qxLen = ATECC_PUBKEY_SIZE/2, qyLen = ATECC_PUBKEY_SIZE/2;
|
||||||
|
|
||||||
if (pubKeyDer == NULL || pubKeySz == NULL || out == NULL || outlen == NULL) {
|
if (pubKeyDer == NULL || pubKeySz == NULL ||
|
||||||
|
out == NULL || outlen == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,7 +704,8 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
|||||||
|
|
||||||
/* export peer's key as raw unsigned for hardware */
|
/* export peer's key as raw unsigned for hardware */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_ecc_export_public_raw(otherKey, qx, &qxLen, qy, &qyLen);
|
ret = wc_ecc_export_public_raw(otherKey, qx, &qxLen,
|
||||||
|
qy, &qyLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,7 +714,8 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
|||||||
tmpKey.slot = otherKey->slot;
|
tmpKey.slot = otherKey->slot;
|
||||||
|
|
||||||
/* import peer's key and export as raw unsigned for hardware */
|
/* import peer's key and export as raw unsigned for hardware */
|
||||||
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &tmpKey, ECC_SECP256R1);
|
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &tmpKey,
|
||||||
|
ECC_SECP256R1);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
||||||
}
|
}
|
||||||
@ -845,9 +855,9 @@ exit:
|
|||||||
/**
|
/**
|
||||||
* \brief Verify signature received from peers to prove peer's private key.
|
* \brief Verify signature received from peers to prove peer's private key.
|
||||||
*/
|
*/
|
||||||
int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, unsigned int sigSz,
|
int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig,
|
||||||
const byte* hash, unsigned int hashSz, const byte* key, unsigned int keySz, int* result,
|
unsigned int sigSz, const byte* hash, unsigned int hashSz, const byte* key,
|
||||||
void* ctx)
|
unsigned int keySz, int* result, void* ctx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ecc_key tmpKey;
|
ecc_key tmpKey;
|
||||||
@ -864,7 +874,8 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, unsigned int sigS
|
|||||||
(void)hashSz;
|
(void)hashSz;
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
|
|
||||||
if (ssl == NULL || key == NULL || sig == NULL || hash == NULL || result == NULL) {
|
if (ssl == NULL || key == NULL || sig == NULL ||
|
||||||
|
hash == NULL || result == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,72 +942,131 @@ exit:
|
|||||||
|
|
||||||
static int atcatls_set_certificates(WOLFSSL_CTX *ctx)
|
static int atcatls_set_certificates(WOLFSSL_CTX *ctx)
|
||||||
{
|
{
|
||||||
|
#ifndef ATCATLS_SIGNER_CERT_MAX_SIZE
|
||||||
|
#define ATCATLS_SIGNER_CERT_MAX_SIZE 0x250
|
||||||
|
#endif
|
||||||
|
#ifndef ATCATLS_DEVICE_CERT_MAX_SIZE
|
||||||
|
#define ATCATLS_DEVICE_CERT_MAX_SIZE 0x250
|
||||||
|
#endif
|
||||||
|
#ifndef ATCATLS_CERT_BUFF_MAX_SIZE
|
||||||
|
#define ATCATLS_CERT_BUFF_MAX_SIZE (ATCATLS_SIGNER_CERT_MAX_SIZE +\
|
||||||
|
ATCATLS_DEVICE_CERT_MAX_SIZE)
|
||||||
|
#endif
|
||||||
|
#ifndef ATCATLS_PUBKEY_BUFF_MAX_SIZE
|
||||||
|
#define ATCATLS_PUBKEY_BUFF_MAX_SIZE 65
|
||||||
|
#endif
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ATCA_STATUS status;
|
ATCA_STATUS status;
|
||||||
size_t signerCertSize=0;
|
size_t signerCertSize = ATCATLS_SIGNER_CERT_MAX_SIZE;
|
||||||
size_t deviceCertSize=0;
|
size_t deviceCertSize = ATCATLS_DEVICE_CERT_MAX_SIZE;
|
||||||
uint8_t *certBuffer;
|
uint8_t certBuffer[ATCATLS_CERT_BUFF_MAX_SIZE];
|
||||||
|
uint8_t signerBuffer[ATCATLS_SIGNER_CERT_MAX_SIZE];
|
||||||
|
#ifdef WOLFSSL_ATECC_TFLXTLS
|
||||||
|
uint8_t signerPubKeyBuffer[ATCATLS_PUBKEY_BUFF_MAX_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* fetch signer cert size */
|
#ifdef WOLFSSL_ATECC_TNGTLS
|
||||||
status=tng_atcacert_read_signer_cert(NULL, &signerCertSize);
|
ret = tng_atcacert_max_signer_cert_size(&signerCertSize);
|
||||||
if (ATCA_SUCCESS != status) {
|
if (ret != ATCACERT_E_SUCCESS) {
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
printf("Failed reading Signer cert size(0x%x)\r\n", status);
|
printf("Failed to get max signer cert size\r\n");
|
||||||
#endif
|
#endif
|
||||||
return WOLFSSL_FAILURE;
|
return ret;
|
||||||
|
}
|
||||||
|
else if (signerCertSize > ATCATLS_SIGNER_CERT_MAX_SIZE) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Signer CA cert buffer too small, need to increase at least"
|
||||||
|
" to %d\r\n", signerCertSize);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fetch device cert size */
|
/* Read TNGTLS signer cert */
|
||||||
status=tng_atcacert_read_device_cert(NULL, &deviceCertSize, NULL);
|
status = tng_atcacert_read_signer_cert(signerBuffer, &signerCertSize);
|
||||||
if (ATCA_SUCCESS != status) {
|
if (ATCA_SUCCESS != status) {
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
ret = atmel_ecc_translate_err(status);
|
||||||
printf("Failed reading device cert size(0x%x)\r\n", status);
|
|
||||||
#endif
|
|
||||||
return WOLFSSL_FAILURE;
|
|
||||||
}
|
|
||||||
certBuffer=(uint8_t*)XMALLOC(signerCertSize+deviceCertSize, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
if(NULL == certBuffer){
|
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
|
||||||
printf("Failed allocating space for certBuffer\r\n");
|
|
||||||
#endif
|
|
||||||
return WOLFSSL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read signer cert */
|
|
||||||
status = tng_atcacert_read_signer_cert(&certBuffer[deviceCertSize],
|
|
||||||
&signerCertSize);
|
|
||||||
if (ATCA_SUCCESS != status) {
|
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
|
||||||
printf("Error reading signer cert(0x%x)\r\n", status);
|
|
||||||
#endif
|
|
||||||
XFREE(certBuffer,NULL,DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
ret = atmel_ecc_translate_err(ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read device cert signed by the signer above */
|
/* Read device cert signed by the signer above */
|
||||||
status = tng_atcacert_read_device_cert(certBuffer, &deviceCertSize,
|
status = tng_atcacert_read_device_cert(certBuffer, &deviceCertSize,
|
||||||
&certBuffer[deviceCertSize]);
|
signerBuffer);
|
||||||
if (ATCA_SUCCESS != status) {
|
if (ATCA_SUCCESS != status) {
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
ret = atmel_ecc_translate_err(status);
|
||||||
printf("Error reading device cert(0x%x)\r\n", status);
|
|
||||||
#endif
|
|
||||||
XFREE(certBuffer,NULL,DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
ret = atmel_ecc_translate_err(ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
else if (deviceCertSize > ATCATLS_DEVICE_CERT_MAX_SIZE) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Device cert buffer too small, need to increase at least"
|
||||||
|
" to %d\r\n", deviceCertSize);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_ATECC_TFLXTLS
|
||||||
|
/* MAKE SURE TO COPY YOUR CUSTOM CERTIFICATE FILES UNDER CAL/tng
|
||||||
|
* Verify variable names, here below the code uses typical tflxtls
|
||||||
|
* proto example.
|
||||||
|
*
|
||||||
|
* g_cert_def_1_signer
|
||||||
|
* g_cert_ca_public_key_1_signer
|
||||||
|
* g_cert_def_3_device
|
||||||
|
*/
|
||||||
|
|
||||||
|
status = atcacert_read_cert(&g_cert_def_1_signer,
|
||||||
|
(const uint8_t*)g_cert_ca_public_key_1_signer,
|
||||||
|
signerBuffer, &signerCertSize);
|
||||||
|
if (status != ATCA_SUCCESS) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Failed to read TFLXTLS signer cert!\r\n");
|
||||||
|
#endif
|
||||||
|
return (int)status;
|
||||||
|
}
|
||||||
|
else if (signerCertSize > ATCATLS_SIGNER_CERT_MAX_SIZE) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Signer TFLXTLS CA cert buffer too small, need to increase"
|
||||||
|
" at least to %d\r\n", signerCertSize);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = atcacert_get_subj_public_key(&g_cert_def_1_signer, signerBuffer,
|
||||||
|
signerCertSize, signerPubKeyBuffer);
|
||||||
|
if (status != ATCA_SUCCESS) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Failed to read TFLXTLS signer public key!\r\n");
|
||||||
|
#endif
|
||||||
|
return (int)status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = atcacert_read_cert(&g_cert_def_3_device, signerPubKeyBuffer,
|
||||||
|
certBuffer, &deviceCertSize);
|
||||||
|
if (status != ATCA_SUCCESS) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
|
printf("Failed to read device cert!\r\n");
|
||||||
|
#endif
|
||||||
|
return (int)status;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Prepare the full buffer adding the signer certificate */
|
||||||
|
XMEMCPY(&certBuffer[deviceCertSize], signerBuffer, signerCertSize);
|
||||||
|
|
||||||
ret = wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
|
ret = wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
|
||||||
(const unsigned char*)certBuffer, signerCertSize+deviceCertSize,
|
(const unsigned char*)certBuffer, (signerCertSize + deviceCertSize),
|
||||||
WOLFSSL_FILETYPE_ASN1);
|
WOLFSSL_FILETYPE_ASN1);
|
||||||
if (ret != WOLFSSL_SUCCESS) {
|
if (ret != WOLFSSL_SUCCESS) {
|
||||||
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
printf("Error registering certificate chain\r\n");
|
printf("Error registering certificate chain\r\n");
|
||||||
|
#endif
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
XFREE(certBuffer,NULL,DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,12 +1077,12 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx)
|
|||||||
wolfSSL_CTX_SetEccVerifyCb(ctx, atcatls_verify_signature_cb);
|
wolfSSL_CTX_SetEccVerifyCb(ctx, atcatls_verify_signature_cb);
|
||||||
wolfSSL_CTX_SetEccSignCb(ctx, atcatls_sign_certificate_cb);
|
wolfSSL_CTX_SetEccSignCb(ctx, atcatls_sign_certificate_cb);
|
||||||
wolfSSL_CTX_SetEccSharedSecretCb(ctx, atcatls_create_pms_cb);
|
wolfSSL_CTX_SetEccSharedSecretCb(ctx, atcatls_create_pms_cb);
|
||||||
#ifdef WOLFSSL_ATECC_TNGTLS
|
#if defined(WOLFSSL_ATECC_TNGTLS) || defined(WOLFSSL_ATECC_TFLXTLS)
|
||||||
ret = atcatls_set_certificates(ctx);
|
ret = atcatls_set_certificates(ctx);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
#ifdef WOLFSSL_ATECC_DEBUG
|
#ifdef WOLFSSL_ATECC_DEBUG
|
||||||
printf("atcatls_set_certificates failed. (%d)\r\n", ret);
|
printf("atcatls_set_certificates failed. (%d)\r\n", ret);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user