-
Notifications
You must be signed in to change notification settings - Fork 14
stm32l4-multi: add stm32n6 cryp driver #591
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?
Conversation
Summary of ChangesHello @winderdoot, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates a new hardware cryptographic driver for the STM32N6 microcontroller, facilitating secure operations through dedicated hardware acceleration. The implementation offers a consistent interface with existing cryptographic libraries, simplifying its adoption within the system. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
| storeVector(cryp_k0lr, key, 32); | ||
| } | ||
|
|
||
| /* Wait untill key writing sequence succeded */ |
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.
[codespell] reported by reviewdog 🐶
untill ==> until
| storeVector(cryp_k0lr, key, 32); | ||
| } | ||
|
|
||
| /* Wait untill key writing sequence succeded */ |
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.
[codespell] reported by reviewdog 🐶
succeded ==> succeeded
|
|
||
| dataBarier(); | ||
|
|
||
| /* Wait untill input FIFO not full */ |
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.
[codespell] reported by reviewdog 🐶
untill ==> until
|
|
||
| dataBarier(); | ||
|
|
||
| /* Wait untill output FIFO not empty */ |
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.
[codespell] reported by reviewdog 🐶
untill ==> until
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.
Code Review
This pull request introduces a new CRYP driver for the STM32N6 platform. The changes are well-structured, adding the necessary Makefile rule, a public header file, and the driver implementation. My review has identified a critical linker error due to a declared but undefined function. Additionally, there are several areas for improvement regarding robustness, such as adding timeouts to busy-wait loops to prevent CPU hangs. I've also provided suggestions to enhance maintainability by removing magic numbers, cleaning up unused includes, and clarifying enum definitions. An unimplemented function in the public API should also be addressed.
| }; | ||
|
|
||
|
|
||
| int libcryp_tmp(unsigned char *key, unsigned char *iv, const unsigned char *in, unsigned char *out); |
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.
| static inline void waitBusy(void) | ||
| { | ||
| while ((*(common.base + cryp_sr) & (0x1 << SR_BUSY)) != 0) | ||
| ; | ||
| } |
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.
| while ((*(common.base + cryp_sr) & (0x1 << SR_IFNF)) == 0) | ||
| ; |
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.
| while ((*(common.base + cryp_sr) & (0x1 << SR_OFNE)) == 0) | ||
| ; |
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.
| enum { | ||
| aes_128 = 0, | ||
| aes_256 = 1, | ||
| aes_192 = 2 | ||
| }; |
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.
The values for AES key sizes are a bit confusing, with aes_256 being 1 and aes_192 being 2. While the implementation in libcryp_setKey handles this correctly, it's counter-intuitive and error-prone for future maintenance. Consider reordering the enum values to be more logical and align with the hardware register values (00 for 128-bit, 01 for 192-bit, 10 for 256-bit). This would make the code more readable and robust, though it would require updating the logic in libcryp_setKey.
| enum { | |
| aes_128 = 0, | |
| aes_256 = 1, | |
| aes_192 = 2 | |
| }; | |
| enum { | |
| aes_128 = 0, /* Corresponds to HW value 0 */ | |
| aes_192 = 1, /* Corresponds to HW value 1 */ | |
| aes_256 = 2 /* Corresponds to HW value 2 */ | |
| }; |
| #define SR_IFNF (1) | ||
| #define SR_IFEM (0) | ||
|
|
||
| #define CRYP_BASE ((void *)0x54020800) |
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.
|
|
||
|
|
||
| /* Can only be enabled when KEYVALID is set */ | ||
| inline void libcryp_enable(void) |
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.
Using the inline keyword on a non-static function defined in a .c file is a GNU extension and may not behave as expected with all toolchains. For functions that are part of the public API, it's standard practice to declare them in the header without inline and define them in the source file without inline. If inlining is desired, the function should typically be defined as static inline in the header file.
| inline void libcryp_enable(void) | |
| void libcryp_enable(void) |
| } | ||
|
|
||
|
|
||
| inline void libcryp_disable(void) |
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.
Using the inline keyword on a non-static function defined in a .c file is a GNU extension and may not behave as expected with all toolchains. For functions that are part of the public API, it's standard practice to declare them in the header without inline and define them in the source file without inline. If inlining is desired, the function should typically be defined as static inline in the header file.
| inline void libcryp_disable(void) | |
| void libcryp_disable(void) |
| if (keylen == aes_128) { | ||
| *(common.base + cryp_cr) = t | (0x0 << CR_KEYSIZE); | ||
| storeVector(cryp_k2lr, key, 16); | ||
| } | ||
| else if (keylen == aes_192) { | ||
| *(common.base + cryp_cr) = t | (0x1 << CR_KEYSIZE); | ||
| storeVector(cryp_k1lr, key, 24); | ||
| } | ||
| else { | ||
| *(common.base + cryp_cr) = t | (0x2 << CR_KEYSIZE); | ||
| storeVector(cryp_k0lr, key, 32); | ||
| } |
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.
The if-else if-else structure for setting the key size is fragile. It implicitly assumes that any keylen that is not aes_128 or aes_192 must be aes_256. This could lead to incorrect behavior if other key sizes are added to the enum in the future. A more robust approach would be to use an explicit check for aes_256 or a switch statement, and handle invalid keylen values with an error.
| void libcryp_getKey(unsigned char *key, int keylen) | ||
| { | ||
| return; | ||
| } |
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.
Add simple driver for CRYP peripheral on STM32N6
Description
Add libcryp API similar to libaes for STM32L4 (AES peripheral).
Motivation and Context
Allows for hardware accelerated cryptography on this platform.
How Has This Been Tested?
Checklist:
Special treatment