Fix null pointer arithmetic in error case
When mbedtls_nist_kw_wrap was called with output=NULL and out_size=0, it performed arithmetic on the null pointer before detecting that the output buffer is too small and returning an error code. This was unlikely to have consequences on real-world hardware today, but it is undefined behavior and UBSan with Clang 10 flagged it. So fix it (fix #4025). Fix a similar-looking pattern in unwrap, though I haven't verified that it's reachable there. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
bbd617be5f
commit
89ee599092
1 changed files with 5 additions and 3 deletions
|
@ -189,8 +189,6 @@ int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
|
||||||
uint64_t t = 0;
|
uint64_t t = 0;
|
||||||
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
|
|
||||||
unsigned char *A = output;
|
|
||||||
|
|
||||||
*out_len = 0;
|
*out_len = 0;
|
||||||
/*
|
/*
|
||||||
|
@ -266,6 +264,9 @@ int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
|
||||||
|
unsigned char *A = output;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the wrapping function W, as defined in RFC 3394 section 2.2.1
|
* Do the wrapping function W, as defined in RFC 3394 section 2.2.1
|
||||||
*/
|
*/
|
||||||
|
@ -329,7 +330,7 @@ static int unwrap( mbedtls_nist_kw_context *ctx,
|
||||||
uint64_t t = 0;
|
uint64_t t = 0;
|
||||||
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
|
||||||
unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
|
unsigned char *R = NULL;
|
||||||
*out_len = 0;
|
*out_len = 0;
|
||||||
|
|
||||||
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
|
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
|
||||||
|
@ -339,6 +340,7 @@ static int unwrap( mbedtls_nist_kw_context *ctx,
|
||||||
|
|
||||||
memcpy( A, input, KW_SEMIBLOCK_LENGTH );
|
memcpy( A, input, KW_SEMIBLOCK_LENGTH );
|
||||||
memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
|
memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
|
||||||
|
R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
|
||||||
|
|
||||||
/* Calculate intermediate values */
|
/* Calculate intermediate values */
|
||||||
for( t = s; t >= 1; t-- )
|
for( t = s; t >= 1; t-- )
|
||||||
|
|
Loading…
Reference in a new issue