mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-04 04:32:24 -05: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_STAR_ENCRYPT or
 | 
			
		||||
                                                #MBEDTLS_CCM_STAR_DECRYPT. */
 | 
			
		||||
    int MBEDTLS_PRIVATE(state);              /*!< Working value holding context's
 | 
			
		||||
                                                  state. Used for chunked data
 | 
			
		||||
                                                  input */
 | 
			
		||||
}
 | 
			
		||||
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];                                   \
 | 
			
		||||
    } while( 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 )
 | 
			
		||||
#define CCM_STATE__CLEAR                0
 | 
			
		||||
#define CCM_STATE__STARTED              0x0001
 | 
			
		||||
#define CCM_STATE__LENGHTS_SET          0x0002
 | 
			
		||||
 | 
			
		||||
static void mbedtls_ccm_clear_state(mbedtls_ccm_context *ctx) {
 | 
			
		||||
    ctx->state = CCM_STATE__CLEAR;
 | 
			
		||||
    memset( ctx->b, 0, 16);
 | 
			
		||||
    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;
 | 
			
		||||
    unsigned char i;
 | 
			
		||||
    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->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
 | 
			
		||||
@ -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 )
 | 
			
		||||
        return( MBEDTLS_ERR_CCM_BAD_INPUT );
 | 
			
		||||
 | 
			
		||||
    /* Also implies q is within bounds */
 | 
			
		||||
    if( iv_len < 7 || iv_len > 13 )
 | 
			
		||||
    if( total_ad_len >= 0xFF00 )
 | 
			
		||||
        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:
 | 
			
		||||
     * 0        .. 0        flags
 | 
			
		||||
     * 1        .. iv_len   nonce (aka iv)
 | 
			
		||||
     * iv_len+1 .. 15       length
 | 
			
		||||
     * 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?
 | 
			
		||||
     * 5 .. 3   (t - 2) / 2
 | 
			
		||||
     * 2 .. 0   q - 1
 | 
			
		||||
     * 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] = 0;
 | 
			
		||||
    ctx->b[0] |= ( add_len > 0 ) << 6;
 | 
			
		||||
    ctx->b[0] |= ( total_ad_len > 0 ) << 6;
 | 
			
		||||
    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->b[15-i] = (unsigned char)( len_left & 0xFF );
 | 
			
		||||
    ctx->state |= CCM_STATE__LENGHTS_SET;
 | 
			
		||||
    ret = mbedtls_ccm_calculate_first_block(ctx);
 | 
			
		||||
 | 
			
		||||
    if( len_left > 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_CCM_BAD_INPUT );
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Start CBC-MAC with first block */
 | 
			
		||||
    memset( ctx->y, 0, 16 );
 | 
			
		||||
    UPDATE_CBC_MAC;
 | 
			
		||||
int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx,
 | 
			
		||||
                           const unsigned char *add,
 | 
			
		||||
                           size_t add_len )
 | 
			
		||||
{
 | 
			
		||||
    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
 | 
			
		||||
@ -242,20 +321,24 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 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
 | 
			
		||||
     */
 | 
			
		||||
    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;
 | 
			
		||||
    return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mbedtls_ccm_update( mbedtls_ccm_context *ctx,
 | 
			
		||||
                        const unsigned char *input, size_t input_len,
 | 
			
		||||
                        unsigned char *output, size_t output_size,
 | 
			
		||||
                        size_t *output_len )
 | 
			
		||||
{
 | 
			
		||||
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 | 
			
		||||
    unsigned char i;
 | 
			
		||||
    size_t len_left, olen;
 | 
			
		||||
    const unsigned char *src;
 | 
			
		||||
    unsigned char *dst;
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
@ -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 respective order of authentication and {en,de}cryption.
 | 
			
		||||
     */
 | 
			
		||||
    len_left = length;
 | 
			
		||||
    len_left = input_len;
 | 
			
		||||
    src = input;
 | 
			
		||||
    dst = output;
 | 
			
		||||
 | 
			
		||||
@ -300,6 +383,16 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
 | 
			
		||||
                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
 | 
			
		||||
     */
 | 
			
		||||
@ -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 );
 | 
			
		||||
    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 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user