1 /* cmac_mode.h -- interface to a CMAC implementation */ 2 3 /* 4 * Copyright (C) 2017 by Intel Corporation, All Rights Reserved 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Intel Corporation nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /** 34 * @file 35 * @brief Interface to a CMAC implementation. 36 * 37 * Overview: CMAC is defined NIST in SP 800-38B, and is the standard algorithm 38 * for computing a MAC using a block cipher. It can compute the MAC 39 * for a byte string of any length. It is distinguished from CBC-MAC 40 * in the processing of the final message block; CMAC uses a 41 * different technique to compute the final message block is full 42 * size or only partial, while CBC-MAC uses the same technique for 43 * both. This difference permits CMAC to be applied to variable 44 * length messages, while all messages authenticated by CBC-MAC must 45 * be the same length. 46 * 47 * Security: AES128-CMAC mode of operation offers 64 bits of security against 48 * collision attacks. Note however that an external attacker cannot 49 * generate the tags him/herself without knowing the MAC key. In this 50 * sense, to attack the collision property of AES128-CMAC, an 51 * external attacker would need the cooperation of the legal user to 52 * produce an exponentially high number of tags (e.g. 2^64) to 53 * finally be able to look for collisions and benefit from them. As 54 * an extra precaution, the current implementation allows to at most 55 * 2^48 calls to the tc_cmac_update function before re-calling 56 * tc_cmac_setup (allowing a new key to be set), as suggested in 57 * Appendix B of SP 800-38B. 58 * 59 * Requires: AES-128 60 * 61 * Usage: This implementation provides a "scatter-gather" interface, so that 62 * the CMAC value can be computed incrementally over a message 63 * scattered in different segments throughout memory. Experience shows 64 * this style of interface tends to minimize the burden of programming 65 * correctly. Like all symmetric key operations, it is session 66 * oriented. 67 * 68 * To begin a CMAC session, use tc_cmac_setup to initialize a struct 69 * tc_cmac_struct with encryption key and buffer. Our implementation 70 * always assume that the AES key to be the same size as the block 71 * cipher block size. Once setup, this data structure can be used for 72 * many CMAC computations. 73 * 74 * Once the state has been setup with a key, computing the CMAC of 75 * some data requires three steps: 76 * 77 * (1) first use tc_cmac_init to initialize a new CMAC computation. 78 * (2) next mix all of the data into the CMAC computation state using 79 * tc_cmac_update. If all of the data resides in a single data 80 * segment then only one tc_cmac_update call is needed; if data 81 * is scattered throughout memory in n data segments, then n calls 82 * will be needed. CMAC IS ORDER SENSITIVE, to be able to detect 83 * attacks that swap bytes, so the order in which data is mixed 84 * into the state is critical! 85 * (3) Once all of the data for a message has been mixed, use 86 * tc_cmac_final to compute the CMAC tag value. 87 * 88 * Steps (1)-(3) can be repeated as many times as you want to CMAC 89 * multiple messages. A practical limit is 2^48 1K messages before you 90 * have to change the key. 91 * 92 * Once you are done computing CMAC with a key, it is a good idea to 93 * destroy the state so an attacker cannot recover the key; use 94 * tc_cmac_erase to accomplish this. 95 */ 96 97 #ifndef __TC_CMAC_MODE_H__ 98 #define __TC_CMAC_MODE_H__ 99 100 #include <tinycrypt/aes.h> 101 102 #include <stddef.h> 103 104 #ifdef __cplusplus 105 extern "C" { 106 #endif 107 108 /* padding for last message block */ 109 #define TC_CMAC_PADDING 0x80 110 111 /* struct tc_cmac_struct represents the state of a CMAC computation */ 112 typedef struct tc_cmac_struct { 113 /* initialization vector */ 114 uint8_t iv[TC_AES_BLOCK_SIZE]; 115 /* used if message length is a multiple of block_size bytes */ 116 uint8_t K1[TC_AES_BLOCK_SIZE]; 117 /* used if message length isn't a multiple block_size bytes */ 118 uint8_t K2[TC_AES_BLOCK_SIZE]; 119 /* where to put bytes that didn't fill a block */ 120 uint8_t leftover[TC_AES_BLOCK_SIZE]; 121 /* identifies the encryption key */ 122 unsigned int keyid; 123 /* next available leftover location */ 124 unsigned int leftover_offset; 125 /* AES key schedule */ 126 TCAesKeySched_t sched; 127 /* calls to tc_cmac_update left before re-key */ 128 uint64_t countdown; 129 } *TCCmacState_t; 130 131 /** 132 * @brief Configures the CMAC state to use the given AES key 133 * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state 134 * returns TC_CRYPTO_FAIL (0) if: 135 * s == NULL or 136 * key == NULL 137 * 138 * @param s IN/OUT -- the state to set up 139 * @param key IN -- the key to use 140 * @param sched IN -- AES key schedule 141 */ 142 int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, 143 TCAesKeySched_t sched); 144 145 /** 146 * @brief Erases the CMAC state 147 * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state 148 * returns TC_CRYPTO_FAIL (0) if: 149 * s == NULL 150 * 151 * @param s IN/OUT -- the state to erase 152 */ 153 int tc_cmac_erase(TCCmacState_t s); 154 155 /** 156 * @brief Initializes a new CMAC computation 157 * @return returns TC_CRYPTO_SUCCESS (1) after having initialized the CMAC state 158 * returns TC_CRYPTO_FAIL (0) if: 159 * s == NULL 160 * 161 * @param s IN/OUT -- the state to initialize 162 */ 163 int tc_cmac_init(TCCmacState_t s); 164 165 /** 166 * @brief Incrementally computes CMAC over the next data segment 167 * @return returns TC_CRYPTO_SUCCESS (1) after successfully updating the CMAC state 168 * returns TC_CRYPTO_FAIL (0) if: 169 * s == NULL or 170 * if data == NULL when dlen > 0 171 * 172 * @param s IN/OUT -- the CMAC state 173 * @param data IN -- the next data segment to MAC 174 * @param dlen IN -- the length of data in bytes 175 */ 176 int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t dlen); 177 178 /** 179 * @brief Generates the tag from the CMAC state 180 * @return returns TC_CRYPTO_SUCCESS (1) after successfully generating the tag 181 * returns TC_CRYPTO_FAIL (0) if: 182 * tag == NULL or 183 * s == NULL 184 * 185 * @param tag OUT -- the CMAC tag 186 * @param s IN -- CMAC state 187 */ 188 int tc_cmac_final(uint8_t *tag, TCCmacState_t s); 189 190 #ifdef __cplusplus 191 } 192 #endif 193 194 #endif /* __TC_CMAC_MODE_H__ */ 195