-
Notifications
You must be signed in to change notification settings - Fork 2k
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
sys/crypto: Enable support for AES-192, AES-256 #16183
Conversation
Fixes #16178 |
@Ollrogge thanks for your contribution, it is very useful!
|
BTW: All tests pass on native and nrf51dk and the PR currently adds about 500 Bytes ROM. |
Yes I did. Sadly it does not contain test vectors for CCM and OCB mode.
True. By removing
Yes I think it does. I removed |
How? Can you explain in a bit more detail? If |
How about the Cryptographic Algorithm Validation Program CAVP?
What is the origin? |
Sorry, I mean the I could however remove the interfaces and leave just 1 interface called |
Nice ! Thank you, these have cases for 192 and 256 bit keys. I will add these.
this is where I took the additional tests for 192 and 256 bit keys for CBC, CTR and ECB mode from. |
Sounds reasonable! |
Hey @PeterKietzmann, I have added the additional AES-CCM test cases for 192 and 256 bit keys. |
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.
sys/crypto/aes.c
Outdated
@@ -45,12 +45,14 @@ | |||
*/ | |||
static const cipher_interface_t aes_interface = { | |||
AES_BLOCK_SIZE, | |||
AES_KEY_SIZE, |
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 must be considered as an API change which I would like to avoid here. My comment was only meant for clarification, not to propose such a change.
sys/crypto/aes.c
Outdated
@@ -1037,7 +1038,7 @@ int aes_encrypt(const cipher_context_t *context, const uint8_t *plainBlock, | |||
const AES_KEY *key = &aeskey; | |||
|
|||
res = aes_set_encrypt_key((unsigned char *)context->context, | |||
AES_KEY_SIZE * 8, &aeskey); | |||
context->key_size * 8, &aeskey); |
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.
What if context->key_size
is not initialized? This happens easily when a user does not utilize the ciphers
module (see Fortuna RNG). Wouldn't be necessary with the old cipher_interface_t
struct.
sys/crypto/ciphers.c
Outdated
cipher->interface = cipher_id; | ||
return cipher->interface->init(&cipher->context, key, key_size); | ||
cipher->context.key_size = key_size; |
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.
I would rather deal with that in a follow-up PR and focus on aes_*
here (see comment about API change above)
sys/crypto/ciphers.c
Outdated
@@ -22,30 +22,24 @@ | |||
int cipher_init(cipher_t *cipher, cipher_id_t cipher_id, const uint8_t *key, | |||
uint8_t key_size) | |||
{ | |||
if (key_size > cipher_id->max_key_size) { |
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.
Why remove that change?
sys/crypto/ciphers.c
Outdated
} | ||
|
||
|
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.
Maybe don't commit any of the changes in ciphers.c
sys/include/crypto/ciphers.h
Outdated
#if defined(MODULE_CRYPTO_3DES) | ||
#define CIPHER_MAX_CONTEXT_SIZE 24 | ||
#elif defined(MODULE_CRYPTO_AES) | ||
#if defined(MODULE_CRYPTO_3DES) || defined(MODULE_CRYPTO_AES) |
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.
Before, CIPHER_MAX_CONTEXT_SIZE
was 24
for MODULE_CRYPTO_3DES
, now is 32
.
-> What was the intention behind this?
sys/crypto/aes.c
Outdated
@@ -1305,7 +1306,7 @@ int aes_decrypt(const cipher_context_t *context, const uint8_t *cipherBlock, | |||
const AES_KEY *key = &aeskey; | |||
|
|||
res = aes_set_decrypt_key((unsigned char *)context->context, | |||
AES_KEY_SIZE * 8, &aeskey); | |||
context->key_size * 8, &aeskey); |
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.
Same as above.
sys/include/crypto/ciphers.h
Outdated
@@ -65,6 +63,7 @@ extern "C" { | |||
* @brief the context for cipher-operations | |||
*/ | |||
typedef struct { | |||
uint8_t key_size; /**< key size used */ |
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.
See comment above.
sys/include/crypto/ciphers.h
Outdated
@@ -76,9 +75,6 @@ typedef struct cipher_interface_st { | |||
/** Blocksize of this cipher */ | |||
uint8_t block_size; | |||
|
|||
/** Maximum key size for this cipher */ | |||
uint8_t max_key_size; |
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.
Maybe it is redundant but probably not a task of this PR (see above)
tests/sys_crypto/tests-crypto-aes.c
Outdated
int err; | ||
uint8_t data[AES_BLOCK_SIZE]; | ||
|
||
err = aes_init(&ctx, TEST_0_KEY, sizeof(TEST_0_KEY)); | ||
err = cipher_init(&cipher, CIPHER_AES_128, TEST_0_KEY, sizeof(TEST_0_KEY)); |
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.
We should not replace the plain tests of the AES API with tests of the ciphers API.
I checked the .elf files with elf_diff. Most of the difference comes from An option that might work is to conditionally enable support for the different sizes using pesudomodules. After that, one option could be a macro |
Another option @PeterKietzmann and I talked about was to leave the implementation as is and make |
Could you show a short piece of pseudo code to assist implementing it? |
I was thinking on defining the pseudomodules on the Makefiles, and then have a macro like: #if IS_USED(MODULE_AES_128) && !IS_USED(MODULE_AES_192) && !IS_USED(MODULE_AES_256)
# define KEY_SIZE(ctx) AES_KEY_SIZE_128
#elif !IS_USED(MODULE_AES_128) && IS_USED(MODULE_AES_192) && !IS_USED(MODULE_AES_256)
# define KEY_SIZE(ctx) AES_KEY_SIZE_192
#elif !IS_USED(MODULE_AES_128) && !IS_USED(MODULE_AES_192) && IS_USED(MODULE_AES_256)
# define KEY_SIZE(ctx) AES_KEY_SIZE_256
#else
# define KEY_SIZE(ctx) ctx->keySize
#endif |
Hey @leandrolanzieri, Additionally I removed all the changes in ciphers.c as you suggested @PeterKietzmann. I hope its okay that I already squashed the commits. My fixups got really messy in the end. |
#16253 was merged. Please update this PR as discussed offline. |
I updated the PR based on the changes from #16253 . Using 128 bit keys now adds +8 bytes to the .text section compared to master. While changing the CIPHERS_MAX_KEY_SIZE to be adjusted based on the key sizes used I noticed that it was 20 bytes before. I don't really understand why because 16 bytes should have been sufficient for 128 bit keys ? When using 16 bytes instead of 20 bytes for 128 bit keys the specific tests still pass. |
@Ollrogge thanks for updating the makefiles! It looks like just a couple of boards are overflowing after splitting the crypto tests. For those you can simply add them to the I think the test application names are not really descriptive, could you try to use a more precise name for them? Also, it would be nice to add some |
Rebased my changes onto upstream/master and added the overflowing boards to Since my latest fixup commit the Murdock test is failing completely. I don't really understand why ? Can you tell me what I did wrong ? |
953fb69
to
245fd87
Compare
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.
I added one more comment regarding the dependency resolution. Otherwise it looks good. Feel free to squash after applying the fix @Ollrogge
My ACK holds, but I haven't followed the latest changes that deal with the size of the tests. @leandrolanzieri wanna merge? |
I'm running tests of the affected modules, just to be on the safe side. |
Tested OpenWSN, nodes join fine (this is the part where crypto is used):
|
I have tested the following, which work as expected:
|
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.
Changes look good, the feature works as expected while keeping the default behaviour and code-size because of the optimizations in place. Tests have been greatly improved.
ACK! Thanks @Ollrogge for the contribution!
And GO! |
}; | ||
|
||
typedef struct aes_key_st AES_KEY; | ||
} AES_KEY; |
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.
Why not?
} AES_KEY; | |
} aes_key_t; |
Contribution description
This PR adds support for AES-192 and AES-256. The code in /crypto/aes.c did already support AES-192 and AES-256 but the functionality was not made available. This PR adds the additional interfaces to enable AES-192 and AES-256.
Testing procedure
I have added tests for 192 bit and 256 bit keys to the already existing tests for CBC, CTR and ECB mode. The tests have the same origin as the original ones.
I was unable to find official test vectors for 192 bit and 256 bit for CCM and OCB mode. If someone can point me towards test vectors for these modes I can add them as well.
Issues/PRs references
Fixes #16178,
waiting for #16253