Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /**
marcozecchini 0:9fca2b23d0ba 2 * \file cmac.c
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
marcozecchini 0:9fca2b23d0ba 5 *
marcozecchini 0:9fca2b23d0ba 6 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
marcozecchini 0:9fca2b23d0ba 7 * SPDX-License-Identifier: Apache-2.0
marcozecchini 0:9fca2b23d0ba 8 *
marcozecchini 0:9fca2b23d0ba 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
marcozecchini 0:9fca2b23d0ba 10 * not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 11 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 12 *
marcozecchini 0:9fca2b23d0ba 13 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 14 *
marcozecchini 0:9fca2b23d0ba 15 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
marcozecchini 0:9fca2b23d0ba 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 18 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 19 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 20 *
marcozecchini 0:9fca2b23d0ba 21 * This file is part of mbed TLS (https://tls.mbed.org)
marcozecchini 0:9fca2b23d0ba 22 */
marcozecchini 0:9fca2b23d0ba 23
marcozecchini 0:9fca2b23d0ba 24 /*
marcozecchini 0:9fca2b23d0ba 25 * References:
marcozecchini 0:9fca2b23d0ba 26 *
marcozecchini 0:9fca2b23d0ba 27 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
marcozecchini 0:9fca2b23d0ba 28 * CMAC Mode for Authentication
marcozecchini 0:9fca2b23d0ba 29 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
marcozecchini 0:9fca2b23d0ba 30 *
marcozecchini 0:9fca2b23d0ba 31 * - RFC 4493 - The AES-CMAC Algorithm
marcozecchini 0:9fca2b23d0ba 32 * https://tools.ietf.org/html/rfc4493
marcozecchini 0:9fca2b23d0ba 33 *
marcozecchini 0:9fca2b23d0ba 34 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
marcozecchini 0:9fca2b23d0ba 35 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
marcozecchini 0:9fca2b23d0ba 36 * Algorithm for the Internet Key Exchange Protocol (IKE)
marcozecchini 0:9fca2b23d0ba 37 * https://tools.ietf.org/html/rfc4615
marcozecchini 0:9fca2b23d0ba 38 *
marcozecchini 0:9fca2b23d0ba 39 * Additional test vectors: ISO/IEC 9797-1
marcozecchini 0:9fca2b23d0ba 40 *
marcozecchini 0:9fca2b23d0ba 41 */
marcozecchini 0:9fca2b23d0ba 42
marcozecchini 0:9fca2b23d0ba 43 #if !defined(MBEDTLS_CONFIG_FILE)
marcozecchini 0:9fca2b23d0ba 44 #include "mbedtls/config.h"
marcozecchini 0:9fca2b23d0ba 45 #else
marcozecchini 0:9fca2b23d0ba 46 #include MBEDTLS_CONFIG_FILE
marcozecchini 0:9fca2b23d0ba 47 #endif
marcozecchini 0:9fca2b23d0ba 48
marcozecchini 0:9fca2b23d0ba 49 #if defined(MBEDTLS_CMAC_C)
marcozecchini 0:9fca2b23d0ba 50
marcozecchini 0:9fca2b23d0ba 51 #include "mbedtls/cmac.h"
marcozecchini 0:9fca2b23d0ba 52
marcozecchini 0:9fca2b23d0ba 53 #include <string.h>
marcozecchini 0:9fca2b23d0ba 54
marcozecchini 0:9fca2b23d0ba 55
marcozecchini 0:9fca2b23d0ba 56 #if defined(MBEDTLS_PLATFORM_C)
marcozecchini 0:9fca2b23d0ba 57 #include "mbedtls/platform.h"
marcozecchini 0:9fca2b23d0ba 58 #else
marcozecchini 0:9fca2b23d0ba 59 #include <stdlib.h>
marcozecchini 0:9fca2b23d0ba 60 #define mbedtls_calloc calloc
marcozecchini 0:9fca2b23d0ba 61 #define mbedtls_free free
marcozecchini 0:9fca2b23d0ba 62 #if defined(MBEDTLS_SELF_TEST)
marcozecchini 0:9fca2b23d0ba 63 #include <stdio.h>
marcozecchini 0:9fca2b23d0ba 64 #define mbedtls_printf printf
marcozecchini 0:9fca2b23d0ba 65 #endif /* MBEDTLS_SELF_TEST */
marcozecchini 0:9fca2b23d0ba 66 #endif /* MBEDTLS_PLATFORM_C */
marcozecchini 0:9fca2b23d0ba 67
marcozecchini 0:9fca2b23d0ba 68 /* Implementation that should never be optimized out by the compiler */
marcozecchini 0:9fca2b23d0ba 69 static void mbedtls_zeroize( void *v, size_t n ) {
marcozecchini 0:9fca2b23d0ba 70 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
marcozecchini 0:9fca2b23d0ba 71 }
marcozecchini 0:9fca2b23d0ba 72
marcozecchini 0:9fca2b23d0ba 73 /*
marcozecchini 0:9fca2b23d0ba 74 * Multiplication by u in the Galois field of GF(2^n)
marcozecchini 0:9fca2b23d0ba 75 *
marcozecchini 0:9fca2b23d0ba 76 * As explained in NIST SP 800-38B, this can be computed:
marcozecchini 0:9fca2b23d0ba 77 *
marcozecchini 0:9fca2b23d0ba 78 * If MSB(p) = 0, then p = (p << 1)
marcozecchini 0:9fca2b23d0ba 79 * If MSB(p) = 1, then p = (p << 1) ^ R_n
marcozecchini 0:9fca2b23d0ba 80 * with R_64 = 0x1B and R_128 = 0x87
marcozecchini 0:9fca2b23d0ba 81 *
marcozecchini 0:9fca2b23d0ba 82 * Input and output MUST NOT point to the same buffer
marcozecchini 0:9fca2b23d0ba 83 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
marcozecchini 0:9fca2b23d0ba 84 */
marcozecchini 0:9fca2b23d0ba 85 static int cmac_multiply_by_u( unsigned char *output,
marcozecchini 0:9fca2b23d0ba 86 const unsigned char *input,
marcozecchini 0:9fca2b23d0ba 87 size_t blocksize )
marcozecchini 0:9fca2b23d0ba 88 {
marcozecchini 0:9fca2b23d0ba 89 const unsigned char R_128 = 0x87;
marcozecchini 0:9fca2b23d0ba 90 const unsigned char R_64 = 0x1B;
marcozecchini 0:9fca2b23d0ba 91 unsigned char R_n, mask;
marcozecchini 0:9fca2b23d0ba 92 unsigned char overflow = 0x00;
marcozecchini 0:9fca2b23d0ba 93 int i;
marcozecchini 0:9fca2b23d0ba 94
marcozecchini 0:9fca2b23d0ba 95 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
marcozecchini 0:9fca2b23d0ba 96 {
marcozecchini 0:9fca2b23d0ba 97 R_n = R_128;
marcozecchini 0:9fca2b23d0ba 98 }
marcozecchini 0:9fca2b23d0ba 99 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
marcozecchini 0:9fca2b23d0ba 100 {
marcozecchini 0:9fca2b23d0ba 101 R_n = R_64;
marcozecchini 0:9fca2b23d0ba 102 }
marcozecchini 0:9fca2b23d0ba 103 else
marcozecchini 0:9fca2b23d0ba 104 {
marcozecchini 0:9fca2b23d0ba 105 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 106 }
marcozecchini 0:9fca2b23d0ba 107
marcozecchini 0:9fca2b23d0ba 108 for( i = (int)blocksize - 1; i >= 0; i-- )
marcozecchini 0:9fca2b23d0ba 109 {
marcozecchini 0:9fca2b23d0ba 110 output[i] = input[i] << 1 | overflow;
marcozecchini 0:9fca2b23d0ba 111 overflow = input[i] >> 7;
marcozecchini 0:9fca2b23d0ba 112 }
marcozecchini 0:9fca2b23d0ba 113
marcozecchini 0:9fca2b23d0ba 114 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
marcozecchini 0:9fca2b23d0ba 115 * using bit operations to avoid branches */
marcozecchini 0:9fca2b23d0ba 116
marcozecchini 0:9fca2b23d0ba 117 /* MSVC has a warning about unary minus on unsigned, but this is
marcozecchini 0:9fca2b23d0ba 118 * well-defined and precisely what we want to do here */
marcozecchini 0:9fca2b23d0ba 119 #if defined(_MSC_VER)
marcozecchini 0:9fca2b23d0ba 120 #pragma warning( push )
marcozecchini 0:9fca2b23d0ba 121 #pragma warning( disable : 4146 )
marcozecchini 0:9fca2b23d0ba 122 #endif
marcozecchini 0:9fca2b23d0ba 123 mask = - ( input[0] >> 7 );
marcozecchini 0:9fca2b23d0ba 124 #if defined(_MSC_VER)
marcozecchini 0:9fca2b23d0ba 125 #pragma warning( pop )
marcozecchini 0:9fca2b23d0ba 126 #endif
marcozecchini 0:9fca2b23d0ba 127
marcozecchini 0:9fca2b23d0ba 128 output[ blocksize - 1 ] ^= R_n & mask;
marcozecchini 0:9fca2b23d0ba 129
marcozecchini 0:9fca2b23d0ba 130 return( 0 );
marcozecchini 0:9fca2b23d0ba 131 }
marcozecchini 0:9fca2b23d0ba 132
marcozecchini 0:9fca2b23d0ba 133 /*
marcozecchini 0:9fca2b23d0ba 134 * Generate subkeys
marcozecchini 0:9fca2b23d0ba 135 *
marcozecchini 0:9fca2b23d0ba 136 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
marcozecchini 0:9fca2b23d0ba 137 */
marcozecchini 0:9fca2b23d0ba 138 static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
marcozecchini 0:9fca2b23d0ba 139 unsigned char* K1, unsigned char* K2 )
marcozecchini 0:9fca2b23d0ba 140 {
marcozecchini 0:9fca2b23d0ba 141 int ret;
marcozecchini 0:9fca2b23d0ba 142 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 143 size_t olen, block_size;
marcozecchini 0:9fca2b23d0ba 144
marcozecchini 0:9fca2b23d0ba 145 mbedtls_zeroize( L, sizeof( L ) );
marcozecchini 0:9fca2b23d0ba 146
marcozecchini 0:9fca2b23d0ba 147 block_size = ctx->cipher_info->block_size;
marcozecchini 0:9fca2b23d0ba 148
marcozecchini 0:9fca2b23d0ba 149 /* Calculate Ek(0) */
marcozecchini 0:9fca2b23d0ba 150 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 151 goto exit;
marcozecchini 0:9fca2b23d0ba 152
marcozecchini 0:9fca2b23d0ba 153 /*
marcozecchini 0:9fca2b23d0ba 154 * Generate K1 and K2
marcozecchini 0:9fca2b23d0ba 155 */
marcozecchini 0:9fca2b23d0ba 156 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 157 goto exit;
marcozecchini 0:9fca2b23d0ba 158
marcozecchini 0:9fca2b23d0ba 159 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 160 goto exit;
marcozecchini 0:9fca2b23d0ba 161
marcozecchini 0:9fca2b23d0ba 162 exit:
marcozecchini 0:9fca2b23d0ba 163 mbedtls_zeroize( L, sizeof( L ) );
marcozecchini 0:9fca2b23d0ba 164
marcozecchini 0:9fca2b23d0ba 165 return( ret );
marcozecchini 0:9fca2b23d0ba 166 }
marcozecchini 0:9fca2b23d0ba 167
marcozecchini 0:9fca2b23d0ba 168 static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
marcozecchini 0:9fca2b23d0ba 169 const unsigned char *input2,
marcozecchini 0:9fca2b23d0ba 170 const size_t block_size )
marcozecchini 0:9fca2b23d0ba 171 {
marcozecchini 0:9fca2b23d0ba 172 size_t idx;
marcozecchini 0:9fca2b23d0ba 173
marcozecchini 0:9fca2b23d0ba 174 for( idx = 0; idx < block_size; idx++ )
marcozecchini 0:9fca2b23d0ba 175 output[ idx ] = input1[ idx ] ^ input2[ idx ];
marcozecchini 0:9fca2b23d0ba 176 }
marcozecchini 0:9fca2b23d0ba 177
marcozecchini 0:9fca2b23d0ba 178 /*
marcozecchini 0:9fca2b23d0ba 179 * Create padded last block from (partial) last block.
marcozecchini 0:9fca2b23d0ba 180 *
marcozecchini 0:9fca2b23d0ba 181 * We can't use the padding option from the cipher layer, as it only works for
marcozecchini 0:9fca2b23d0ba 182 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
marcozecchini 0:9fca2b23d0ba 183 */
marcozecchini 0:9fca2b23d0ba 184 static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
marcozecchini 0:9fca2b23d0ba 185 size_t padded_block_len,
marcozecchini 0:9fca2b23d0ba 186 const unsigned char *last_block,
marcozecchini 0:9fca2b23d0ba 187 size_t last_block_len )
marcozecchini 0:9fca2b23d0ba 188 {
marcozecchini 0:9fca2b23d0ba 189 size_t j;
marcozecchini 0:9fca2b23d0ba 190
marcozecchini 0:9fca2b23d0ba 191 for( j = 0; j < padded_block_len; j++ )
marcozecchini 0:9fca2b23d0ba 192 {
marcozecchini 0:9fca2b23d0ba 193 if( j < last_block_len )
marcozecchini 0:9fca2b23d0ba 194 padded_block[j] = last_block[j];
marcozecchini 0:9fca2b23d0ba 195 else if( j == last_block_len )
marcozecchini 0:9fca2b23d0ba 196 padded_block[j] = 0x80;
marcozecchini 0:9fca2b23d0ba 197 else
marcozecchini 0:9fca2b23d0ba 198 padded_block[j] = 0x00;
marcozecchini 0:9fca2b23d0ba 199 }
marcozecchini 0:9fca2b23d0ba 200 }
marcozecchini 0:9fca2b23d0ba 201
marcozecchini 0:9fca2b23d0ba 202 int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
marcozecchini 0:9fca2b23d0ba 203 const unsigned char *key, size_t keybits )
marcozecchini 0:9fca2b23d0ba 204 {
marcozecchini 0:9fca2b23d0ba 205 mbedtls_cipher_type_t type;
marcozecchini 0:9fca2b23d0ba 206 mbedtls_cmac_context_t *cmac_ctx;
marcozecchini 0:9fca2b23d0ba 207 int retval;
marcozecchini 0:9fca2b23d0ba 208
marcozecchini 0:9fca2b23d0ba 209 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
marcozecchini 0:9fca2b23d0ba 210 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 211
marcozecchini 0:9fca2b23d0ba 212 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
marcozecchini 0:9fca2b23d0ba 213 MBEDTLS_ENCRYPT ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 214 return( retval );
marcozecchini 0:9fca2b23d0ba 215
marcozecchini 0:9fca2b23d0ba 216 type = ctx->cipher_info->type;
marcozecchini 0:9fca2b23d0ba 217
marcozecchini 0:9fca2b23d0ba 218 switch( type )
marcozecchini 0:9fca2b23d0ba 219 {
marcozecchini 0:9fca2b23d0ba 220 case MBEDTLS_CIPHER_AES_128_ECB:
marcozecchini 0:9fca2b23d0ba 221 case MBEDTLS_CIPHER_AES_192_ECB:
marcozecchini 0:9fca2b23d0ba 222 case MBEDTLS_CIPHER_AES_256_ECB:
marcozecchini 0:9fca2b23d0ba 223 case MBEDTLS_CIPHER_DES_EDE3_ECB:
marcozecchini 0:9fca2b23d0ba 224 break;
marcozecchini 0:9fca2b23d0ba 225 default:
marcozecchini 0:9fca2b23d0ba 226 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 227 }
marcozecchini 0:9fca2b23d0ba 228
marcozecchini 0:9fca2b23d0ba 229 /* Allocated and initialise in the cipher context memory for the CMAC
marcozecchini 0:9fca2b23d0ba 230 * context */
marcozecchini 0:9fca2b23d0ba 231 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
marcozecchini 0:9fca2b23d0ba 232 if( cmac_ctx == NULL )
marcozecchini 0:9fca2b23d0ba 233 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
marcozecchini 0:9fca2b23d0ba 234
marcozecchini 0:9fca2b23d0ba 235 ctx->cmac_ctx = cmac_ctx;
marcozecchini 0:9fca2b23d0ba 236
marcozecchini 0:9fca2b23d0ba 237 mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
marcozecchini 0:9fca2b23d0ba 238
marcozecchini 0:9fca2b23d0ba 239 return 0;
marcozecchini 0:9fca2b23d0ba 240 }
marcozecchini 0:9fca2b23d0ba 241
marcozecchini 0:9fca2b23d0ba 242 int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
marcozecchini 0:9fca2b23d0ba 243 const unsigned char *input, size_t ilen )
marcozecchini 0:9fca2b23d0ba 244 {
marcozecchini 0:9fca2b23d0ba 245 mbedtls_cmac_context_t* cmac_ctx;
marcozecchini 0:9fca2b23d0ba 246 unsigned char *state;
marcozecchini 0:9fca2b23d0ba 247 int ret = 0;
marcozecchini 0:9fca2b23d0ba 248 size_t n, j, olen, block_size;
marcozecchini 0:9fca2b23d0ba 249
marcozecchini 0:9fca2b23d0ba 250 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
marcozecchini 0:9fca2b23d0ba 251 ctx->cmac_ctx == NULL )
marcozecchini 0:9fca2b23d0ba 252 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 253
marcozecchini 0:9fca2b23d0ba 254 cmac_ctx = ctx->cmac_ctx;
marcozecchini 0:9fca2b23d0ba 255 block_size = ctx->cipher_info->block_size;
marcozecchini 0:9fca2b23d0ba 256 state = ctx->cmac_ctx->state;
marcozecchini 0:9fca2b23d0ba 257
marcozecchini 0:9fca2b23d0ba 258 /* Is there data still to process from the last call, that's greater in
marcozecchini 0:9fca2b23d0ba 259 * size than a block? */
marcozecchini 0:9fca2b23d0ba 260 if( cmac_ctx->unprocessed_len > 0 &&
marcozecchini 0:9fca2b23d0ba 261 ilen > block_size - cmac_ctx->unprocessed_len )
marcozecchini 0:9fca2b23d0ba 262 {
marcozecchini 0:9fca2b23d0ba 263 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
marcozecchini 0:9fca2b23d0ba 264 input,
marcozecchini 0:9fca2b23d0ba 265 block_size - cmac_ctx->unprocessed_len );
marcozecchini 0:9fca2b23d0ba 266
marcozecchini 0:9fca2b23d0ba 267 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
marcozecchini 0:9fca2b23d0ba 268
marcozecchini 0:9fca2b23d0ba 269 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
marcozecchini 0:9fca2b23d0ba 270 &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 271 {
marcozecchini 0:9fca2b23d0ba 272 goto exit;
marcozecchini 0:9fca2b23d0ba 273 }
marcozecchini 0:9fca2b23d0ba 274
marcozecchini 0:9fca2b23d0ba 275 input += block_size - cmac_ctx->unprocessed_len;
marcozecchini 0:9fca2b23d0ba 276 ilen -= block_size - cmac_ctx->unprocessed_len;
marcozecchini 0:9fca2b23d0ba 277 cmac_ctx->unprocessed_len = 0;
marcozecchini 0:9fca2b23d0ba 278 }
marcozecchini 0:9fca2b23d0ba 279
marcozecchini 0:9fca2b23d0ba 280 /* n is the number of blocks including any final partial block */
marcozecchini 0:9fca2b23d0ba 281 n = ( ilen + block_size - 1 ) / block_size;
marcozecchini 0:9fca2b23d0ba 282
marcozecchini 0:9fca2b23d0ba 283 /* Iterate across the input data in block sized chunks, excluding any
marcozecchini 0:9fca2b23d0ba 284 * final partial or complete block */
marcozecchini 0:9fca2b23d0ba 285 for( j = 1; j < n; j++ )
marcozecchini 0:9fca2b23d0ba 286 {
marcozecchini 0:9fca2b23d0ba 287 cmac_xor_block( state, input, state, block_size );
marcozecchini 0:9fca2b23d0ba 288
marcozecchini 0:9fca2b23d0ba 289 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
marcozecchini 0:9fca2b23d0ba 290 &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 291 goto exit;
marcozecchini 0:9fca2b23d0ba 292
marcozecchini 0:9fca2b23d0ba 293 ilen -= block_size;
marcozecchini 0:9fca2b23d0ba 294 input += block_size;
marcozecchini 0:9fca2b23d0ba 295 }
marcozecchini 0:9fca2b23d0ba 296
marcozecchini 0:9fca2b23d0ba 297 /* If there is data left over that wasn't aligned to a block */
marcozecchini 0:9fca2b23d0ba 298 if( ilen > 0 )
marcozecchini 0:9fca2b23d0ba 299 {
marcozecchini 0:9fca2b23d0ba 300 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
marcozecchini 0:9fca2b23d0ba 301 input,
marcozecchini 0:9fca2b23d0ba 302 ilen );
marcozecchini 0:9fca2b23d0ba 303 cmac_ctx->unprocessed_len += ilen;
marcozecchini 0:9fca2b23d0ba 304 }
marcozecchini 0:9fca2b23d0ba 305
marcozecchini 0:9fca2b23d0ba 306 exit:
marcozecchini 0:9fca2b23d0ba 307 return( ret );
marcozecchini 0:9fca2b23d0ba 308 }
marcozecchini 0:9fca2b23d0ba 309
marcozecchini 0:9fca2b23d0ba 310 int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
marcozecchini 0:9fca2b23d0ba 311 unsigned char *output )
marcozecchini 0:9fca2b23d0ba 312 {
marcozecchini 0:9fca2b23d0ba 313 mbedtls_cmac_context_t* cmac_ctx;
marcozecchini 0:9fca2b23d0ba 314 unsigned char *state, *last_block;
marcozecchini 0:9fca2b23d0ba 315 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 316 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 317 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 318 int ret;
marcozecchini 0:9fca2b23d0ba 319 size_t olen, block_size;
marcozecchini 0:9fca2b23d0ba 320
marcozecchini 0:9fca2b23d0ba 321 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
marcozecchini 0:9fca2b23d0ba 322 output == NULL )
marcozecchini 0:9fca2b23d0ba 323 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 324
marcozecchini 0:9fca2b23d0ba 325 cmac_ctx = ctx->cmac_ctx;
marcozecchini 0:9fca2b23d0ba 326 block_size = ctx->cipher_info->block_size;
marcozecchini 0:9fca2b23d0ba 327 state = cmac_ctx->state;
marcozecchini 0:9fca2b23d0ba 328
marcozecchini 0:9fca2b23d0ba 329 mbedtls_zeroize( K1, sizeof( K1 ) );
marcozecchini 0:9fca2b23d0ba 330 mbedtls_zeroize( K2, sizeof( K2 ) );
marcozecchini 0:9fca2b23d0ba 331 cmac_generate_subkeys( ctx, K1, K2 );
marcozecchini 0:9fca2b23d0ba 332
marcozecchini 0:9fca2b23d0ba 333 last_block = cmac_ctx->unprocessed_block;
marcozecchini 0:9fca2b23d0ba 334
marcozecchini 0:9fca2b23d0ba 335 /* Calculate last block */
marcozecchini 0:9fca2b23d0ba 336 if( cmac_ctx->unprocessed_len < block_size )
marcozecchini 0:9fca2b23d0ba 337 {
marcozecchini 0:9fca2b23d0ba 338 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
marcozecchini 0:9fca2b23d0ba 339 cmac_xor_block( M_last, M_last, K2, block_size );
marcozecchini 0:9fca2b23d0ba 340 }
marcozecchini 0:9fca2b23d0ba 341 else
marcozecchini 0:9fca2b23d0ba 342 {
marcozecchini 0:9fca2b23d0ba 343 /* Last block is complete block */
marcozecchini 0:9fca2b23d0ba 344 cmac_xor_block( M_last, last_block, K1, block_size );
marcozecchini 0:9fca2b23d0ba 345 }
marcozecchini 0:9fca2b23d0ba 346
marcozecchini 0:9fca2b23d0ba 347
marcozecchini 0:9fca2b23d0ba 348 cmac_xor_block( state, M_last, state, block_size );
marcozecchini 0:9fca2b23d0ba 349 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
marcozecchini 0:9fca2b23d0ba 350 &olen ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 351 {
marcozecchini 0:9fca2b23d0ba 352 goto exit;
marcozecchini 0:9fca2b23d0ba 353 }
marcozecchini 0:9fca2b23d0ba 354
marcozecchini 0:9fca2b23d0ba 355 memcpy( output, state, block_size );
marcozecchini 0:9fca2b23d0ba 356
marcozecchini 0:9fca2b23d0ba 357 exit:
marcozecchini 0:9fca2b23d0ba 358 /* Wipe the generated keys on the stack, and any other transients to avoid
marcozecchini 0:9fca2b23d0ba 359 * side channel leakage */
marcozecchini 0:9fca2b23d0ba 360 mbedtls_zeroize( K1, sizeof( K1 ) );
marcozecchini 0:9fca2b23d0ba 361 mbedtls_zeroize( K2, sizeof( K2 ) );
marcozecchini 0:9fca2b23d0ba 362
marcozecchini 0:9fca2b23d0ba 363 cmac_ctx->unprocessed_len = 0;
marcozecchini 0:9fca2b23d0ba 364 mbedtls_zeroize( cmac_ctx->unprocessed_block,
marcozecchini 0:9fca2b23d0ba 365 sizeof( cmac_ctx->unprocessed_block ) );
marcozecchini 0:9fca2b23d0ba 366
marcozecchini 0:9fca2b23d0ba 367 mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
marcozecchini 0:9fca2b23d0ba 368 return( ret );
marcozecchini 0:9fca2b23d0ba 369 }
marcozecchini 0:9fca2b23d0ba 370
marcozecchini 0:9fca2b23d0ba 371 int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
marcozecchini 0:9fca2b23d0ba 372 {
marcozecchini 0:9fca2b23d0ba 373 mbedtls_cmac_context_t* cmac_ctx;
marcozecchini 0:9fca2b23d0ba 374
marcozecchini 0:9fca2b23d0ba 375 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
marcozecchini 0:9fca2b23d0ba 376 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 377
marcozecchini 0:9fca2b23d0ba 378 cmac_ctx = ctx->cmac_ctx;
marcozecchini 0:9fca2b23d0ba 379
marcozecchini 0:9fca2b23d0ba 380 /* Reset the internal state */
marcozecchini 0:9fca2b23d0ba 381 cmac_ctx->unprocessed_len = 0;
marcozecchini 0:9fca2b23d0ba 382 mbedtls_zeroize( cmac_ctx->unprocessed_block,
marcozecchini 0:9fca2b23d0ba 383 sizeof( cmac_ctx->unprocessed_block ) );
marcozecchini 0:9fca2b23d0ba 384 mbedtls_zeroize( cmac_ctx->state,
marcozecchini 0:9fca2b23d0ba 385 sizeof( cmac_ctx->state ) );
marcozecchini 0:9fca2b23d0ba 386
marcozecchini 0:9fca2b23d0ba 387 return( 0 );
marcozecchini 0:9fca2b23d0ba 388 }
marcozecchini 0:9fca2b23d0ba 389
marcozecchini 0:9fca2b23d0ba 390 int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
marcozecchini 0:9fca2b23d0ba 391 const unsigned char *key, size_t keylen,
marcozecchini 0:9fca2b23d0ba 392 const unsigned char *input, size_t ilen,
marcozecchini 0:9fca2b23d0ba 393 unsigned char *output )
marcozecchini 0:9fca2b23d0ba 394 {
marcozecchini 0:9fca2b23d0ba 395 mbedtls_cipher_context_t ctx;
marcozecchini 0:9fca2b23d0ba 396 int ret;
marcozecchini 0:9fca2b23d0ba 397
marcozecchini 0:9fca2b23d0ba 398 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
marcozecchini 0:9fca2b23d0ba 399 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 400
marcozecchini 0:9fca2b23d0ba 401 mbedtls_cipher_init( &ctx );
marcozecchini 0:9fca2b23d0ba 402
marcozecchini 0:9fca2b23d0ba 403 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 404 goto exit;
marcozecchini 0:9fca2b23d0ba 405
marcozecchini 0:9fca2b23d0ba 406 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
marcozecchini 0:9fca2b23d0ba 407 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 408 goto exit;
marcozecchini 0:9fca2b23d0ba 409
marcozecchini 0:9fca2b23d0ba 410 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
marcozecchini 0:9fca2b23d0ba 411 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 412 goto exit;
marcozecchini 0:9fca2b23d0ba 413
marcozecchini 0:9fca2b23d0ba 414 ret = mbedtls_cipher_cmac_finish( &ctx, output );
marcozecchini 0:9fca2b23d0ba 415
marcozecchini 0:9fca2b23d0ba 416 exit:
marcozecchini 0:9fca2b23d0ba 417 mbedtls_cipher_free( &ctx );
marcozecchini 0:9fca2b23d0ba 418
marcozecchini 0:9fca2b23d0ba 419 return( ret );
marcozecchini 0:9fca2b23d0ba 420 }
marcozecchini 0:9fca2b23d0ba 421
marcozecchini 0:9fca2b23d0ba 422 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 423 /*
marcozecchini 0:9fca2b23d0ba 424 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
marcozecchini 0:9fca2b23d0ba 425 */
marcozecchini 0:9fca2b23d0ba 426 int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
marcozecchini 0:9fca2b23d0ba 427 const unsigned char *input, size_t in_len,
marcozecchini 0:9fca2b23d0ba 428 unsigned char *output )
marcozecchini 0:9fca2b23d0ba 429 {
marcozecchini 0:9fca2b23d0ba 430 int ret;
marcozecchini 0:9fca2b23d0ba 431 const mbedtls_cipher_info_t *cipher_info;
marcozecchini 0:9fca2b23d0ba 432 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
marcozecchini 0:9fca2b23d0ba 433 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
marcozecchini 0:9fca2b23d0ba 434
marcozecchini 0:9fca2b23d0ba 435 if( key == NULL || input == NULL || output == NULL )
marcozecchini 0:9fca2b23d0ba 436 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
marcozecchini 0:9fca2b23d0ba 437
marcozecchini 0:9fca2b23d0ba 438 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
marcozecchini 0:9fca2b23d0ba 439 if( cipher_info == NULL )
marcozecchini 0:9fca2b23d0ba 440 {
marcozecchini 0:9fca2b23d0ba 441 /* Failing at this point must be due to a build issue */
marcozecchini 0:9fca2b23d0ba 442 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 443 goto exit;
marcozecchini 0:9fca2b23d0ba 444 }
marcozecchini 0:9fca2b23d0ba 445
marcozecchini 0:9fca2b23d0ba 446 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
marcozecchini 0:9fca2b23d0ba 447 {
marcozecchini 0:9fca2b23d0ba 448 /* Use key as is */
marcozecchini 0:9fca2b23d0ba 449 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
marcozecchini 0:9fca2b23d0ba 450 }
marcozecchini 0:9fca2b23d0ba 451 else
marcozecchini 0:9fca2b23d0ba 452 {
marcozecchini 0:9fca2b23d0ba 453 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
marcozecchini 0:9fca2b23d0ba 454
marcozecchini 0:9fca2b23d0ba 455 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
marcozecchini 0:9fca2b23d0ba 456 key_length, int_key );
marcozecchini 0:9fca2b23d0ba 457 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 458 goto exit;
marcozecchini 0:9fca2b23d0ba 459 }
marcozecchini 0:9fca2b23d0ba 460
marcozecchini 0:9fca2b23d0ba 461 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
marcozecchini 0:9fca2b23d0ba 462 output );
marcozecchini 0:9fca2b23d0ba 463
marcozecchini 0:9fca2b23d0ba 464 exit:
marcozecchini 0:9fca2b23d0ba 465 mbedtls_zeroize( int_key, sizeof( int_key ) );
marcozecchini 0:9fca2b23d0ba 466
marcozecchini 0:9fca2b23d0ba 467 return( ret );
marcozecchini 0:9fca2b23d0ba 468 }
marcozecchini 0:9fca2b23d0ba 469 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 470
marcozecchini 0:9fca2b23d0ba 471 #if defined(MBEDTLS_SELF_TEST)
marcozecchini 0:9fca2b23d0ba 472 /*
marcozecchini 0:9fca2b23d0ba 473 * CMAC test data for SP800-38B
marcozecchini 0:9fca2b23d0ba 474 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
marcozecchini 0:9fca2b23d0ba 475 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
marcozecchini 0:9fca2b23d0ba 476 *
marcozecchini 0:9fca2b23d0ba 477 * AES-CMAC-PRF-128 test data from RFC 4615
marcozecchini 0:9fca2b23d0ba 478 * https://tools.ietf.org/html/rfc4615#page-4
marcozecchini 0:9fca2b23d0ba 479 */
marcozecchini 0:9fca2b23d0ba 480
marcozecchini 0:9fca2b23d0ba 481 #define NB_CMAC_TESTS_PER_KEY 4
marcozecchini 0:9fca2b23d0ba 482 #define NB_PRF_TESTS 3
marcozecchini 0:9fca2b23d0ba 483
marcozecchini 0:9fca2b23d0ba 484 #if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
marcozecchini 0:9fca2b23d0ba 485 /* All CMAC test inputs are truncated from the same 64 byte buffer. */
marcozecchini 0:9fca2b23d0ba 486 static const unsigned char test_message[] = {
marcozecchini 0:9fca2b23d0ba 487 /* PT */
marcozecchini 0:9fca2b23d0ba 488 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
marcozecchini 0:9fca2b23d0ba 489 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
marcozecchini 0:9fca2b23d0ba 490 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
marcozecchini 0:9fca2b23d0ba 491 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
marcozecchini 0:9fca2b23d0ba 492 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
marcozecchini 0:9fca2b23d0ba 493 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
marcozecchini 0:9fca2b23d0ba 494 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
marcozecchini 0:9fca2b23d0ba 495 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
marcozecchini 0:9fca2b23d0ba 496 };
marcozecchini 0:9fca2b23d0ba 497 #endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
marcozecchini 0:9fca2b23d0ba 498
marcozecchini 0:9fca2b23d0ba 499 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 500 /* Truncation point of message for AES CMAC tests */
marcozecchini 0:9fca2b23d0ba 501 static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
marcozecchini 0:9fca2b23d0ba 502 /* Mlen */
marcozecchini 0:9fca2b23d0ba 503 0,
marcozecchini 0:9fca2b23d0ba 504 16,
marcozecchini 0:9fca2b23d0ba 505 20,
marcozecchini 0:9fca2b23d0ba 506 64
marcozecchini 0:9fca2b23d0ba 507 };
marcozecchini 0:9fca2b23d0ba 508
marcozecchini 0:9fca2b23d0ba 509 /* CMAC-AES128 Test Data */
marcozecchini 0:9fca2b23d0ba 510 static const unsigned char aes_128_key[16] = {
marcozecchini 0:9fca2b23d0ba 511 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
marcozecchini 0:9fca2b23d0ba 512 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
marcozecchini 0:9fca2b23d0ba 513 };
marcozecchini 0:9fca2b23d0ba 514 static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 515 {
marcozecchini 0:9fca2b23d0ba 516 /* K1 */
marcozecchini 0:9fca2b23d0ba 517 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
marcozecchini 0:9fca2b23d0ba 518 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
marcozecchini 0:9fca2b23d0ba 519 },
marcozecchini 0:9fca2b23d0ba 520 {
marcozecchini 0:9fca2b23d0ba 521 /* K2 */
marcozecchini 0:9fca2b23d0ba 522 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
marcozecchini 0:9fca2b23d0ba 523 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
marcozecchini 0:9fca2b23d0ba 524 }
marcozecchini 0:9fca2b23d0ba 525 };
marcozecchini 0:9fca2b23d0ba 526 static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 527 {
marcozecchini 0:9fca2b23d0ba 528 /* Example #1 */
marcozecchini 0:9fca2b23d0ba 529 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
marcozecchini 0:9fca2b23d0ba 530 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
marcozecchini 0:9fca2b23d0ba 531 },
marcozecchini 0:9fca2b23d0ba 532 {
marcozecchini 0:9fca2b23d0ba 533 /* Example #2 */
marcozecchini 0:9fca2b23d0ba 534 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
marcozecchini 0:9fca2b23d0ba 535 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
marcozecchini 0:9fca2b23d0ba 536 },
marcozecchini 0:9fca2b23d0ba 537 {
marcozecchini 0:9fca2b23d0ba 538 /* Example #3 */
marcozecchini 0:9fca2b23d0ba 539 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
marcozecchini 0:9fca2b23d0ba 540 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
marcozecchini 0:9fca2b23d0ba 541 },
marcozecchini 0:9fca2b23d0ba 542 {
marcozecchini 0:9fca2b23d0ba 543 /* Example #4 */
marcozecchini 0:9fca2b23d0ba 544 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
marcozecchini 0:9fca2b23d0ba 545 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
marcozecchini 0:9fca2b23d0ba 546 }
marcozecchini 0:9fca2b23d0ba 547 };
marcozecchini 0:9fca2b23d0ba 548
marcozecchini 0:9fca2b23d0ba 549 /* CMAC-AES192 Test Data */
marcozecchini 0:9fca2b23d0ba 550 static const unsigned char aes_192_key[24] = {
marcozecchini 0:9fca2b23d0ba 551 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
marcozecchini 0:9fca2b23d0ba 552 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
marcozecchini 0:9fca2b23d0ba 553 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
marcozecchini 0:9fca2b23d0ba 554 };
marcozecchini 0:9fca2b23d0ba 555 static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 556 {
marcozecchini 0:9fca2b23d0ba 557 /* K1 */
marcozecchini 0:9fca2b23d0ba 558 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
marcozecchini 0:9fca2b23d0ba 559 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
marcozecchini 0:9fca2b23d0ba 560 },
marcozecchini 0:9fca2b23d0ba 561 {
marcozecchini 0:9fca2b23d0ba 562 /* K2 */
marcozecchini 0:9fca2b23d0ba 563 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
marcozecchini 0:9fca2b23d0ba 564 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
marcozecchini 0:9fca2b23d0ba 565 }
marcozecchini 0:9fca2b23d0ba 566 };
marcozecchini 0:9fca2b23d0ba 567 static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 568 {
marcozecchini 0:9fca2b23d0ba 569 /* Example #1 */
marcozecchini 0:9fca2b23d0ba 570 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
marcozecchini 0:9fca2b23d0ba 571 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
marcozecchini 0:9fca2b23d0ba 572 },
marcozecchini 0:9fca2b23d0ba 573 {
marcozecchini 0:9fca2b23d0ba 574 /* Example #2 */
marcozecchini 0:9fca2b23d0ba 575 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
marcozecchini 0:9fca2b23d0ba 576 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
marcozecchini 0:9fca2b23d0ba 577 },
marcozecchini 0:9fca2b23d0ba 578 {
marcozecchini 0:9fca2b23d0ba 579 /* Example #3 */
marcozecchini 0:9fca2b23d0ba 580 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
marcozecchini 0:9fca2b23d0ba 581 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
marcozecchini 0:9fca2b23d0ba 582 },
marcozecchini 0:9fca2b23d0ba 583 {
marcozecchini 0:9fca2b23d0ba 584 /* Example #4 */
marcozecchini 0:9fca2b23d0ba 585 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
marcozecchini 0:9fca2b23d0ba 586 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
marcozecchini 0:9fca2b23d0ba 587 }
marcozecchini 0:9fca2b23d0ba 588 };
marcozecchini 0:9fca2b23d0ba 589
marcozecchini 0:9fca2b23d0ba 590 /* CMAC-AES256 Test Data */
marcozecchini 0:9fca2b23d0ba 591 static const unsigned char aes_256_key[32] = {
marcozecchini 0:9fca2b23d0ba 592 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
marcozecchini 0:9fca2b23d0ba 593 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
marcozecchini 0:9fca2b23d0ba 594 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
marcozecchini 0:9fca2b23d0ba 595 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
marcozecchini 0:9fca2b23d0ba 596 };
marcozecchini 0:9fca2b23d0ba 597 static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 598 {
marcozecchini 0:9fca2b23d0ba 599 /* K1 */
marcozecchini 0:9fca2b23d0ba 600 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
marcozecchini 0:9fca2b23d0ba 601 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
marcozecchini 0:9fca2b23d0ba 602 },
marcozecchini 0:9fca2b23d0ba 603 {
marcozecchini 0:9fca2b23d0ba 604 /* K2 */
marcozecchini 0:9fca2b23d0ba 605 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
marcozecchini 0:9fca2b23d0ba 606 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
marcozecchini 0:9fca2b23d0ba 607 }
marcozecchini 0:9fca2b23d0ba 608 };
marcozecchini 0:9fca2b23d0ba 609 static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 610 {
marcozecchini 0:9fca2b23d0ba 611 /* Example #1 */
marcozecchini 0:9fca2b23d0ba 612 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
marcozecchini 0:9fca2b23d0ba 613 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
marcozecchini 0:9fca2b23d0ba 614 },
marcozecchini 0:9fca2b23d0ba 615 {
marcozecchini 0:9fca2b23d0ba 616 /* Example #2 */
marcozecchini 0:9fca2b23d0ba 617 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
marcozecchini 0:9fca2b23d0ba 618 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
marcozecchini 0:9fca2b23d0ba 619 },
marcozecchini 0:9fca2b23d0ba 620 {
marcozecchini 0:9fca2b23d0ba 621 /* Example #3 */
marcozecchini 0:9fca2b23d0ba 622 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
marcozecchini 0:9fca2b23d0ba 623 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
marcozecchini 0:9fca2b23d0ba 624 },
marcozecchini 0:9fca2b23d0ba 625 {
marcozecchini 0:9fca2b23d0ba 626 /* Example #4 */
marcozecchini 0:9fca2b23d0ba 627 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
marcozecchini 0:9fca2b23d0ba 628 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
marcozecchini 0:9fca2b23d0ba 629 }
marcozecchini 0:9fca2b23d0ba 630 };
marcozecchini 0:9fca2b23d0ba 631 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 632
marcozecchini 0:9fca2b23d0ba 633 #if defined(MBEDTLS_DES_C)
marcozecchini 0:9fca2b23d0ba 634 /* Truncation point of message for 3DES CMAC tests */
marcozecchini 0:9fca2b23d0ba 635 static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
marcozecchini 0:9fca2b23d0ba 636 0,
marcozecchini 0:9fca2b23d0ba 637 16,
marcozecchini 0:9fca2b23d0ba 638 20,
marcozecchini 0:9fca2b23d0ba 639 32
marcozecchini 0:9fca2b23d0ba 640 };
marcozecchini 0:9fca2b23d0ba 641
marcozecchini 0:9fca2b23d0ba 642 /* CMAC-TDES (Generation) - 2 Key Test Data */
marcozecchini 0:9fca2b23d0ba 643 static const unsigned char des3_2key_key[24] = {
marcozecchini 0:9fca2b23d0ba 644 /* Key1 */
marcozecchini 0:9fca2b23d0ba 645 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
marcozecchini 0:9fca2b23d0ba 646 /* Key2 */
marcozecchini 0:9fca2b23d0ba 647 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
marcozecchini 0:9fca2b23d0ba 648 /* Key3 */
marcozecchini 0:9fca2b23d0ba 649 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
marcozecchini 0:9fca2b23d0ba 650 };
marcozecchini 0:9fca2b23d0ba 651 static const unsigned char des3_2key_subkeys[2][8] = {
marcozecchini 0:9fca2b23d0ba 652 {
marcozecchini 0:9fca2b23d0ba 653 /* K1 */
marcozecchini 0:9fca2b23d0ba 654 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
marcozecchini 0:9fca2b23d0ba 655 },
marcozecchini 0:9fca2b23d0ba 656 {
marcozecchini 0:9fca2b23d0ba 657 /* K2 */
marcozecchini 0:9fca2b23d0ba 658 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
marcozecchini 0:9fca2b23d0ba 659 }
marcozecchini 0:9fca2b23d0ba 660 };
marcozecchini 0:9fca2b23d0ba 661 static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 662 {
marcozecchini 0:9fca2b23d0ba 663 /* Sample #1 */
marcozecchini 0:9fca2b23d0ba 664 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
marcozecchini 0:9fca2b23d0ba 665 },
marcozecchini 0:9fca2b23d0ba 666 {
marcozecchini 0:9fca2b23d0ba 667 /* Sample #2 */
marcozecchini 0:9fca2b23d0ba 668 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
marcozecchini 0:9fca2b23d0ba 669 },
marcozecchini 0:9fca2b23d0ba 670 {
marcozecchini 0:9fca2b23d0ba 671 /* Sample #3 */
marcozecchini 0:9fca2b23d0ba 672 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
marcozecchini 0:9fca2b23d0ba 673 },
marcozecchini 0:9fca2b23d0ba 674 {
marcozecchini 0:9fca2b23d0ba 675 /* Sample #4 */
marcozecchini 0:9fca2b23d0ba 676 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
marcozecchini 0:9fca2b23d0ba 677 }
marcozecchini 0:9fca2b23d0ba 678 };
marcozecchini 0:9fca2b23d0ba 679
marcozecchini 0:9fca2b23d0ba 680 /* CMAC-TDES (Generation) - 3 Key Test Data */
marcozecchini 0:9fca2b23d0ba 681 static const unsigned char des3_3key_key[24] = {
marcozecchini 0:9fca2b23d0ba 682 /* Key1 */
marcozecchini 0:9fca2b23d0ba 683 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
marcozecchini 0:9fca2b23d0ba 684 /* Key2 */
marcozecchini 0:9fca2b23d0ba 685 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
marcozecchini 0:9fca2b23d0ba 686 /* Key3 */
marcozecchini 0:9fca2b23d0ba 687 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
marcozecchini 0:9fca2b23d0ba 688 };
marcozecchini 0:9fca2b23d0ba 689 static const unsigned char des3_3key_subkeys[2][8] = {
marcozecchini 0:9fca2b23d0ba 690 {
marcozecchini 0:9fca2b23d0ba 691 /* K1 */
marcozecchini 0:9fca2b23d0ba 692 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
marcozecchini 0:9fca2b23d0ba 693 },
marcozecchini 0:9fca2b23d0ba 694 {
marcozecchini 0:9fca2b23d0ba 695 /* K2 */
marcozecchini 0:9fca2b23d0ba 696 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
marcozecchini 0:9fca2b23d0ba 697 }
marcozecchini 0:9fca2b23d0ba 698 };
marcozecchini 0:9fca2b23d0ba 699 static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
marcozecchini 0:9fca2b23d0ba 700 {
marcozecchini 0:9fca2b23d0ba 701 /* Sample #1 */
marcozecchini 0:9fca2b23d0ba 702 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
marcozecchini 0:9fca2b23d0ba 703 },
marcozecchini 0:9fca2b23d0ba 704 {
marcozecchini 0:9fca2b23d0ba 705 /* Sample #2 */
marcozecchini 0:9fca2b23d0ba 706 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
marcozecchini 0:9fca2b23d0ba 707 },
marcozecchini 0:9fca2b23d0ba 708 {
marcozecchini 0:9fca2b23d0ba 709 /* Sample #3 */
marcozecchini 0:9fca2b23d0ba 710 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
marcozecchini 0:9fca2b23d0ba 711 },
marcozecchini 0:9fca2b23d0ba 712 {
marcozecchini 0:9fca2b23d0ba 713 /* Sample #4 */
marcozecchini 0:9fca2b23d0ba 714 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
marcozecchini 0:9fca2b23d0ba 715 }
marcozecchini 0:9fca2b23d0ba 716 };
marcozecchini 0:9fca2b23d0ba 717
marcozecchini 0:9fca2b23d0ba 718 #endif /* MBEDTLS_DES_C */
marcozecchini 0:9fca2b23d0ba 719
marcozecchini 0:9fca2b23d0ba 720 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 721 /* AES AES-CMAC-PRF-128 Test Data */
marcozecchini 0:9fca2b23d0ba 722 static const unsigned char PRFK[] = {
marcozecchini 0:9fca2b23d0ba 723 /* Key */
marcozecchini 0:9fca2b23d0ba 724 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
marcozecchini 0:9fca2b23d0ba 725 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
marcozecchini 0:9fca2b23d0ba 726 0xed, 0xcb
marcozecchini 0:9fca2b23d0ba 727 };
marcozecchini 0:9fca2b23d0ba 728
marcozecchini 0:9fca2b23d0ba 729 /* Sizes in bytes */
marcozecchini 0:9fca2b23d0ba 730 static const size_t PRFKlen[NB_PRF_TESTS] = {
marcozecchini 0:9fca2b23d0ba 731 18,
marcozecchini 0:9fca2b23d0ba 732 16,
marcozecchini 0:9fca2b23d0ba 733 10
marcozecchini 0:9fca2b23d0ba 734 };
marcozecchini 0:9fca2b23d0ba 735
marcozecchini 0:9fca2b23d0ba 736 /* Message */
marcozecchini 0:9fca2b23d0ba 737 static const unsigned char PRFM[] = {
marcozecchini 0:9fca2b23d0ba 738 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
marcozecchini 0:9fca2b23d0ba 739 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
marcozecchini 0:9fca2b23d0ba 740 0x10, 0x11, 0x12, 0x13
marcozecchini 0:9fca2b23d0ba 741 };
marcozecchini 0:9fca2b23d0ba 742
marcozecchini 0:9fca2b23d0ba 743 static const unsigned char PRFT[NB_PRF_TESTS][16] = {
marcozecchini 0:9fca2b23d0ba 744 {
marcozecchini 0:9fca2b23d0ba 745 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
marcozecchini 0:9fca2b23d0ba 746 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
marcozecchini 0:9fca2b23d0ba 747 },
marcozecchini 0:9fca2b23d0ba 748 {
marcozecchini 0:9fca2b23d0ba 749 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
marcozecchini 0:9fca2b23d0ba 750 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
marcozecchini 0:9fca2b23d0ba 751 },
marcozecchini 0:9fca2b23d0ba 752 {
marcozecchini 0:9fca2b23d0ba 753 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
marcozecchini 0:9fca2b23d0ba 754 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
marcozecchini 0:9fca2b23d0ba 755 }
marcozecchini 0:9fca2b23d0ba 756 };
marcozecchini 0:9fca2b23d0ba 757 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 758
marcozecchini 0:9fca2b23d0ba 759 static int cmac_test_subkeys( int verbose,
marcozecchini 0:9fca2b23d0ba 760 const char* testname,
marcozecchini 0:9fca2b23d0ba 761 const unsigned char* key,
marcozecchini 0:9fca2b23d0ba 762 int keybits,
marcozecchini 0:9fca2b23d0ba 763 const unsigned char* subkeys,
marcozecchini 0:9fca2b23d0ba 764 mbedtls_cipher_type_t cipher_type,
marcozecchini 0:9fca2b23d0ba 765 int block_size,
marcozecchini 0:9fca2b23d0ba 766 int num_tests )
marcozecchini 0:9fca2b23d0ba 767 {
marcozecchini 0:9fca2b23d0ba 768 int i, ret;
marcozecchini 0:9fca2b23d0ba 769 mbedtls_cipher_context_t ctx;
marcozecchini 0:9fca2b23d0ba 770 const mbedtls_cipher_info_t *cipher_info;
marcozecchini 0:9fca2b23d0ba 771 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 772 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 773
marcozecchini 0:9fca2b23d0ba 774 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
marcozecchini 0:9fca2b23d0ba 775 if( cipher_info == NULL )
marcozecchini 0:9fca2b23d0ba 776 {
marcozecchini 0:9fca2b23d0ba 777 /* Failing at this point must be due to a build issue */
marcozecchini 0:9fca2b23d0ba 778 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
marcozecchini 0:9fca2b23d0ba 779 }
marcozecchini 0:9fca2b23d0ba 780
marcozecchini 0:9fca2b23d0ba 781 for( i = 0; i < num_tests; i++ )
marcozecchini 0:9fca2b23d0ba 782 {
marcozecchini 0:9fca2b23d0ba 783 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 784 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
marcozecchini 0:9fca2b23d0ba 785
marcozecchini 0:9fca2b23d0ba 786 mbedtls_cipher_init( &ctx );
marcozecchini 0:9fca2b23d0ba 787
marcozecchini 0:9fca2b23d0ba 788 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 789 {
marcozecchini 0:9fca2b23d0ba 790 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 791 mbedtls_printf( "test execution failed\n" );
marcozecchini 0:9fca2b23d0ba 792
marcozecchini 0:9fca2b23d0ba 793 goto cleanup;
marcozecchini 0:9fca2b23d0ba 794 }
marcozecchini 0:9fca2b23d0ba 795
marcozecchini 0:9fca2b23d0ba 796 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
marcozecchini 0:9fca2b23d0ba 797 MBEDTLS_ENCRYPT ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 798 {
marcozecchini 0:9fca2b23d0ba 799 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 800 mbedtls_printf( "test execution failed\n" );
marcozecchini 0:9fca2b23d0ba 801
marcozecchini 0:9fca2b23d0ba 802 goto cleanup;
marcozecchini 0:9fca2b23d0ba 803 }
marcozecchini 0:9fca2b23d0ba 804
marcozecchini 0:9fca2b23d0ba 805 ret = cmac_generate_subkeys( &ctx, K1, K2 );
marcozecchini 0:9fca2b23d0ba 806 if( ret != 0 )
marcozecchini 0:9fca2b23d0ba 807 {
marcozecchini 0:9fca2b23d0ba 808 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 809 mbedtls_printf( "failed\n" );
marcozecchini 0:9fca2b23d0ba 810
marcozecchini 0:9fca2b23d0ba 811 goto cleanup;
marcozecchini 0:9fca2b23d0ba 812 }
marcozecchini 0:9fca2b23d0ba 813
marcozecchini 0:9fca2b23d0ba 814 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
marcozecchini 0:9fca2b23d0ba 815 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 816 {
marcozecchini 0:9fca2b23d0ba 817 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 818 mbedtls_printf( "failed\n" );
marcozecchini 0:9fca2b23d0ba 819
marcozecchini 0:9fca2b23d0ba 820 goto cleanup;
marcozecchini 0:9fca2b23d0ba 821 }
marcozecchini 0:9fca2b23d0ba 822
marcozecchini 0:9fca2b23d0ba 823 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 824 mbedtls_printf( "passed\n" );
marcozecchini 0:9fca2b23d0ba 825
marcozecchini 0:9fca2b23d0ba 826 mbedtls_cipher_free( &ctx );
marcozecchini 0:9fca2b23d0ba 827 }
marcozecchini 0:9fca2b23d0ba 828
marcozecchini 0:9fca2b23d0ba 829 goto exit;
marcozecchini 0:9fca2b23d0ba 830
marcozecchini 0:9fca2b23d0ba 831 cleanup:
marcozecchini 0:9fca2b23d0ba 832 mbedtls_cipher_free( &ctx );
marcozecchini 0:9fca2b23d0ba 833
marcozecchini 0:9fca2b23d0ba 834 exit:
marcozecchini 0:9fca2b23d0ba 835 return( ret );
marcozecchini 0:9fca2b23d0ba 836 }
marcozecchini 0:9fca2b23d0ba 837
marcozecchini 0:9fca2b23d0ba 838 static int cmac_test_wth_cipher( int verbose,
marcozecchini 0:9fca2b23d0ba 839 const char* testname,
marcozecchini 0:9fca2b23d0ba 840 const unsigned char* key,
marcozecchini 0:9fca2b23d0ba 841 int keybits,
marcozecchini 0:9fca2b23d0ba 842 const unsigned char* messages,
marcozecchini 0:9fca2b23d0ba 843 const unsigned int message_lengths[4],
marcozecchini 0:9fca2b23d0ba 844 const unsigned char* expected_result,
marcozecchini 0:9fca2b23d0ba 845 mbedtls_cipher_type_t cipher_type,
marcozecchini 0:9fca2b23d0ba 846 int block_size,
marcozecchini 0:9fca2b23d0ba 847 int num_tests )
marcozecchini 0:9fca2b23d0ba 848 {
marcozecchini 0:9fca2b23d0ba 849 const mbedtls_cipher_info_t *cipher_info;
marcozecchini 0:9fca2b23d0ba 850 int i, ret;
marcozecchini 0:9fca2b23d0ba 851 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
marcozecchini 0:9fca2b23d0ba 852
marcozecchini 0:9fca2b23d0ba 853 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
marcozecchini 0:9fca2b23d0ba 854 if( cipher_info == NULL )
marcozecchini 0:9fca2b23d0ba 855 {
marcozecchini 0:9fca2b23d0ba 856 /* Failing at this point must be due to a build issue */
marcozecchini 0:9fca2b23d0ba 857 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
marcozecchini 0:9fca2b23d0ba 858 goto exit;
marcozecchini 0:9fca2b23d0ba 859 }
marcozecchini 0:9fca2b23d0ba 860
marcozecchini 0:9fca2b23d0ba 861 for( i = 0; i < num_tests; i++ )
marcozecchini 0:9fca2b23d0ba 862 {
marcozecchini 0:9fca2b23d0ba 863 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 864 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
marcozecchini 0:9fca2b23d0ba 865
marcozecchini 0:9fca2b23d0ba 866 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
marcozecchini 0:9fca2b23d0ba 867 message_lengths[i], output ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 868 {
marcozecchini 0:9fca2b23d0ba 869 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 870 mbedtls_printf( "failed\n" );
marcozecchini 0:9fca2b23d0ba 871 goto exit;
marcozecchini 0:9fca2b23d0ba 872 }
marcozecchini 0:9fca2b23d0ba 873
marcozecchini 0:9fca2b23d0ba 874 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 875 {
marcozecchini 0:9fca2b23d0ba 876 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 877 mbedtls_printf( "failed\n" );
marcozecchini 0:9fca2b23d0ba 878 goto exit;
marcozecchini 0:9fca2b23d0ba 879 }
marcozecchini 0:9fca2b23d0ba 880
marcozecchini 0:9fca2b23d0ba 881 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 882 mbedtls_printf( "passed\n" );
marcozecchini 0:9fca2b23d0ba 883 }
marcozecchini 0:9fca2b23d0ba 884
marcozecchini 0:9fca2b23d0ba 885 exit:
marcozecchini 0:9fca2b23d0ba 886 return( ret );
marcozecchini 0:9fca2b23d0ba 887 }
marcozecchini 0:9fca2b23d0ba 888
marcozecchini 0:9fca2b23d0ba 889 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 890 static int test_aes128_cmac_prf( int verbose )
marcozecchini 0:9fca2b23d0ba 891 {
marcozecchini 0:9fca2b23d0ba 892 int i;
marcozecchini 0:9fca2b23d0ba 893 int ret;
marcozecchini 0:9fca2b23d0ba 894 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
marcozecchini 0:9fca2b23d0ba 895
marcozecchini 0:9fca2b23d0ba 896 for( i = 0; i < NB_PRF_TESTS; i++ )
marcozecchini 0:9fca2b23d0ba 897 {
marcozecchini 0:9fca2b23d0ba 898 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
marcozecchini 0:9fca2b23d0ba 899 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
marcozecchini 0:9fca2b23d0ba 900 if( ret != 0 ||
marcozecchini 0:9fca2b23d0ba 901 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
marcozecchini 0:9fca2b23d0ba 902 {
marcozecchini 0:9fca2b23d0ba 903
marcozecchini 0:9fca2b23d0ba 904 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 905 mbedtls_printf( "failed\n" );
marcozecchini 0:9fca2b23d0ba 906
marcozecchini 0:9fca2b23d0ba 907 return( ret );
marcozecchini 0:9fca2b23d0ba 908 }
marcozecchini 0:9fca2b23d0ba 909 else if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 910 {
marcozecchini 0:9fca2b23d0ba 911 mbedtls_printf( "passed\n" );
marcozecchini 0:9fca2b23d0ba 912 }
marcozecchini 0:9fca2b23d0ba 913 }
marcozecchini 0:9fca2b23d0ba 914 return( ret );
marcozecchini 0:9fca2b23d0ba 915 }
marcozecchini 0:9fca2b23d0ba 916 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 917
marcozecchini 0:9fca2b23d0ba 918 int mbedtls_cmac_self_test( int verbose )
marcozecchini 0:9fca2b23d0ba 919 {
marcozecchini 0:9fca2b23d0ba 920 int ret;
marcozecchini 0:9fca2b23d0ba 921
marcozecchini 0:9fca2b23d0ba 922 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 923 /* AES-128 */
marcozecchini 0:9fca2b23d0ba 924 if( ( ret = cmac_test_subkeys( verbose,
marcozecchini 0:9fca2b23d0ba 925 "AES 128",
marcozecchini 0:9fca2b23d0ba 926 aes_128_key,
marcozecchini 0:9fca2b23d0ba 927 128,
marcozecchini 0:9fca2b23d0ba 928 (const unsigned char*)aes_128_subkeys,
marcozecchini 0:9fca2b23d0ba 929 MBEDTLS_CIPHER_AES_128_ECB,
marcozecchini 0:9fca2b23d0ba 930 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 931 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 932 {
marcozecchini 0:9fca2b23d0ba 933 return( ret );
marcozecchini 0:9fca2b23d0ba 934 }
marcozecchini 0:9fca2b23d0ba 935
marcozecchini 0:9fca2b23d0ba 936 if( ( ret = cmac_test_wth_cipher( verbose,
marcozecchini 0:9fca2b23d0ba 937 "AES 128",
marcozecchini 0:9fca2b23d0ba 938 aes_128_key,
marcozecchini 0:9fca2b23d0ba 939 128,
marcozecchini 0:9fca2b23d0ba 940 test_message,
marcozecchini 0:9fca2b23d0ba 941 aes_message_lengths,
marcozecchini 0:9fca2b23d0ba 942 (const unsigned char*)aes_128_expected_result,
marcozecchini 0:9fca2b23d0ba 943 MBEDTLS_CIPHER_AES_128_ECB,
marcozecchini 0:9fca2b23d0ba 944 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 945 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 946 {
marcozecchini 0:9fca2b23d0ba 947 return( ret );
marcozecchini 0:9fca2b23d0ba 948 }
marcozecchini 0:9fca2b23d0ba 949
marcozecchini 0:9fca2b23d0ba 950 /* AES-192 */
marcozecchini 0:9fca2b23d0ba 951 if( ( ret = cmac_test_subkeys( verbose,
marcozecchini 0:9fca2b23d0ba 952 "AES 192",
marcozecchini 0:9fca2b23d0ba 953 aes_192_key,
marcozecchini 0:9fca2b23d0ba 954 192,
marcozecchini 0:9fca2b23d0ba 955 (const unsigned char*)aes_192_subkeys,
marcozecchini 0:9fca2b23d0ba 956 MBEDTLS_CIPHER_AES_192_ECB,
marcozecchini 0:9fca2b23d0ba 957 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 958 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 959 {
marcozecchini 0:9fca2b23d0ba 960 return( ret );
marcozecchini 0:9fca2b23d0ba 961 }
marcozecchini 0:9fca2b23d0ba 962
marcozecchini 0:9fca2b23d0ba 963 if( ( ret = cmac_test_wth_cipher( verbose,
marcozecchini 0:9fca2b23d0ba 964 "AES 192",
marcozecchini 0:9fca2b23d0ba 965 aes_192_key,
marcozecchini 0:9fca2b23d0ba 966 192,
marcozecchini 0:9fca2b23d0ba 967 test_message,
marcozecchini 0:9fca2b23d0ba 968 aes_message_lengths,
marcozecchini 0:9fca2b23d0ba 969 (const unsigned char*)aes_192_expected_result,
marcozecchini 0:9fca2b23d0ba 970 MBEDTLS_CIPHER_AES_192_ECB,
marcozecchini 0:9fca2b23d0ba 971 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 972 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 973 {
marcozecchini 0:9fca2b23d0ba 974 return( ret );
marcozecchini 0:9fca2b23d0ba 975 }
marcozecchini 0:9fca2b23d0ba 976
marcozecchini 0:9fca2b23d0ba 977 /* AES-256 */
marcozecchini 0:9fca2b23d0ba 978 if( ( ret = cmac_test_subkeys( verbose,
marcozecchini 0:9fca2b23d0ba 979 "AES 256",
marcozecchini 0:9fca2b23d0ba 980 aes_256_key,
marcozecchini 0:9fca2b23d0ba 981 256,
marcozecchini 0:9fca2b23d0ba 982 (const unsigned char*)aes_256_subkeys,
marcozecchini 0:9fca2b23d0ba 983 MBEDTLS_CIPHER_AES_256_ECB,
marcozecchini 0:9fca2b23d0ba 984 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 985 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 986 {
marcozecchini 0:9fca2b23d0ba 987 return( ret );
marcozecchini 0:9fca2b23d0ba 988 }
marcozecchini 0:9fca2b23d0ba 989
marcozecchini 0:9fca2b23d0ba 990 if( ( ret = cmac_test_wth_cipher ( verbose,
marcozecchini 0:9fca2b23d0ba 991 "AES 256",
marcozecchini 0:9fca2b23d0ba 992 aes_256_key,
marcozecchini 0:9fca2b23d0ba 993 256,
marcozecchini 0:9fca2b23d0ba 994 test_message,
marcozecchini 0:9fca2b23d0ba 995 aes_message_lengths,
marcozecchini 0:9fca2b23d0ba 996 (const unsigned char*)aes_256_expected_result,
marcozecchini 0:9fca2b23d0ba 997 MBEDTLS_CIPHER_AES_256_ECB,
marcozecchini 0:9fca2b23d0ba 998 MBEDTLS_AES_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 999 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1000 {
marcozecchini 0:9fca2b23d0ba 1001 return( ret );
marcozecchini 0:9fca2b23d0ba 1002 }
marcozecchini 0:9fca2b23d0ba 1003 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 1004
marcozecchini 0:9fca2b23d0ba 1005 #if defined(MBEDTLS_DES_C)
marcozecchini 0:9fca2b23d0ba 1006 /* 3DES 2 key */
marcozecchini 0:9fca2b23d0ba 1007 if( ( ret = cmac_test_subkeys( verbose,
marcozecchini 0:9fca2b23d0ba 1008 "3DES 2 key",
marcozecchini 0:9fca2b23d0ba 1009 des3_2key_key,
marcozecchini 0:9fca2b23d0ba 1010 192,
marcozecchini 0:9fca2b23d0ba 1011 (const unsigned char*)des3_2key_subkeys,
marcozecchini 0:9fca2b23d0ba 1012 MBEDTLS_CIPHER_DES_EDE3_ECB,
marcozecchini 0:9fca2b23d0ba 1013 MBEDTLS_DES3_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 1014 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1015 {
marcozecchini 0:9fca2b23d0ba 1016 return( ret );
marcozecchini 0:9fca2b23d0ba 1017 }
marcozecchini 0:9fca2b23d0ba 1018
marcozecchini 0:9fca2b23d0ba 1019 if( ( ret = cmac_test_wth_cipher( verbose,
marcozecchini 0:9fca2b23d0ba 1020 "3DES 2 key",
marcozecchini 0:9fca2b23d0ba 1021 des3_2key_key,
marcozecchini 0:9fca2b23d0ba 1022 192,
marcozecchini 0:9fca2b23d0ba 1023 test_message,
marcozecchini 0:9fca2b23d0ba 1024 des3_message_lengths,
marcozecchini 0:9fca2b23d0ba 1025 (const unsigned char*)des3_2key_expected_result,
marcozecchini 0:9fca2b23d0ba 1026 MBEDTLS_CIPHER_DES_EDE3_ECB,
marcozecchini 0:9fca2b23d0ba 1027 MBEDTLS_DES3_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 1028 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1029 {
marcozecchini 0:9fca2b23d0ba 1030 return( ret );
marcozecchini 0:9fca2b23d0ba 1031 }
marcozecchini 0:9fca2b23d0ba 1032
marcozecchini 0:9fca2b23d0ba 1033 /* 3DES 3 key */
marcozecchini 0:9fca2b23d0ba 1034 if( ( ret = cmac_test_subkeys( verbose,
marcozecchini 0:9fca2b23d0ba 1035 "3DES 3 key",
marcozecchini 0:9fca2b23d0ba 1036 des3_3key_key,
marcozecchini 0:9fca2b23d0ba 1037 192,
marcozecchini 0:9fca2b23d0ba 1038 (const unsigned char*)des3_3key_subkeys,
marcozecchini 0:9fca2b23d0ba 1039 MBEDTLS_CIPHER_DES_EDE3_ECB,
marcozecchini 0:9fca2b23d0ba 1040 MBEDTLS_DES3_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 1041 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1042 {
marcozecchini 0:9fca2b23d0ba 1043 return( ret );
marcozecchini 0:9fca2b23d0ba 1044 }
marcozecchini 0:9fca2b23d0ba 1045
marcozecchini 0:9fca2b23d0ba 1046 if( ( ret = cmac_test_wth_cipher( verbose,
marcozecchini 0:9fca2b23d0ba 1047 "3DES 3 key",
marcozecchini 0:9fca2b23d0ba 1048 des3_3key_key,
marcozecchini 0:9fca2b23d0ba 1049 192,
marcozecchini 0:9fca2b23d0ba 1050 test_message,
marcozecchini 0:9fca2b23d0ba 1051 des3_message_lengths,
marcozecchini 0:9fca2b23d0ba 1052 (const unsigned char*)des3_3key_expected_result,
marcozecchini 0:9fca2b23d0ba 1053 MBEDTLS_CIPHER_DES_EDE3_ECB,
marcozecchini 0:9fca2b23d0ba 1054 MBEDTLS_DES3_BLOCK_SIZE,
marcozecchini 0:9fca2b23d0ba 1055 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1056 {
marcozecchini 0:9fca2b23d0ba 1057 return( ret );
marcozecchini 0:9fca2b23d0ba 1058 }
marcozecchini 0:9fca2b23d0ba 1059 #endif /* MBEDTLS_DES_C */
marcozecchini 0:9fca2b23d0ba 1060
marcozecchini 0:9fca2b23d0ba 1061 #if defined(MBEDTLS_AES_C)
marcozecchini 0:9fca2b23d0ba 1062 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
marcozecchini 0:9fca2b23d0ba 1063 return( ret );
marcozecchini 0:9fca2b23d0ba 1064 #endif /* MBEDTLS_AES_C */
marcozecchini 0:9fca2b23d0ba 1065
marcozecchini 0:9fca2b23d0ba 1066 if( verbose != 0 )
marcozecchini 0:9fca2b23d0ba 1067 mbedtls_printf( "\n" );
marcozecchini 0:9fca2b23d0ba 1068
marcozecchini 0:9fca2b23d0ba 1069 return( 0 );
marcozecchini 0:9fca2b23d0ba 1070 }
marcozecchini 0:9fca2b23d0ba 1071
marcozecchini 0:9fca2b23d0ba 1072 #endif /* MBEDTLS_SELF_TEST */
marcozecchini 0:9fca2b23d0ba 1073
marcozecchini 0:9fca2b23d0ba 1074 #endif /* MBEDTLS_CMAC_C */