This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit dfd1cbc27c0cc6d354d8feaa46bb5d7093d7ad53
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Wed Feb 10 08:34:01 2021 -0300

    kinetis: crypto: add initial LTC support
    
    Signed-off-by: Fabio Utzig <ut...@apache.org>
---
 .../crypto/crypto_kinetis/src/crypto_kinetis.c     | 109 ++++++++++++++++++++-
 hw/drivers/crypto/crypto_kinetis/syscfg.yml        |  10 ++
 2 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/hw/drivers/crypto/crypto_kinetis/src/crypto_kinetis.c 
b/hw/drivers/crypto/crypto_kinetis/src/crypto_kinetis.c
index 8261f5f..a4fba3e 100644
--- a/hw/drivers/crypto/crypto_kinetis/src/crypto_kinetis.c
+++ b/hw/drivers/crypto/crypto_kinetis/src/crypto_kinetis.c
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+#include <stdint.h>
 #include <string.h>
 #include "mcu/cmsis_nvic.h"
 #include <os/mynewt.h>
@@ -24,6 +25,15 @@
 #include "crypto/crypto.h"
 #include "crypto_kinetis/crypto_kinetis.h"
 
+#if MYNEWT_VAL(KINETIS_CRYPTO_USE_CAU)
+#define USE_CAU 1
+#elif MYNEWT_VAL(KINETIS_CRYPTO_USE_LTC)
+#define USE_LTC 1
+#include "fsl_ltc.h"
+#else
+#error "Unsupported CRYPTO HW"
+#endif
+
 static struct os_mutex gmtx;
 
 static inline uint8_t
@@ -39,6 +49,7 @@ ROUNDS_PER_KEYLEN(uint16_t keylen)
     }
 }
 
+#if USE_CAU
 /*
  * These routines are exported by NXP's provided CAU and mmCAU software
  * library.
@@ -107,6 +118,78 @@ kinetis_crypto_cau_aes_nr(cau_aes_func_t aes_func, const 
uint8_t *key,
     return i;
 }
 
+#else /* USE_LTC */
+
+static uint32_t
+kinetis_crypto_ltc_aes_encrypt(uint16_t mode, const uint8_t *key,
+        int keylen, uint8_t *iv, const uint8_t *inbuf, uint8_t *outbuf,
+        size_t len)
+{
+    status_t ret = 0;
+    uint32_t keysize = keylen / 8;
+
+    switch (mode) {
+    case CRYPTO_MODE_ECB:
+        ret = LTC_AES_EncryptEcb(LTC0, inbuf, outbuf, len, key, keysize);
+        if (ret == 0) {
+            return len;
+        }
+        break;
+    case CRYPTO_MODE_CTR:
+        ret = LTC_AES_CryptCtr(LTC0, inbuf, outbuf, len, iv, key, keysize, 
NULL, NULL);
+        if (ret == 0) {
+            return len;
+        }
+        break;
+    case CRYPTO_MODE_CBC:
+        ret = LTC_AES_EncryptCbc(LTC0, inbuf, outbuf, len, iv, key, keysize);
+        if (ret == 0) {
+            memcpy(iv, &outbuf[len-AES_BLOCK_LEN], AES_BLOCK_LEN);
+            return len;
+        }
+        break;
+    }
+
+    return 0;
+}
+
+static uint32_t
+kinetis_crypto_ltc_aes_decrypt(uint16_t mode, const uint8_t *key,
+        int keylen, uint8_t *iv, const uint8_t *inbuf, uint8_t *outbuf,
+        size_t len)
+{
+    status_t ret = 0;
+    uint16_t keysize = keylen / 8;
+    uint8_t iv_save[AES_BLOCK_LEN];
+
+    switch (mode) {
+    case CRYPTO_MODE_ECB:
+        ret = LTC_AES_DecryptEcb(LTC0, inbuf, outbuf, len, key, keysize, 
kLTC_EncryptKey);
+        if (ret == 0) {
+            return len;
+        }
+        break;
+    case CRYPTO_MODE_CTR:
+        ret = LTC_AES_CryptCtr(LTC0, inbuf, outbuf, len, iv, key, keysize, 
NULL, NULL);
+        if (ret == 0) {
+            return len;
+        }
+        break;
+    case CRYPTO_MODE_CBC:
+        memcpy(iv_save, &inbuf[len-AES_BLOCK_LEN], AES_BLOCK_LEN);
+        ret = LTC_AES_DecryptCbc(LTC0, inbuf, outbuf, len, iv, key, keysize, 
kLTC_EncryptKey);
+        if (ret == 0) {
+            memcpy(iv, iv_save, AES_BLOCK_LEN);
+            return len;
+        }
+        break;
+    }
+
+    return 0;
+}
+
+#endif
+
 static bool
 kinetis_crypto_has_support(struct crypto_dev *crypto, uint8_t op,
         uint16_t algo, uint16_t mode, uint16_t keylen)
@@ -117,11 +200,19 @@ kinetis_crypto_has_support(struct crypto_dev *crypto, 
uint8_t op,
         return false;
     }
 
-    if (mode != CRYPTO_MODE_ECB) {
+#if USE_CAU
+    if ((mode & CRYPTO_MODE_ECB) == 0) {
+#else
+    if ((mode & (CRYPTO_MODE_ECB | CRYPTO_MODE_CBC | CRYPTO_MODE_CTR)) == 0) {
+#endif
         return false;
     }
 
+#if USE_CAU
     if (!CRYPTO_VALID_AES_KEYLEN(keylen)) {
+#else
+    if (!ltc_check_key_size(keylen / 8)) {
+#endif
         return false;
     }
 
@@ -139,8 +230,13 @@ kinetis_crypto_encrypt(struct crypto_dev *crypto, uint16_t 
algo, uint16_t mode,
         return 0;
     }
 
+#if USE_CAU
     return kinetis_crypto_cau_aes_nr(cau_aes_encrypt, key, keylen, inbuf,
             outbuf, len);
+#else
+    return kinetis_crypto_ltc_aes_encrypt(mode, key, keylen, iv, inbuf,
+            outbuf, len);
+#endif
 }
 
 static uint32_t
@@ -154,8 +250,13 @@ kinetis_crypto_decrypt(struct crypto_dev *crypto, uint16_t 
algo, uint16_t mode,
         return 0;
     }
 
+#if USE_CAU
     return kinetis_crypto_cau_aes_nr(cau_aes_decrypt, key, keylen, inbuf,
             outbuf, len);
+#else
+    return kinetis_crypto_ltc_aes_decrypt(mode, key, keylen, iv, inbuf,
+            outbuf, len);
+#endif
 }
 
 static int
@@ -167,7 +268,11 @@ kinetis_crypto_dev_open(struct os_dev *dev, uint32_t wait, 
void *arg)
     assert(crypto);
 
     if (!(dev->od_flags & OS_DEV_F_STATUS_OPEN)) {
-        /* XXX need to do something here? */
+#if USE_LTC
+        LTC_Init(LTC0);
+        /* Enable differential power analysis resistance */
+        LTC_SetDpaMaskSeed(LTC0, SIM->UIDL);
+#endif
     }
 
     return OS_OK;
diff --git a/hw/drivers/crypto/crypto_kinetis/syscfg.yml 
b/hw/drivers/crypto/crypto_kinetis/syscfg.yml
index 8e5bb8d..adf5cdd 100644
--- a/hw/drivers/crypto/crypto_kinetis/syscfg.yml
+++ b/hw/drivers/crypto/crypto_kinetis/syscfg.yml
@@ -18,6 +18,16 @@
 #
 
 syscfg.defs:
+    KINETIS_CRYPTO_USE_CAU:
+        description: "This MCU has mmCAU HW (default)"
+        value: 1
+        restrictions:
+          - '!KINETIS_CRYPTO_USE_LTC'
+    KINETIS_CRYPTO_USE_LTC:
+        description: "This MCU has LTC HW"
+        value: 0
+        restrictions:
+          - '!KINETIS_CRYPTO_USE_CAU'
     CRYPTO_HW_AES_CBC:
         description: "This HW does not support AES-CBC mode."
         value: 0

Reply via email to