takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

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