Browse Source

Merge pull request #5573 from embhorn/zd14802

Add WOLFSSL_ATECC_TFLXTLS for Atmel port
David Garske 1 year ago
parent
commit
2a96d62e43
2 changed files with 146 additions and 75 deletions
  1. 1 0
      wolfcrypt/src/port/atmel/README.md
  2. 145 75
      wolfcrypt/src/port/atmel/atmel.c

+ 1 - 0
wolfcrypt/src/port/atmel/README.md

@@ -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_IOENC`: Enable use of atcab_ecdh_ioenc() for encrypted ECDH.
 * `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_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. 

+ 145 - 75
wolfcrypt/src/port/atmel/atmel.c

@@ -37,6 +37,12 @@
 #include "tng/tng_atcacert_client.h"
 #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
     #include <wolfssl/wolfcrypt/misc.h>
 #else
@@ -98,33 +104,34 @@ static ATCAIfaceCfg cfg_ateccx08a_i2c_pi;
  */
 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)
-	uint8_t i = 0;
-	uint32_t copy_count = 0;
-	uint8_t rng_buffer[RANDOM_NUM_SIZE];
+    uint8_t i = 0;
+    uint32_t copy_count = 0;
+    uint8_t rng_buffer[RANDOM_NUM_SIZE];
 
-	if (rand_out == NULL) {
-		return -1;
-	}
+    if (rand_out == NULL) {
+        return -1;
+    }
 
-	while (i < count) {
+    while (i < count) {
         ret = atcab_random(rng_buffer);
-		if (ret != ATCA_SUCCESS) {
-			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;
-	}
-    #ifdef ATCAPRINTF
+        if (ret != ATCA_SUCCESS) {
+            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;
+    }
+#ifdef ATCAPRINTF
     atcab_printbin_label((const char*)"\r\nRandom Number", rand_out, count);
-    #endif
+#endif
 #else
     /* TODO: Use on-board TRNG */
 #endif
-	return ret;
+    return ret;
 }
 
 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
             on micro flash */
         /* For this example its a fixed value */
-		if (atmel_init_enc_key() != 0) {
-			WOLFSSL_MSG("Failed to initialize transport key");
+        if (atmel_init_enc_key() != 0) {
+            WOLFSSL_MSG("Failed to initialize transport key");
             return WC_HW_E;
-		}
+        }
 #endif
 
         mAtcaInitDone = 1;
@@ -658,7 +665,8 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
     uint8_t* qy = &peerKey[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;
     }
 
@@ -696,7 +704,8 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
 
             /* export peer's key as raw unsigned for hardware */
             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;
 
             /* 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) {
                 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.
  */
-int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, unsigned int sigSz,
-    const byte* hash, unsigned int hashSz, const byte* key, unsigned int keySz, int* result,
-    void* ctx)
+int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig,
+    unsigned int sigSz, const byte* hash, unsigned int hashSz, const byte* key,
+    unsigned int keySz, int* result, void* ctx)
 {
     int ret;
     ecc_key tmpKey;
@@ -864,7 +874,8 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, unsigned int sigS
     (void)hashSz;
     (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;
     }
 
@@ -931,72 +942,131 @@ exit:
 
 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;
     ATCA_STATUS status;
-    size_t signerCertSize=0;
-    size_t deviceCertSize=0;
-    uint8_t *certBuffer;
+    size_t signerCertSize = ATCATLS_SIGNER_CERT_MAX_SIZE;
+    size_t deviceCertSize = ATCATLS_DEVICE_CERT_MAX_SIZE;
+    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 */
-    status=tng_atcacert_read_signer_cert(NULL, &signerCertSize);
-    if (ATCA_SUCCESS != status) {
-        #ifdef WOLFSSL_ATECC_DEBUG
-        printf("Failed reading Signer cert size(0x%x)\r\n", status);
-        #endif
-        return WOLFSSL_FAILURE;
+#ifdef WOLFSSL_ATECC_TNGTLS	
+    ret = tng_atcacert_max_signer_cert_size(&signerCertSize);
+    if (ret != ATCACERT_E_SUCCESS) {
+    #ifdef WOLFSSL_ATECC_DEBUG
+       printf("Failed to get max signer cert size\r\n");
+    #endif
+       return ret;
     }
-
-    /* fetch device cert size */
-    status=tng_atcacert_read_device_cert(NULL, &deviceCertSize, NULL);
-    if (ATCA_SUCCESS != status) {
-        #ifdef WOLFSSL_ATECC_DEBUG
-        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;
+    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;
     }
-    
-    /* Read signer cert */
-    status = tng_atcacert_read_signer_cert(&certBuffer[deviceCertSize],
-                                           &signerCertSize);
+
+    /* Read TNGTLS signer cert */
+    status = tng_atcacert_read_signer_cert(signerBuffer, &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);
+        ret = atmel_ecc_translate_err(status);
         return ret;
     }
 
     /* Read device cert signed by the signer above */
     status = tng_atcacert_read_device_cert(certBuffer, &deviceCertSize,
-     	                                   &certBuffer[deviceCertSize]);
+                                           signerBuffer);
     if (ATCA_SUCCESS != status) {
-        #ifdef WOLFSSL_ATECC_DEBUG
-        printf("Error reading device cert(0x%x)\r\n", status);
-        #endif
-        XFREE(certBuffer,NULL,DYNAMIC_TYPE_TMP_BUFFER);
-        ret = atmel_ecc_translate_err(ret);
+        ret = atmel_ecc_translate_err(status);
         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,
-          (const unsigned char*)certBuffer, signerCertSize+deviceCertSize,
+          (const unsigned char*)certBuffer, (signerCertSize + deviceCertSize),
           WOLFSSL_FILETYPE_ASN1);
     if (ret != WOLFSSL_SUCCESS) {
+    #ifdef WOLFSSL_ATECC_DEBUG
         printf("Error registering certificate chain\r\n");
+    #endif
         ret = -1;
     }
     else {
-	    ret = 0;
+        ret = 0;
     }
-    XFREE(certBuffer,NULL,DYNAMIC_TYPE_TMP_BUFFER);
+
     return ret;
 }
 
@@ -1007,12 +1077,12 @@ int atcatls_set_callbacks(WOLFSSL_CTX* ctx)
     wolfSSL_CTX_SetEccVerifyCb(ctx, atcatls_verify_signature_cb);
     wolfSSL_CTX_SetEccSignCb(ctx, atcatls_sign_certificate_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);
     if (ret != 0) {
-        #ifdef WOLFSSL_ATECC_DEBUG
+    #ifdef WOLFSSL_ATECC_DEBUG
         printf("atcatls_set_certificates failed. (%d)\r\n", ret);
-        #endif
+    #endif
     }
 #endif
     return ret;