mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

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