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