mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-03 01:20:39 +00:00
Split ccm_auth function.
Move logic to ccm_starts, ccm_set_lengths, ccm_update_ad, ccm_update and ccm_finish Use separate variable to track context state. Encode first block only if both mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() were called. Signed-off-by: Mateusz Starzyk <mateusz.starzyk@mobica.com>
This commit is contained in:
parent
89d469cdb4
commit
793692cbcb
@ -87,6 +87,9 @@ typedef struct mbedtls_ccm_context
|
|||||||
#MBEDTLS_CCM_DECRYPT or
|
#MBEDTLS_CCM_DECRYPT or
|
||||||
#MBEDTLS_CCM_STAR_ENCRYPT or
|
#MBEDTLS_CCM_STAR_ENCRYPT or
|
||||||
#MBEDTLS_CCM_STAR_DECRYPT. */
|
#MBEDTLS_CCM_STAR_DECRYPT. */
|
||||||
|
int MBEDTLS_PRIVATE(state); /*!< Working value holding context's
|
||||||
|
state. Used for chunked data
|
||||||
|
input */
|
||||||
}
|
}
|
||||||
mbedtls_ccm_context;
|
mbedtls_ccm_context;
|
||||||
|
|
||||||
|
225
library/ccm.c
225
library/ccm.c
@ -142,22 +142,105 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
|
|||||||
(dst)[i] = (src)[i] ^ ctx->b[i]; \
|
(dst)[i] = (src)[i] ^ ctx->b[i]; \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
|
||||||
/*
|
#define CCM_STATE__CLEAR 0
|
||||||
* Authenticated encryption or decryption
|
#define CCM_STATE__STARTED 0x0001
|
||||||
*/
|
#define CCM_STATE__LENGHTS_SET 0x0002
|
||||||
static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|
||||||
const unsigned char *iv, size_t iv_len,
|
static void mbedtls_ccm_clear_state(mbedtls_ccm_context *ctx) {
|
||||||
const unsigned char *add, size_t add_len,
|
ctx->state = CCM_STATE__CLEAR;
|
||||||
const unsigned char *input, unsigned char *output,
|
memset( ctx->b, 0, 16);
|
||||||
unsigned char *tag, size_t tag_len )
|
memset( ctx->y, 0, 16);
|
||||||
|
memset( ctx->ctr, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mbedtls_ccm_calculate_first_block(mbedtls_ccm_context *ctx)
|
||||||
{
|
{
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
unsigned char i;
|
unsigned char i;
|
||||||
size_t len_left, olen;
|
size_t len_left, olen;
|
||||||
const unsigned char *src;
|
|
||||||
unsigned char *dst;
|
/* length calulcation can be done only after both
|
||||||
|
* mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
|
||||||
|
*/
|
||||||
|
if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGHTS_SET) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First block B_0:
|
||||||
|
* 0 .. 0 flags - set by: mbedtls_ccm_starts() and mbedtls_ccm_set_lenghts()
|
||||||
|
* 1 .. iv_len nonce (aka iv) - set by: mbedtls_ccm_starts()
|
||||||
|
* iv_len+1 .. 15 length - set by: mbedtls_ccm_calculate_first_block()
|
||||||
|
*/
|
||||||
|
for( i = 0, len_left = ctx->plaintext_len; i < ctx->q; i++, len_left >>= 8 )
|
||||||
|
ctx->b[15-i] = (unsigned char)( len_left & 0xFF );
|
||||||
|
|
||||||
|
if( len_left > 0 )
|
||||||
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
|
/* Start CBC-MAC with first block*/
|
||||||
|
UPDATE_CBC_MAC;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_starts( mbedtls_ccm_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Also implies q is within bounds */
|
||||||
|
if( iv_len < 7 || iv_len > 13 )
|
||||||
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
ctx->mode = mode;
|
ctx->mode = mode;
|
||||||
|
ctx->q = 16 - 1 - (unsigned char) iv_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare counter block for encryption:
|
||||||
|
* 0 .. 0 flags
|
||||||
|
* 1 .. iv_len nonce (aka iv)
|
||||||
|
* iv_len+1 .. 15 counter (initially 1)
|
||||||
|
*
|
||||||
|
* With flags as (bits):
|
||||||
|
* 7 .. 3 0
|
||||||
|
* 2 .. 0 q - 1
|
||||||
|
*/
|
||||||
|
memset( ctx->ctr, 0, 16);
|
||||||
|
ctx->ctr[0] = ctx->q - 1;
|
||||||
|
memcpy( ctx->ctr + 1, iv, iv_len );
|
||||||
|
memset( ctx->ctr + 1 + iv_len, 0, ctx->q );
|
||||||
|
ctx->ctr[15] = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First block B_0:
|
||||||
|
* 0 .. 0 flags - set by: mbedtls_ccm_starts() and mbedtls_ccm_set_lenghts()
|
||||||
|
* 1 .. iv_len nonce (aka iv) - set by: mbedtls_ccm_starts()
|
||||||
|
* iv_len+1 .. 15 length - set by: mbedtls_ccm_calculate_first_block()
|
||||||
|
*
|
||||||
|
* With flags as (bits):
|
||||||
|
* 7 0
|
||||||
|
* 6 add present? - set by: mbedtls_ccm_set_lengths()
|
||||||
|
* 5 .. 3 (t - 2) / 2 - set by: mbedtls_ccm_set_lengths()
|
||||||
|
* 2 .. 0 q - 1 - set by: mbedtls_ccm_starts()
|
||||||
|
*/
|
||||||
|
ctx->b[0] |= ctx->q - 1;
|
||||||
|
|
||||||
|
memcpy( ctx->b + 1, iv, iv_len );
|
||||||
|
|
||||||
|
ctx->state |= CCM_STATE__STARTED;
|
||||||
|
ret = mbedtls_ccm_calculate_first_block(ctx);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_set_lengths( mbedtls_ccm_context *ctx,
|
||||||
|
size_t total_ad_len,
|
||||||
|
size_t plaintext_len,
|
||||||
|
size_t tag_len )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check length requirements: SP800-38C A.1
|
* Check length requirements: SP800-38C A.1
|
||||||
@ -169,44 +252,40 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|||||||
if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
|
if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
|
||||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
/* Also implies q is within bounds */
|
if( total_ad_len >= 0xFF00 )
|
||||||
if( iv_len < 7 || iv_len > 13 )
|
|
||||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
|
||||||
if( add_len >= 0xFF00 )
|
|
||||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
|
||||||
|
|
||||||
ctx->q = 16 - 1 - (unsigned char) iv_len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First block B_0:
|
* First block B_0:
|
||||||
* 0 .. 0 flags
|
* 0 .. 0 flags - set by: mbedtls_ccm_starts() and mbedtls_ccm_set_lenghts()
|
||||||
* 1 .. iv_len nonce (aka iv)
|
* 1 .. iv_len nonce (aka iv) - set by: mbedtls_ccm_starts()
|
||||||
* iv_len+1 .. 15 length
|
* iv_len+1 .. 15 length - set by: mbedtls_ccm_calculate_first_block()
|
||||||
*
|
*
|
||||||
* With flags as (bits):
|
* With flags as (bits):
|
||||||
* 7 0
|
* 7 0
|
||||||
* 6 add present?
|
* 6 add present? - set by: mbedtls_ccm_set_lengths()
|
||||||
* 5 .. 3 (t - 2) / 2
|
* 5 .. 3 (t - 2) / 2 - set by: mbedtls_ccm_set_lengths()
|
||||||
* 2 .. 0 q - 1
|
* 2 .. 0 q - 1 - set by: mbedtls_ccm_starts()
|
||||||
*/
|
*/
|
||||||
ctx->b[0] = 0;
|
ctx->b[0] |= ( total_ad_len > 0 ) << 6;
|
||||||
ctx->b[0] |= ( add_len > 0 ) << 6;
|
|
||||||
ctx->b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
|
ctx->b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
|
||||||
ctx->b[0] |= ctx->q - 1;
|
|
||||||
|
|
||||||
memcpy( ctx->b + 1, iv, iv_len );
|
ctx->plaintext_len = plaintext_len;
|
||||||
|
|
||||||
for( i = 0, len_left = length; i < ctx->q; i++, len_left >>= 8 )
|
ctx->state |= CCM_STATE__LENGHTS_SET;
|
||||||
ctx->b[15-i] = (unsigned char)( len_left & 0xFF );
|
ret = mbedtls_ccm_calculate_first_block(ctx);
|
||||||
|
|
||||||
if( len_left > 0 )
|
return ret;
|
||||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx,
|
||||||
/* Start CBC-MAC with first block */
|
const unsigned char *add,
|
||||||
memset( ctx->y, 0, 16 );
|
size_t add_len )
|
||||||
UPDATE_CBC_MAC;
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char i;
|
||||||
|
size_t len_left, olen;
|
||||||
|
const unsigned char *src;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is additional data, update CBC-MAC with
|
* If there is additional data, update CBC-MAC with
|
||||||
@ -242,20 +321,24 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return (0);
|
||||||
* Prepare counter block for encryption:
|
}
|
||||||
* 0 .. 0 flags
|
|
||||||
* 1 .. iv_len nonce (aka iv)
|
int mbedtls_ccm_update( mbedtls_ccm_context *ctx,
|
||||||
* iv_len+1 .. 15 counter (initially 1)
|
const unsigned char *input, size_t input_len,
|
||||||
*
|
unsigned char *output, size_t output_size,
|
||||||
* With flags as (bits):
|
size_t *output_len )
|
||||||
* 7 .. 3 0
|
{
|
||||||
* 2 .. 0 q - 1
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
*/
|
unsigned char i;
|
||||||
ctx->ctr[0] = ctx->q - 1;
|
size_t len_left, olen;
|
||||||
memcpy( ctx->ctr + 1, iv, iv_len );
|
const unsigned char *src;
|
||||||
memset( ctx->ctr + 1 + iv_len, 0, ctx->q );
|
unsigned char *dst;
|
||||||
ctx->ctr[15] = 1;
|
|
||||||
|
if( output_size < input_len )
|
||||||
|
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||||
|
CCM_VALIDATE_RET( output_length != NULL );
|
||||||
|
*output_len = input_len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authenticate and {en,de}crypt the message.
|
* Authenticate and {en,de}crypt the message.
|
||||||
@ -263,7 +346,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|||||||
* The only difference between encryption and decryption is
|
* The only difference between encryption and decryption is
|
||||||
* the respective order of authentication and {en,de}cryption.
|
* the respective order of authentication and {en,de}cryption.
|
||||||
*/
|
*/
|
||||||
len_left = length;
|
len_left = input_len;
|
||||||
src = input;
|
src = input;
|
||||||
dst = output;
|
dst = output;
|
||||||
|
|
||||||
@ -300,6 +383,16 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_finish( mbedtls_ccm_context *ctx,
|
||||||
|
unsigned char *tag, size_t tag_len )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
unsigned char i;
|
||||||
|
size_t olen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authentication: reset counter and crypt/mask internal tag
|
* Authentication: reset counter and crypt/mask internal tag
|
||||||
*/
|
*/
|
||||||
@ -308,6 +401,38 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
|||||||
|
|
||||||
CTR_CRYPT( ctx->y, ctx->y, 16 );
|
CTR_CRYPT( ctx->y, ctx->y, 16 );
|
||||||
memcpy( tag, ctx->y, tag_len );
|
memcpy( tag, ctx->y, tag_len );
|
||||||
|
mbedtls_ccm_clear_state(ctx);
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticated encryption or decryption
|
||||||
|
*/
|
||||||
|
static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
size_t olen;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ccm_starts( ctx, mode, iv, iv_len ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ccm_set_lengths( ctx, add_len, length, tag_len ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ccm_update_ad( ctx, add, add_len ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ccm_update( ctx, input, length,
|
||||||
|
output, length, &olen ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_ccm_finish( ctx, tag, tag_len ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user