-
Notifications
You must be signed in to change notification settings - Fork 3k
Port aes cc310 driver #10907
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
Port aes cc310 driver #10907
Conversation
Please show effect on resource usage. Flash/ram |
Using the generated map file, I see the following changes: |
benchmark performance with the sw driver:
|
@RonEld, thank you for your changes. |
Add support for CC310 AES driver, returning `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED` for key size other than 128 bits, and for AES modes not supported by the driver. Use `MBEDTLS_CTR_DRBG_USE_128_BIT_KEY`.
I amended the three files with the correct copyright year and updated the |
} | ||
#if defined(MBEDTLS_CIPHER_MODE_XTS) | ||
|
||
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ){} |
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.
If we don't define these, if someone attempts to use them, they'll get build failures. If we implement them doing nothing, that's a small waste of code space, but also could hide the unsupported nature until run-time. Maybe worth adding #error AES XTS is not supported with CC310 AES
within this #if defined(MBEDTLS_CIPHER_MODE_XTS)
, instead of making empty functions.
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.
Personally, I also prefer catching issues as soon as possible, e.g. at build time. However. this is according to our design, and in this specific case it may cause CI issues, when trying to set different configurations on different platforms
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.
OK for now in this PR.
That's a problem in our CI, IMO. We shouldn't count it as a failure, nor attempt such an an invalid configuration, when a certain platform's ALT implementation can't do certain block modes.
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.
Yes, this is why I added the FEATURE UNSUPPORTED
PR
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.
OK
|
||
} | ||
|
||
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *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.
This looks identical to mbedtls_aes_setkey_enc()
other than one flag. Could we implement these functions by returning the result of a new function return mbedtls_aes_setkey(SASI_AES_DECRYPT)
? It should save a bit of flash space, and be more readable.
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); | ||
|
||
return( CC_aes_cipher( ctx, mode, SASI_AES_MODE_ECB, 16, NULL, 0, input, output ) ); | ||
|
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.
Style: Sometimes there is a newline here after return before }
, and sometimes not. Be consistent at least. We prefer the no newline in this location style.
|
||
if ( *nc_off ) | ||
{ | ||
/* handle corner case where we are resuming a previous encryption, |
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.
Does CC_aes_cipher not handle this corner case itself?
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.
no. CC CTR implementation only supports where *nc_off
is zero
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 happens if it isn't? Incorrect computation? How do users of the CC API cope with this limitation ordinarily?
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.
yes, incorrect computation. Users of CC, that are interested in *nc_off != 0
will need to do the same thing
if( ( ( length % SASI_AES_BLOCK_SIZE_IN_BYTES ) != 0 ) && ret == 0 ) | ||
{ | ||
/* in case the length is not aligned, generate stream block for resuming | ||
* increase nonce_block to the correct value*/ |
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.
Could we fail with hardware unsupported or invalid parameter when alignment is not correct?
If not, maybe it's smaller in code size to copy the block to an aligned location, perform the hardware operation, and then copy back.
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.
It's bad wording. It's not a matter of memory alignment. It's a matter of length which is a multiple of AES block size (16). This functionality generates the stream block for resuming on next call( if there is), for generating the first block on next block ( since *nc_off
is not zero in this case)
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 think that returning unsupported feature in this case will result in a major functionality decrease, on the expense of minor flash set back, IMHO
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's the use case exactly? Why this is a major functionality decrease? Don't users usually use AES with a length that's a multiple of the block length?
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.
not for CTR.
CTR is streaming mode, which you can send any length of data, and pause the streaming in the middle, resume the streaming from same location, or any other arbitrary location
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.
Seems odd that CC only lets you do CTR in multiples of the block length. Is that really the case? Doesn't that sort of defeat the purpose of streaming?
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.
@Patater CTR mode is a stream cipher based on top of a block operation. From the user's perspective, partial inputs can have any byte length (even any bit length in theory). But under the hood, the operation involving the key works on 128 bits at a time (for a cipher with 128-bit blocks). If a call completes with a total input size that isn't a multiple of the block size, something in the stack has to remember the partial state. The hardware can't do this by itself (it would need to store the state of all ongoing calls). Either the hardware stores the partial state in an opaque form that the driver just keeps in memory, or the hardware works on 128 bits at a time and it's up to the driver to compensate. Usually, it's the latter: if the “hardware” is doing it, it means that some software layer deeper down is doing it.
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.
@Patater In addition to what was mentioned by @gilles-peskine-arm CC supports any byte length as input, but it doesn't support byte offset.
As you can see from previous call to CC driver(line 284), the full length ( after reducing nc_off
), no matter what the length is. However, if the length is not a multiple of 16, then we need to calculate stream_block
for next API call.
1. Make common function for setting key, which receives the direction as parameter. 2. Remove rediundant extra lines.
@Patater I addressed your issues. |
I don't exactly know how it used to work, but I don't want us to break people use cases. I'd much rather add it as an option for now and make it as default for 6. |
Previously, AES 192 and AES 256 were supported by SW implementation. With this PR, a request for these key size modes( and some addition aes modes such as XTS and OFB ) will return an unsupported error. |
Have the alternative aes undefined by default, in order not to break backwards compatability. `MBEDTLS_CTR_DRBG_USE_128_BIT_KEY` remains defined for better usability.
I made the alternative aes optional. I will make a separate PR, updating the readme file |
@ARMmbed/mbed-os-crypto Please leave your review conclusions, + or -, Can this move forward, or does this require more work? |
if( ( ( length % SASI_AES_BLOCK_SIZE_IN_BYTES ) != 0 ) && ret == 0 ) | ||
{ | ||
/* in case the length is not aligned, generate stream block for resuming | ||
* increase nonce_block to the correct value*/ |
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.
Seems odd that CC only lets you do CTR in multiples of the block length. Is that really the case? Doesn't that sort of defeat the purpose of streaming?
} | ||
#if defined(MBEDTLS_CIPHER_MODE_XTS) | ||
|
||
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ){} |
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.
OK
static int CC_aes_setkey( mbedtls_aes_context *ctx, const unsigned char *key, | ||
unsigned int keybits, SaSiAesEncryptMode_t cipher_flag ) | ||
{ | ||
|
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.
Remove extra newline
} | ||
|
||
return ( 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.
Remove extra newline
|
||
} | ||
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, | ||
unsigned int keybits ) |
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.
Align arguments
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, | ||
int mode, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) |
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.
Align arguments
@@ -22,6 +22,8 @@ | |||
#define __MBEDTLS_DEVICE__ | |||
|
|||
#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT | |||
//#define MBEDTLS_AES_ALT | |||
#define MBEDTLS_CTR_DRBG_USE_128_BIT_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.
I don't think we want to degrade the security of devices by default. Consider wrapping this setting in a ifdef, with a comment explaining why it's needed.
#if defined(MBEDTLS_AES_ALT)
#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
#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.
AES-128 is acceptable as default security as long as there are less than about one quintillion devices (128-bit security, divide by two for the birthday bound) under ideal conditions (if there are side channels, it can be another matter, but more bits often doesn't help anyway). AES-256 gives a better security margin, but there's no reason to require it.
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 agree, we don't want to degrade security, and perhaps as long as AES_ALT is not defined we shouldn't , however I decide to add it in order to have as less configurability as possible, for readability reasons. In addition, as mentioned by Gilles, the degrade doesn't have much effect.
1. Remove redundant extra lines. 2. Have the function parameters aligned. 3. Remove redundant white spaces.
@Patater @gilles-peskine-arm I have fixes some style issues. |
Test run: FAILEDSummary: 2 of 11 test jobs failed Failed test jobs:
|
CI restarted |
Restarted CI (the last run did not complete neither reported here). |
Test run: SUCCESSSummary: 11 of 11 test jobs passed |
Description
Add support for CC310 AES driver,
returning
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED
for key sizeother than 128 bits, and for AES modes not supported by the driver.
Use
MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
.Benchmark information, built with
GCC_ARM
:Tested also with the Mbed TLS On Target Tests on NRF52840_DK
Pull request type
Reviewers
@ARMmbed/mbed-os-crypto
Release Notes
This is a target update, adding hw accelerated AES, however, it can also be considered as a breaking change, as it removes support for AES other than 128 bit keys.