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