1 /* ccm_mode.h - TinyCrypt interface to a CCM mode 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 CCM mode implementation. 36 * 37 * Overview: CCM (for "Counter with CBC-MAC") mode is a NIST approved mode of 38 * operation defined in SP 800-38C. 39 * 40 * TinyCrypt CCM implementation accepts: 41 * 42 * 1) Both non-empty payload and associated data (it encrypts and 43 * authenticates the payload and also authenticates the associated 44 * data); 45 * 2) Non-empty payload and empty associated data (it encrypts and 46 * authenticates the payload); 47 * 3) Non-empty associated data and empty payload (it degenerates to 48 * an authentication mode on the associated data). 49 * 50 * TinyCrypt CCM implementation accepts associated data of any length 51 * between 0 and (2^16 - 2^8) bytes. 52 * 53 * Security: The mac length parameter is an important parameter to estimate the 54 * security against collision attacks (that aim at finding different 55 * messages that produce the same authentication tag). TinyCrypt CCM 56 * implementation accepts any even integer between 4 and 16, as 57 * suggested in SP 800-38C. 58 * 59 * RFC-3610, which also specifies CCM, presents a few relevant 60 * security suggestions, such as: it is recommended for most 61 * applications to use a mac length greater than 8. Besides, the 62 * usage of the same nonce for two different messages which are 63 * encrypted with the same key destroys the security of CCM mode. 64 * 65 * Requires: AES-128 66 * 67 * Usage: 1) call tc_ccm_config to configure. 68 * 69 * 2) call tc_ccm_mode_encrypt to encrypt data and generate tag. 70 * 71 * 3) call tc_ccm_mode_decrypt to decrypt data and verify tag. 72 */ 73 74 #ifndef __TC_CCM_MODE_H__ 75 #define __TC_CCM_MODE_H__ 76 77 #include <tinycrypt/aes.h> 78 #include <stddef.h> 79 80 #ifdef __cplusplus 81 extern "C" { 82 #endif 83 84 /* max additional authenticated size in bytes: 2^16 - 2^8 = 65280 */ 85 #define TC_CCM_AAD_MAX_BYTES 0xff00 86 87 /* max message size in bytes: 2^(8L) = 2^16 = 65536 */ 88 #define TC_CCM_PAYLOAD_MAX_BYTES 0x10000 89 90 /* struct tc_ccm_mode_struct represents the state of a CCM computation */ 91 typedef struct tc_ccm_mode_struct { 92 TCAesKeySched_t sched; /* AES key schedule */ 93 uint8_t *nonce; /* nonce required by CCM */ 94 unsigned int mlen; /* mac length in bytes (parameter t in SP-800 38C) */ 95 } *TCCcmMode_t; 96 97 /** 98 * @brief CCM configuration procedure 99 * @return returns TC_CRYPTO_SUCCESS (1) 100 * returns TC_CRYPTO_FAIL (0) if: 101 * c == NULL or 102 * sched == NULL or 103 * nonce == NULL or 104 * mlen != {4, 6, 8, 10, 12, 16} 105 * @param c -- CCM state 106 * @param sched IN -- AES key schedule 107 * @param nonce IN - nonce 108 * @param nlen -- nonce length in bytes 109 * @param mlen -- mac length in bytes (parameter t in SP-800 38C) 110 */ 111 int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, 112 unsigned int nlen, unsigned int mlen); 113 114 /** 115 * @brief CCM tag generation and encryption procedure 116 * @return returns TC_CRYPTO_SUCCESS (1) 117 * returns TC_CRYPTO_FAIL (0) if: 118 * out == NULL or 119 * c == NULL or 120 * ((plen > 0) and (payload == NULL)) or 121 * ((alen > 0) and (associated_data == NULL)) or 122 * (alen >= TC_CCM_AAD_MAX_BYTES) or 123 * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or 124 * (olen < plen + maclength) 125 * 126 * @param out OUT -- encrypted data 127 * @param olen IN -- output length in bytes 128 * @param associated_data IN -- associated data 129 * @param alen IN -- associated data length in bytes 130 * @param payload IN -- payload 131 * @param plen IN -- payload length in bytes 132 * @param c IN -- CCM state 133 * 134 * @note: out buffer should be at least (plen + c->mlen) bytes long. 135 * 136 * @note: The sequence b for encryption is formatted as follows: 137 * b = [FLAGS | nonce | counter ], where: 138 * FLAGS is 1 byte long 139 * nonce is 13 bytes long 140 * counter is 2 bytes long 141 * The byte FLAGS is composed by the following 8 bits: 142 * 0-2 bits: used to represent the value of q-1 143 * 3-7 btis: always 0's 144 * 145 * @note: The sequence b for authentication is formatted as follows: 146 * b = [FLAGS | nonce | length(mac length)], where: 147 * FLAGS is 1 byte long 148 * nonce is 13 bytes long 149 * length(mac length) is 2 bytes long 150 * The byte FLAGS is composed by the following 8 bits: 151 * 0-2 bits: used to represent the value of q-1 152 * 3-5 bits: mac length (encoded as: (mlen-2)/2) 153 * 6: Adata (0 if alen == 0, and 1 otherwise) 154 * 7: always 0 155 */ 156 int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen, 157 const uint8_t *associated_data, 158 unsigned int alen, const uint8_t *payload, 159 unsigned int plen, TCCcmMode_t c); 160 161 /** 162 * @brief CCM decryption and tag verification procedure 163 * @return returns TC_CRYPTO_SUCCESS (1) 164 * returns TC_CRYPTO_FAIL (0) if: 165 * out == NULL or 166 * c == NULL or 167 * ((plen > 0) and (payload == NULL)) or 168 * ((alen > 0) and (associated_data == NULL)) or 169 * (alen >= TC_CCM_AAD_MAX_BYTES) or 170 * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or 171 * (olen < plen - c->mlen) 172 * 173 * @param out OUT -- decrypted data 174 * @param associated_data IN -- associated data 175 * @param alen IN -- associated data length in bytes 176 * @param payload IN -- payload 177 * @param plen IN -- payload length in bytes 178 * @param c IN -- CCM state 179 * 180 * @note: out buffer should be at least (plen - c->mlen) bytes long. 181 * 182 * @note: The sequence b for encryption is formatted as follows: 183 * b = [FLAGS | nonce | counter ], where: 184 * FLAGS is 1 byte long 185 * nonce is 13 bytes long 186 * counter is 2 bytes long 187 * The byte FLAGS is composed by the following 8 bits: 188 * 0-2 bits: used to represent the value of q-1 189 * 3-7 btis: always 0's 190 * 191 * @note: The sequence b for authentication is formatted as follows: 192 * b = [FLAGS | nonce | length(mac length)], where: 193 * FLAGS is 1 byte long 194 * nonce is 13 bytes long 195 * length(mac length) is 2 bytes long 196 * The byte FLAGS is composed by the following 8 bits: 197 * 0-2 bits: used to represent the value of q-1 198 * 3-5 bits: mac length (encoded as: (mlen-2)/2) 199 * 6: Adata (0 if alen == 0, and 1 otherwise) 200 * 7: always 0 201 */ 202 int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen, 203 const uint8_t *associated_data, 204 unsigned int alen, const uint8_t *payload, unsigned int plen, 205 TCCcmMode_t c); 206 207 #ifdef __cplusplus 208 } 209 #endif 210 211 #endif /* __TC_CCM_MODE_H__ */ 212