From 4858f7d2da1ca0e2ec433c251106e1d0fd9a3130 Mon Sep 17 00:00:00 2001 From: winderdoot Date: Fri, 1 Aug 2025 16:13:19 +0200 Subject: [PATCH] libtinyaes: add stm32n6 hardware-assisted implementation --- libtinyaes/Makefile | 14 ++-- libtinyaes/aes_hw_stm32n6.c | 150 ++++++++++++++++++++++++++++++++++++ libtinyaes/aes_hw_stm32n6.h | 73 ++++++++++++++++++ 3 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 libtinyaes/aes_hw_stm32n6.c create mode 100644 libtinyaes/aes_hw_stm32n6.h diff --git a/libtinyaes/Makefile b/libtinyaes/Makefile index aa42781..706d1f6 100644 --- a/libtinyaes/Makefile +++ b/libtinyaes/Makefile @@ -12,15 +12,17 @@ NAME := libtinyaes LOCAL_PATH := $(call my-dir) ALL_SRCS := $(wildcard $(LOCAL_PATH)*.c) +SRCS := $(filter-out $(LOCAL_PATH)aes_hw_stm32l4.c $(LOCAL_PATH)aes_hw_stm32n6.c, $(ALL_SRCS)) -SRCS := $(filter-out $(LOCAL_PATH)aes_hw_stm32l4.c, $(ALL_SRCS)) - -include $(static-lib.mk) ifeq ($(TARGET_SUBFAMILY), stm32l4x6) NAME := libtinyaes-stm32l4 - SRCS := $(filter-out $(LOCAL_PATH)aes.c, $(ALL_SRCS)) + SRCS := $(filter-out $(LOCAL_PATH)aes.c $(LOCAL_PATH)aes_hw_stm32n6.c, $(ALL_SRCS)) LOCAL_HEADERS_DIR := __none # prevent headers re-installation - - include $(static-lib.mk) +else ifeq ($(TARGET_SUBFAMILY), stm32n6) + NAME := libtinyaes + SRCS := $(filter-out $(LOCAL_PATH)aes.c $(LOCAL_PATH)aes_hw_stm32l4.c, $(ALL_SRCS)) + # LOCAL_HEADERS_DIR := __none # prevent headers re-installation endif + +include $(static-lib.mk) diff --git a/libtinyaes/aes_hw_stm32n6.c b/libtinyaes/aes_hw_stm32n6.c new file mode 100644 index 0000000..3e057ed --- /dev/null +++ b/libtinyaes/aes_hw_stm32n6.c @@ -0,0 +1,150 @@ +/* + * Phoenix-RTOS + * + * Non-thread safe implementation of libtinyaes API using hardware-assisted libcryp + * + * Copyright 2025 Phoenix Systems + * Author: Krzysztof Radzewicz + * + * %LICENSE% + */ + +#include +#include +#include + +#include "tinyaes/aes.h" + +/* FIXME - unfortunate compiling order, corelibs depends on devices. + * Just provide HW AES API directly for now */ +// #include +#include "aes_hw_stm32n6.h" + +/**************************** WARNING ******************************/ +/* This implementation uses a hardware peripheral to perform */ +/* cryptographic operations and is NOT thread safe. Access is not */ +/* synchronized due to performance (avoiding locking/msg overhead) */ +/* and compatibility (retaining the same libtinyaes API) reasons. */ +/* If used in a multi-threaded environment, be sure to use */ +/* application-level locking or other means of synchronization. */ +/*******************************************************************/ + +#if defined(AES_KEYLEN) && AES_KEYLEN == 16 +#define CRYP_KEYLEN aes_128 +#elif defined(AES_KEYLEN) && AES_KEYLEN == 24 +#define CRYP_KEYLEN aes_192 +#else +#define CRYP_KEYLEN aes_256 +#endif + +static unsigned int is_initialized = 0; + +static void AES_init(void) +{ + if (!is_initialized) { + is_initialized = 1; + libcryp_init(); + } +} + +void AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key) +{ + AES_init(); + memcpy(&ctx->RoundKey[0], key, AES_KEYLEN); + ctx->RoundKey[AES_KEYLEN] = 0x0; +} + +#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + +void AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t *key, const uint8_t *iv) +{ + AES_init(); + memcpy(&ctx->RoundKey[0], key, AES_KEYLEN); + ctx->RoundKey[AES_KEYLEN] = 0x0; + memcpy(ctx->Iv, iv, AES_BLOCKLEN); +} + +void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv) +{ + AES_init(); + memcpy(ctx->Iv, iv, AES_BLOCKLEN); +} + +#endif + +#if defined(ECB) && (ECB == 1) + +void AES_ECB_encrypt(struct AES_ctx *ctx, uint8_t *buf) +{ + libcryp_prepare(aes_ecb, aes_encrypt); + libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN); + libcryp_processBlock(buf, buf); + libcryp_unprepare(); +} + +void AES_ECB_decrypt(struct AES_ctx *ctx, uint8_t *buf) +{ + libcryp_deriveDecryptionKey(); + libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN); + libcryp_prepare(aes_ecb, aes_decrypt); + libcryp_enable(); + libcryp_processBlock(buf, buf); + libcryp_unprepare(); +} + +#endif // #if defined(ECB) && (ECB == 1) + + +#if defined(CBC) && (CBC == 1) + +void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length) +{ + libcryp_prepare(aes_cbc, aes_encrypt); + libcryp_setIv(&ctx->Iv[0]); + libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN); + + for (int i = 0; i < length; i += AES_BLOCKLEN) { + libcryp_processBlock(buf, buf); + buf += AES_BLOCKLEN; + } + libcryp_unprepare(); +} + +void AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length) +{ + libcryp_deriveDecryptionKey(); + libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN); + libcryp_prepare(aes_cbc, aes_decrypt); + libcryp_setIv(&ctx->Iv[0]); + libcryp_enable(); + + for (int i = 0; i < length; i += AES_BLOCKLEN) { + libcryp_processBlock(buf, buf); + buf += AES_BLOCKLEN; + } + libcryp_unprepare(); +} + + +#endif // #if defined(CBC) && (CBC == 1) + + +#if defined(CTR) && (CTR == 1) + +void AES_CTR_xcrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length) +{ + /* RM mentions the counter should start at 0x1, but that is wrong. It should be 0. */ + uint8_t nonce[16] = {}; + memcpy(nonce, &ctx->Iv, 12); + libcryp_prepare(aes_ctr, aes_encrypt); + libcryp_setIv(nonce); + libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN); + + for (int i = 0; i < length; i += AES_BLOCKLEN) { + libcryp_processBlock(buf, buf); + buf += AES_BLOCKLEN; + } + libcryp_unprepare(); +} + +#endif // #if defined(CTR) && (CTR == 1) diff --git a/libtinyaes/aes_hw_stm32n6.h b/libtinyaes/aes_hw_stm32n6.h new file mode 100644 index 0000000..f839626 --- /dev/null +++ b/libtinyaes/aes_hw_stm32n6.h @@ -0,0 +1,73 @@ +/* + * Phoenix-RTOS + * + * STM32L4 AES driver API + * + * Copyright 2020 Phoenix Systems + * Author: Daniel Sawka + * + * %LICENSE% + */ + + +#ifndef LIBCRYP_H_ +#define LIBCRYP_H_ + + +enum { + aes_128 = 0, + aes_256 = 1, + aes_192 = 2 +}; + + +enum { + aes_ecb = 0, + aes_cbc = 1, + aes_ctr = 2 +}; + + +enum { + aes_encrypt = 0, + aes_decrypt = 2 +}; + + +int libcryp_tmp(unsigned char *key, unsigned char *iv, const unsigned char *in, unsigned char *out); + + +void libcryp_enable(void); + + +void libcryp_disable(void); + + +int libcryp_setKey(const unsigned char *key, int keylen); + + +void libcryp_getKey(unsigned char *key, int keylen); + + +void libcryp_setIv(const unsigned char *iv); + + +void libcryp_getIv(unsigned char *iv); + + +void libcryp_deriveDecryptionKey(void); + + +void libcryp_prepare(int mode, int dir); + + +void libcryp_unprepare(void); + + +void libcryp_processBlock(const unsigned char *in, unsigned char *out); + + +int libcryp_init(void); + + +#endif