Skip to content
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

return internal error code, if failed #1096

Closed
wants to merge 2 commits into from
Closed

Conversation

RonEld
Copy link
Contributor

@RonEld RonEld commented Sep 19, 2017

Description

in case mbedtls_aes_crypt_ecb failed, return an error from other modes
calling it
Resolves #1092

Status

READY

Requires Backporting

Yes
Which branch?
mbedtls-2.1
mbedtls-1.3

Migrations

NO

Todos

  • Tests
  • Documentation
  • Changelog updated
  • Backported

ChangeLog Outdated

Bugfix
* return error code of `mbedtls_aes_crypt_ecb` if failed, when calling it from
other modes. FIx for #1092 reported by adustm

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two typos here

library/aes.c Outdated
@@ -979,6 +995,9 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,

*iv_off = n;

end:
if ( ret != 0 )
mbedtls_zeroize( output, length );
return( 0 );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be return( ret );

library/aes.c Outdated

end:
if ( ret != 0 )
mbedtls_zeroize( output, length );
return( 0 );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be return( ret );

library/aes.c Outdated

end:
if ( ret != 0 )
mbedtls_zeroize( output, length );
return( 0 );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be return( ret );

library/aes.c Outdated
@@ -880,7 +880,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int i;
int i, ret;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ret should be initialized as the body of the function doesn't alter it for length == 0.

library/aes.c Outdated
@@ -947,15 +955,19 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int c;
int c, ret;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ret should be initialized here, too.

library/aes.c Outdated
@@ -994,11 +1013,14 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
{
unsigned char c;
unsigned char ov[17];
int ret;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ret should be initialized here, too.

library/aes.c Outdated
@@ -1027,13 +1051,15 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int c, i;
int c, i, ret;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ret should be initialized here, too.

Copy link
Contributor

@andresag01 andresag01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional to @hanno-arm's comments. I did a quick grep and found that there are a few other occurrences of mbedtls_aes_*() functions across the library that do not have their return codes being checked. For example:

--> grep -rIn "mbedtls_aes_crypt_\(ecb\|cbc\)" ./library/*
./library/aes.c:1307:                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
./library/aes.c:1323:                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
./library/aes.c:1364:                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
./library/aes.c:1383:                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
./library/ctr_drbg.c:202:            mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain );
./library/ctr_drbg.c:222:        mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
./library/ctr_drbg.c:253:        mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p );
./library/ctr_drbg.c:380:        mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp );
./library/pem.c:195:    mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,

Do you think we should fix these ones here as well?

library/aes.c Outdated
size_t n = *nc_off;

while( length-- )
{
if( n == 0 ) {
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: This line is a bit too long. Could you please break it up?

Copy link

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the approach to fix the bug, but there are still some issues with the code mentioned in the comments.

@RonEld
Copy link
Contributor Author

RonEld commented Sep 24, 2017

Hi @andresag01 @hanno-arm Thank you for your comments. I agree we should change other files as well

@RonEld
Copy link
Contributor Author

RonEld commented Sep 24, 2017

Hi @andresag01 @hanno-arm I modified according to your comments
Note that there are still locations where we don't check ther return code:

> grep -rIn "mbedtls_aes_crypt_\(ecb\|cbc\|ctr\)" ./library/*
./library/aes.c:1308:                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
./library/aes.c:1324:                mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
./library/aes.c:1365:                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
./library/aes.c:1384:                mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
./library/aes.c:1489:            mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
./library/aes.c:1506:            mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
./library/pem.c:195:    mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,

In aes.c these are in the selftest, which is already addressed in #964 and I prefer to avoid the conflicts
In pem.c , the call is in static void pem_aes_decrypt() , which we may consider changing its return value as well, but I think this should be done in a different PR

ChangeLog Outdated
@@ -3,8 +3,8 @@ mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS x.x.x branch released xxxx-xx-xx

Bugfix
* return error code of `mbedtls_aes_crypt_ecb` if failed, when calling it from
other modes. FIx for #1092 reported by adustm
* Return error code of `mbedtls_aes_crypt_ecb` if failed, when calling it from
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not pointing it out later, but please note that ChangeLog is not markdown and the ` character has no efect there. I would suggest ``mbedtls_aes_crypt_ecb`` -> mbedtls_aes_crypt_ecb()

@RonEld
Copy link
Contributor Author

RonEld commented Sep 25, 2017

I fixed the ChangeLog
@andresag01 @hanno-arm please approve

@andresag01
Copy link
Contributor

@RonEld: Now that I recall, the return value for the PEM functions has been fixed in a separate PR. Please refer to #828

Copy link
Contributor

@andresag01 andresag01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RonEld: Many thanks for considering the comments. I have gone through the ctr_drbg file more carefuly and pointed out a few things. What do you think?

mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );

ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
if ( ret != 0 )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: Please remove between if and (

memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );

return( 0 );
exit:
return( ret );
}

void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that its slightly pointless to check the return codes of block_cipher_df() and ctr_drbg_update_internal() as mbedtls_ctr_drbg_update() does not have a return value. However, it would be nice if we could at least abort the update if either of the calls fails. Also, it would be good to add a comment nearby explaning the situation (and perhaps raise a ticket as the API might need to be modified).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to check the return values of of the functions ctr_drbg_update_internal() and ctr_drbg_update_internal() called from mbedtls_ctr_drbg_reseed() as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RonEld: I dont think this was fully addressed. There are still a couple of unchecked return values here and here. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I missed this

@RonEld
Copy link
Contributor Author

RonEld commented Sep 25, 2017

@andresag01 I addressed your comments. Please approve

if( ret != 0)
return;
ret = ctr_drbg_update_internal( ctx, add_input );
if( ret != 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: This might not even be worth pointing out, but there is a missing before )...

@RonEld
Copy link
Contributor Author

RonEld commented Sep 25, 2017

@andresag01 Thanks for your comments. I missed that part.
Please review

andresag01
andresag01 previously approved these changes Sep 25, 2017
Copy link
Contributor

@andresag01 andresag01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RonEld: Thanks for considering my comments. I am happy with the changes.

ctr_drbg_update_internal( ctx, seed );
ret = ctr_drbg_update_internal( ctx, seed );
if( ret != 0 )
return ret;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: brackets missing around ret here and a few lines above.

@RonEld
Copy link
Contributor Author

RonEld commented Sep 25, 2017

I have added brackets as your comment.
Please approve

library/aes.c Outdated
return( 0 );
end:
if ( ret != 0 )
mbedtls_zeroize( output, length );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not bringing this up earlier, but this probably does not do what it is intended to do: The output and length values are updated during the operations, so this zeroization will clear the remaining, so far unwritten, output buffer, while the part that has already been written is left untouched. Also, the loops decrease length at the beginning of the iteration while output is increased at the end, so the zeroization will omit one byte at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I missed that for some reason. I'll fix that.

@RonEld
Copy link
Contributor Author

RonEld commented Sep 26, 2017

Hi @hanno-arm I fixed according to your comment
Please review

@simonbutcher simonbutcher removed the needs-review Every commit must be reviewed by at least two team members, label Jan 9, 2019
@RonEld
Copy link
Contributor Author

RonEld commented Jan 10, 2019

@sbutcher-arm Thanks for the review.
I addressed your comments.

cc @Patater

I will squash the commits once the PR is fully approved

@RonEld RonEld added the needs-review Every commit must be reviewed by at least two team members, label Jan 10, 2019
simonbutcher
simonbutcher previously approved these changes Jan 10, 2019
Copy link
Contributor

@simonbutcher simonbutcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@simonbutcher
Copy link
Contributor

I guess the PR just needs squashing, back porting and re-approval now.

@RonEld
Copy link
Contributor Author

RonEld commented Jan 10, 2019

@sbutcher-arm yes that's my plan

@andresag01 \ @Patater Do you want me to squash before you approve?

@RonEld
Copy link
Contributor Author

RonEld commented Jan 10, 2019

@sbutcher-arm
Actually, I think that #1096 (comment) should be addressed on all other mode as well.
I will fix that first

@RonEld
Copy link
Contributor Author

RonEld commented Jan 10, 2019

I removed the bytes_written in all other modes, except xts, as in this mode, output does not point to the end of the buffer, when the operation finishes.

Ron Eldor added 2 commits January 31, 2019 16:24
In case `mbedtls_aes_crypt_ecb` failed, return an error from other modes
calling it, and check return code of internal functions.
Add ChangeLog entry for bug fix of returning error code of ecb calls.
@RonEld
Copy link
Contributor Author

RonEld commented Jan 31, 2019

@Patater @andresag01 I have rebased to resolve conflicts, and squashedthe commits. Please review.
Once approved, I will backport this to 2.7

@RonEld
Copy link
Contributor Author

RonEld commented Jan 31, 2019

Backports available at #2396 and #2397

@RonEld RonEld removed the needs-review Every commit must be reviewed by at least two team members, label Feb 3, 2019
@mpg
Copy link
Contributor

mpg commented Feb 8, 2019

Almost ready for merge, just waiting for the 2.7 backport to be approved.

@RonEld
Copy link
Contributor Author

RonEld commented Mar 20, 2019

Both backports have been fully reviewed and approved, so removing the "needs backports" label"

cc @Patater

@RonEld RonEld removed the needs-backports Backports are missing or are pending review and approval. label Mar 20, 2019
@RonEld RonEld added the needs-ci Needs to pass CI tests label Apr 14, 2019
@gilles-peskine-arm
Copy link
Contributor

Unfortunately, there are now merge conflicts. I think I independently rediscovered the issue in ctr_drbg. The aes part is still relevant.

@gilles-peskine-arm gilles-peskine-arm removed the needs-ci Needs to pass CI tests label Oct 6, 2020
@gilles-peskine-arm
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component-crypto Crypto primitives and low-level interfaces needs-work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The returned value of mbedtls_aes_crypt_ecb should be checked and returned by its callers
7 participants