mbed TLS Build

Dependents:   Encrypt_Decrypt1 mbed_blink_tls encrypt encrypt

Committer:
markrad
Date:
Thu Jan 05 00:18:44 2017 +0000
Revision:
0:cdf462088d13
Initial commit

Who changed what in which revision?

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