-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Added support for AES-ECB to the PSA Crypto implementation #3480
Merged
gilles-peskine-arm
merged 5 commits into
Mbed-TLS:development
from
stevew817:feature/aes-ecb
Sep 14, 2020
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
ed3c9ec
Added support for AES-ECB to the PSA Crypto implementation
stevew817 2a48b53
Added changelog entry for AES-ECB in PSA
stevew817 a6033e9
Style and language fixes
stevew817 ffecb7b
Implement support for multipart ECB and add tests
stevew817 177deba
Fix style and pull out ECB processing in separate function
stevew817 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Features | ||
* Add support for ECB to the PSA cipher API. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2518,6 +2518,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( | |
case PSA_ALG_OFB: | ||
mode = MBEDTLS_MODE_OFB; | ||
break; | ||
case PSA_ALG_ECB_NO_PADDING: | ||
mode = MBEDTLS_MODE_ECB; | ||
break; | ||
case PSA_ALG_CBC_NO_PADDING: | ||
mode = MBEDTLS_MODE_CBC; | ||
break; | ||
|
@@ -3746,7 +3749,14 @@ static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation, | |
operation->alg = alg; | ||
operation->key_set = 0; | ||
operation->iv_set = 0; | ||
operation->iv_required = 1; | ||
if( alg == PSA_ALG_ECB_NO_PADDING ) | ||
{ | ||
operation->iv_required = 0; | ||
} | ||
else | ||
{ | ||
operation->iv_required = 1; | ||
} | ||
operation->iv_size = 0; | ||
operation->block_size = 0; | ||
mbedtls_cipher_init( &operation->ctx.cipher ); | ||
|
@@ -3837,7 +3847,8 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, | |
operation->key_set = 1; | ||
operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 : | ||
PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) ); | ||
if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) | ||
if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 && | ||
alg != PSA_ALG_ECB_NO_PADDING ) | ||
{ | ||
operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ); | ||
} | ||
|
@@ -3927,15 +3938,102 @@ psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation, | |
return( status ); | ||
} | ||
|
||
/* Process input for which the algorithm is set to ECB mode. This requires | ||
* manual processing, since the PSA API is defined as being able to process | ||
* arbitrary-length calls to psa_cipher_update() with ECB mode, but the | ||
* underlying mbedtls_cipher_update only takes full blocks. */ | ||
static psa_status_t psa_cipher_update_ecb_internal( | ||
mbedtls_cipher_context_t *ctx, | ||
const uint8_t *input, | ||
size_t input_length, | ||
uint8_t *output, | ||
size_t output_size, | ||
size_t *output_length ) | ||
{ | ||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; | ||
size_t block_size = ctx->cipher_info->block_size; | ||
size_t internal_output_length = 0; | ||
*output_length = 0; | ||
|
||
if( input_length == 0 ) | ||
{ | ||
status = PSA_SUCCESS; | ||
goto exit; | ||
} | ||
|
||
if( ctx->unprocessed_len > 0 ) | ||
{ | ||
/* Fill up to block size, and run the block if there's a full one. */ | ||
size_t bytes_to_copy = block_size - ctx->unprocessed_len; | ||
|
||
if( input_length < bytes_to_copy ) | ||
bytes_to_copy = input_length; | ||
|
||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), | ||
input, bytes_to_copy ); | ||
input_length -= bytes_to_copy; | ||
input += bytes_to_copy; | ||
ctx->unprocessed_len += bytes_to_copy; | ||
|
||
if( ctx->unprocessed_len == block_size ) | ||
{ | ||
status = mbedtls_to_psa_error( | ||
mbedtls_cipher_update( ctx, | ||
ctx->unprocessed_data, | ||
block_size, | ||
output, &internal_output_length ) ); | ||
|
||
if( status != PSA_SUCCESS ) | ||
goto exit; | ||
|
||
output += internal_output_length; | ||
output_size -= internal_output_length; | ||
*output_length += internal_output_length; | ||
ctx->unprocessed_len = 0; | ||
} | ||
} | ||
|
||
while( input_length >= block_size ) | ||
{ | ||
/* Run all full blocks we have, one by one */ | ||
status = mbedtls_to_psa_error( | ||
mbedtls_cipher_update( ctx, input, | ||
block_size, | ||
output, &internal_output_length ) ); | ||
|
||
if( status != PSA_SUCCESS ) | ||
goto exit; | ||
|
||
input_length -= block_size; | ||
input += block_size; | ||
|
||
output += internal_output_length; | ||
output_size -= internal_output_length; | ||
*output_length += internal_output_length; | ||
} | ||
|
||
if( input_length > 0 ) | ||
{ | ||
/* Save unprocessed bytes for later processing */ | ||
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), | ||
input, input_length ); | ||
ctx->unprocessed_len += input_length; | ||
} | ||
|
||
status = PSA_SUCCESS; | ||
|
||
exit: | ||
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. Since there's no cleanup, it would be more readable to use |
||
return( status ); | ||
} | ||
|
||
psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, | ||
const uint8_t *input, | ||
size_t input_length, | ||
uint8_t *output, | ||
size_t output_size, | ||
size_t *output_length ) | ||
{ | ||
psa_status_t status; | ||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | ||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; | ||
size_t expected_output_size; | ||
|
||
if( operation->alg == 0 ) | ||
|
@@ -3964,9 +4062,24 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, | |
goto exit; | ||
} | ||
|
||
ret = mbedtls_cipher_update( &operation->ctx.cipher, input, | ||
input_length, output, output_length ); | ||
status = mbedtls_to_psa_error( ret ); | ||
if( operation->alg == PSA_ALG_ECB_NO_PADDING ) | ||
{ | ||
gilles-peskine-arm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/* mbedtls_cipher_update has an API inconsistency: it will only | ||
* process a single block at a time in ECB mode. Abstract away that | ||
* inconsistency here to match the PSA API behaviour. */ | ||
status = psa_cipher_update_ecb_internal( &operation->ctx.cipher, | ||
input, | ||
input_length, | ||
output, | ||
output_size, | ||
output_length ); | ||
} | ||
else | ||
{ | ||
status = mbedtls_to_psa_error( | ||
mbedtls_cipher_update( &operation->ctx.cipher, input, | ||
input_length, output, output_length ) ); | ||
} | ||
exit: | ||
if( status != PSA_SUCCESS ) | ||
psa_cipher_abort( operation ); | ||
|
@@ -3991,12 +4104,15 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, | |
return( PSA_ERROR_BAD_STATE ); | ||
} | ||
|
||
if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT && | ||
operation->alg == PSA_ALG_CBC_NO_PADDING && | ||
operation->ctx.cipher.unprocessed_len != 0 ) | ||
if( operation->ctx.cipher.unprocessed_len != 0 ) | ||
{ | ||
if( operation->alg == PSA_ALG_ECB_NO_PADDING || | ||
( operation->alg == PSA_ALG_CBC_NO_PADDING && | ||
operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) ) | ||
{ | ||
status = PSA_ERROR_INVALID_ARGUMENT; | ||
goto error; | ||
} | ||
} | ||
|
||
cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher, | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Please include the warning against use as well.