-
Notifications
You must be signed in to change notification settings - Fork 5
libtinyaes: add stm32n6 hardware-assisted implementation #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 <stdint.h> | ||
| #include <string.h> | ||
| #include <stdio.h> | ||
|
|
||
| #include "tinyaes/aes.h" | ||
|
|
||
| /* FIXME - unfortunate compiling order, corelibs depends on devices. | ||
| * Just provide HW AES API directly for now */ | ||
| // #include <libmulti/libcryp.h> | ||
| #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; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line appears to be dead code. In the |
||
| } | ||
|
|
||
| #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); | ||
|
Comment on lines
+87
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The order of operations here seems incorrect. libcryp_setKey(&ctx->RoundKey[0], CRYP_KEYLEN);
libcryp_deriveDecryptionKey(); |
||
| 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(); | ||
| } | ||
|
Comment on lines
+100
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation of A similar issue exists in You should retrieve the updated IV from the hardware after processing (or manually update it with the last ciphertext block) and store it back into |
||
|
|
||
| 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(); | ||
| } | ||
|
Comment on lines
+134
to
+148
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation of Similar to the |
||
|
|
||
| #endif // #if defined(CTR) && (CTR == 1) | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,73 @@ | ||||||||||||||||||
| /* | ||||||||||||||||||
| * Phoenix-RTOS | ||||||||||||||||||
| * | ||||||||||||||||||
| * STM32L4 AES driver API | ||||||||||||||||||
| * | ||||||||||||||||||
| * Copyright 2020 Phoenix Systems | ||||||||||||||||||
| * Author: Daniel Sawka | ||||||||||||||||||
|
Comment on lines
+4
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The header comment appears to be copied from the STM32L4 driver. Please update it to reflect that this is for the STM32N6, and also update the copyright year and author to be consistent with
Suggested change
|
||||||||||||||||||
| * | ||||||||||||||||||
| * %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); | ||||||||||||||||||
|
|
||||||||||||||||||
|
Comment on lines
+36
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||
|
|
||||||||||||||||||
| 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 | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commented-out line should be removed to improve code cleanliness.