RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

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