summaryrefslogtreecommitdiff
path: root/src/libs/mynewt-nimble/ext/tinycrypt/include/tinycrypt/ccm_mode.h
blob: 69c798e2f5ac9de6e44ab2e3816bdee5c8681de3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* ccm_mode.h - TinyCrypt interface to a CCM mode implementation */

/*
 *  Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *    - Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *
 *    - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 *    - Neither the name of Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * @brief Interface to a CCM mode implementation.
 *
 *  Overview: CCM (for "Counter with CBC-MAC") mode is a NIST approved mode of
 *            operation defined in SP 800-38C.
 *
 *            TinyCrypt CCM implementation accepts:
 *
 *            1) Both non-empty payload and associated data (it encrypts and
 *            authenticates the payload and also authenticates the associated
 *            data);
 *            2) Non-empty payload and empty associated data (it encrypts and
 *            authenticates the payload);
 *            3) Non-empty associated data and empty payload (it degenerates to
 *            an authentication mode on the associated data).
 *
 *            TinyCrypt CCM implementation accepts associated data of any length
 *            between 0 and (2^16 - 2^8) bytes.
 *
 *  Security: The mac length parameter is an important parameter to estimate the
 *            security against collision attacks (that aim at finding different
 *            messages that produce the same authentication tag). TinyCrypt CCM
 *            implementation accepts any even integer between 4 and 16, as
 *            suggested in SP 800-38C.
 *
 *            RFC-3610, which also specifies CCM, presents a few relevant
 *            security suggestions, such as: it is recommended for most
 *            applications to use a mac length greater than 8. Besides, the
 *            usage of the same nonce for two different messages which are
 *            encrypted with the same key destroys the security of CCM mode.
 *
 *  Requires: AES-128
 *
 *  Usage:    1) call tc_ccm_config to configure.
 *
 *            2) call tc_ccm_mode_encrypt to encrypt data and generate tag.
 *
 *            3) call tc_ccm_mode_decrypt to decrypt data and verify tag.
 */

#ifndef __TC_CCM_MODE_H__
#define __TC_CCM_MODE_H__

#include <tinycrypt/aes.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

/* max additional authenticated size in bytes: 2^16 - 2^8 = 65280 */
#define TC_CCM_AAD_MAX_BYTES 0xff00

/* max message size in bytes: 2^(8L) = 2^16 = 65536 */
#define TC_CCM_PAYLOAD_MAX_BYTES 0x10000

/* struct tc_ccm_mode_struct represents the state of a CCM computation */
typedef struct tc_ccm_mode_struct {
	TCAesKeySched_t sched; /* AES key schedule */
	uint8_t *nonce; /* nonce required by CCM */
	unsigned int mlen; /* mac length in bytes (parameter t in SP-800 38C) */
} *TCCcmMode_t;

/**
 * @brief CCM configuration procedure
 * @return returns TC_CRYPTO_SUCCESS (1)
 *          returns TC_CRYPTO_FAIL (0) if:
 *                c == NULL or
 *                sched == NULL or
 *                nonce == NULL or
 *                mlen != {4, 6, 8, 10, 12, 16}
 * @param c -- CCM state
 * @param sched IN -- AES key schedule
 * @param nonce IN - nonce
 * @param nlen -- nonce length in bytes
 * @param mlen -- mac length in bytes (parameter t in SP-800 38C)
 */
int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce,
		  unsigned int nlen, unsigned int mlen);

/**
 * @brief CCM tag generation and encryption procedure
 * @return returns TC_CRYPTO_SUCCESS (1)
 *         returns TC_CRYPTO_FAIL (0) if:
 *                out == NULL or
 *                c == NULL or
 *                ((plen > 0) and (payload == NULL)) or
 *                ((alen > 0) and (associated_data == NULL)) or
 *                (alen >= TC_CCM_AAD_MAX_BYTES) or
 *                (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or
 *                (olen < plen + maclength)
 *
 * @param out OUT -- encrypted data
 * @param olen IN -- output length in bytes
 * @param associated_data IN -- associated data
 * @param alen IN -- associated data length in bytes
 * @param payload IN -- payload
 * @param plen IN -- payload length in bytes
 * @param c IN -- CCM state
 *
 * @note: out buffer should be at least (plen + c->mlen) bytes long.
 *
 * @note: The sequence b for encryption is formatted as follows:
 *        b = [FLAGS | nonce | counter ], where:
 *          FLAGS is 1 byte long
 *          nonce is 13 bytes long
 *          counter is 2 bytes long
 *        The byte FLAGS is composed by the following 8 bits:
 *          0-2 bits: used to represent the value of q-1
 *          3-7 btis: always 0's
 *
 * @note: The sequence b for authentication is formatted as follows:
 *        b = [FLAGS | nonce | length(mac length)], where:
 *          FLAGS is 1 byte long
 *          nonce is 13 bytes long
 *          length(mac length) is 2 bytes long
 *        The byte FLAGS is composed by the following 8 bits:
 *          0-2 bits: used to represent the value of q-1
 *          3-5 bits: mac length (encoded as: (mlen-2)/2)
 *          6: Adata (0 if alen == 0, and 1 otherwise)
 *          7: always 0
 */
int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen,
			   	 const uint8_t *associated_data,
			   	 unsigned int alen, const uint8_t *payload,
				 unsigned int plen, TCCcmMode_t c);

/**
 * @brief CCM decryption and tag verification procedure
 * @return returns TC_CRYPTO_SUCCESS (1)
 *         returns TC_CRYPTO_FAIL (0) if:
 *                out == NULL or
 *                c == NULL or
 *                ((plen > 0) and (payload == NULL)) or
 *                ((alen > 0) and (associated_data == NULL)) or
 *                (alen >= TC_CCM_AAD_MAX_BYTES) or
 *                (plen >= TC_CCM_PAYLOAD_MAX_BYTES) or
 *                (olen < plen - c->mlen)
 *
 * @param out OUT -- decrypted data
 * @param associated_data IN -- associated data
 * @param alen IN -- associated data length in bytes
 * @param payload IN -- payload
 * @param plen IN -- payload length in bytes
 * @param c IN -- CCM state
 *
 * @note: out buffer should be at least (plen - c->mlen) bytes long.
 *
 * @note: The sequence b for encryption is formatted as follows:
 *        b = [FLAGS | nonce | counter ], where:
 *          FLAGS is 1 byte long
 *          nonce is 13 bytes long
 *          counter is 2 bytes long
 *        The byte FLAGS is composed by the following 8 bits:
 *          0-2 bits: used to represent the value of q-1
 *          3-7 btis: always 0's
 *
 * @note: The sequence b for authentication is formatted as follows:
 *        b = [FLAGS | nonce | length(mac length)], where:
 *          FLAGS is 1 byte long
 *          nonce is 13 bytes long
 *          length(mac length) is 2 bytes long
 *        The byte FLAGS is composed by the following 8 bits:
 *          0-2 bits: used to represent the value of q-1
 *          3-5 bits: mac length (encoded as: (mlen-2)/2)
 *          6: Adata (0 if alen == 0, and 1 otherwise)
 *          7: always 0
 */
int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen,
				   const uint8_t *associated_data,
				   unsigned int alen, const uint8_t *payload, unsigned int plen,
				   TCCcmMode_t c);

#ifdef __cplusplus
}
#endif

#endif /* __TC_CCM_MODE_H__ */