Merge pull request #3500 from AndrzejKurek/fi-sha256-fixes

Introduce sha256 security review fixes
This commit is contained in:
Andrzej Kurek 2020-08-03 12:13:40 +02:00 committed by GitHub
commit 898d330148
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 21 deletions

View file

@ -118,7 +118,7 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
* and have a hash operation started. * and have a hash operation started.
* \param input The buffer holding the data. This must be a readable * \param input The buffer holding the data. This must be a readable
* buffer of length \p ilen Bytes. * buffer of length \p ilen Bytes.
* \param ilen The length of the input data in Bytes. * \param ilen The length of the input data in Bytes. At most UINT32_MAX.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return A negative error code on failure. * \return A negative error code on failure.

View file

@ -35,6 +35,7 @@
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#include <stdint.h>
#include <string.h> #include <string.h>
@ -188,7 +189,7 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
{ {
uint32_t temp1, temp2, W[64]; uint32_t temp1, temp2, W[64];
uint32_t A[8]; uint32_t A[8];
uint32_t flow_ctrl = 0; volatile uint32_t flow_ctrl = 0;
unsigned int i; unsigned int i;
SHA256_VALIDATE_RET( ctx != NULL ); SHA256_VALIDATE_RET( ctx != NULL );
@ -214,11 +215,6 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
} }
} }
if( flow_ctrl != 16 )
{
return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
}
for( i = 0; i < 64; i++ ) for( i = 0; i < 64; i++ )
{ {
if( i >= 16 ) if( i >= 16 )
@ -317,19 +313,22 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
SHA256_VALIDATE_RET( ctx != NULL ); SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
if( ilen == 0 ) /* ilen_dup is used instead of ilen, to have it volatile for FI protection */
if( ilen_dup == 0 )
return( 0 ); return( 0 );
if( ilen_dup > UINT32_MAX )
return( MBEDTLS_ERR_SHA256_BAD_INPUT_DATA );
left = ctx->total[0] & 0x3F; left = ctx->total[0] & 0x3F;
fill = 64 - left; fill = 64 - left;
ctx->total[0] += (uint32_t) ilen; ctx->total[0] += (uint32_t) ilen_dup;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen ) if( ctx->total[0] < (uint32_t) ilen_dup )
ctx->total[1]++; ctx->total[1]++;
if( left && ilen >= fill ) if( left && ilen_dup >= fill )
{ {
mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill ); mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, fill );
@ -337,27 +336,27 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
return( ret ); return( ret );
input += fill; input += fill;
ilen -= fill; ilen_dup -= fill;
left = 0; left = 0;
} }
while( ilen >= 64 ) while( ilen_dup >= 64 )
{ {
if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
return( ret ); return( ret );
input += 64; input += 64;
ilen -= 64; ilen_dup -= 64;
} }
if( ilen > 0 ) if( ilen_dup > 0 )
mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen ); mbedtls_platform_memcpy( (void *) (ctx->buffer + left), input, ilen_dup );
/* Re-check ilen to protect from a FI attack */ /* Re-check ilen_dup to protect from a FI attack */
if( ilen < 64 ) if( ilen_dup < 64 )
{ {
/* Re-check that the calculated offsets are correct */ /* Re-check that the calculated offsets are correct */
ilen_change = ilen_dup - ilen; ilen_change = ilen - ilen_dup;
if( ( input_dup + ilen_change ) == input ) if( ( input_dup + ilen_change ) == input )
{ {
return( 0 ); return( 0 );
@ -387,7 +386,7 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
uint32_t used; uint32_t used;
uint32_t high, low; uint32_t high, low;
uint32_t offset = 0; uint32_t offset = 0;
uint32_t flow_ctrl = 0; volatile uint32_t flow_ctrl = 0;
SHA256_VALIDATE_RET( ctx != NULL ); SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); SHA256_VALIDATE_RET( (unsigned char *)output != NULL );