blob: 5a153f41e0f38f68abf782eff18ad4dee6d1af5f [file] [log] [blame]
Srinivas Paladugudd42a612019-08-09 19:30:39 +00001/* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 */
49
50#include <assert.h>
51#include <string.h>
52
53#include <openssl/cpu.h>
54#include <openssl/mem.h>
55
56#include "../../internal.h"
57#include "internal.h"
58
59
60struct ccm128_state {
61 union {
62 uint64_t u[2];
63 uint8_t c[16];
64 } nonce, cmac;
65};
66
67int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const AES_KEY *key,
68 block128_f block, ctr128_f ctr, unsigned M, unsigned L) {
69 if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) {
70 return 0;
71 }
72 ctx->block = block;
73 ctx->ctr = ctr;
74 ctx->M = M;
75 ctx->L = L;
76 return 1;
77}
78
79size_t CRYPTO_ccm128_max_input(const CCM128_CONTEXT *ctx) {
80 return ctx->L >= sizeof(size_t) ? (size_t)-1
81 : (((size_t)1) << (ctx->L * 8)) - 1;
82}
83
84static int ccm128_init_state(const CCM128_CONTEXT *ctx,
85 struct ccm128_state *state, const AES_KEY *key,
86 const uint8_t *nonce, size_t nonce_len,
87 const uint8_t *aad, size_t aad_len,
88 size_t plaintext_len) {
89 const block128_f block = ctx->block;
90 const unsigned M = ctx->M;
91 const unsigned L = ctx->L;
92
93 // |L| determines the expected |nonce_len| and the limit for |plaintext_len|.
94 if (plaintext_len > CRYPTO_ccm128_max_input(ctx) ||
95 nonce_len != 15 - L) {
96 return 0;
97 }
98
99 // Assemble the first block for computing the MAC.
100 OPENSSL_memset(state, 0, sizeof(*state));
101 state->nonce.c[0] = (uint8_t)((L - 1) | ((M - 2) / 2) << 3);
102 if (aad_len != 0) {
103 state->nonce.c[0] |= 0x40; // Set AAD Flag
104 }
105 OPENSSL_memcpy(&state->nonce.c[1], nonce, nonce_len);
106 for (unsigned i = 0; i < L; i++) {
107 state->nonce.c[15 - i] = (uint8_t)(plaintext_len >> (8 * i));
108 }
109
110 (*block)(state->nonce.c, state->cmac.c, key);
111 size_t blocks = 1;
112
113 if (aad_len != 0) {
114 unsigned i;
115 // Cast to u64 to avoid the compiler complaining about invalid shifts.
116 uint64_t aad_len_u64 = aad_len;
117 if (aad_len_u64 < 0x10000 - 0x100) {
118 state->cmac.c[0] ^= (uint8_t)(aad_len_u64 >> 8);
119 state->cmac.c[1] ^= (uint8_t)aad_len_u64;
120 i = 2;
121 } else if (aad_len_u64 <= 0xffffffff) {
122 state->cmac.c[0] ^= 0xff;
123 state->cmac.c[1] ^= 0xfe;
124 state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 24);
125 state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 16);
126 state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 8);
127 state->cmac.c[5] ^= (uint8_t)aad_len_u64;
128 i = 6;
129 } else {
130 state->cmac.c[0] ^= 0xff;
131 state->cmac.c[1] ^= 0xff;
132 state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 56);
133 state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 48);
134 state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 40);
135 state->cmac.c[5] ^= (uint8_t)(aad_len_u64 >> 32);
136 state->cmac.c[6] ^= (uint8_t)(aad_len_u64 >> 24);
137 state->cmac.c[7] ^= (uint8_t)(aad_len_u64 >> 16);
138 state->cmac.c[8] ^= (uint8_t)(aad_len_u64 >> 8);
139 state->cmac.c[9] ^= (uint8_t)aad_len_u64;
140 i = 10;
141 }
142
143 do {
144 for (; i < 16 && aad_len != 0; i++) {
145 state->cmac.c[i] ^= *aad;
146 aad++;
147 aad_len--;
148 }
149 (*block)(state->cmac.c, state->cmac.c, key);
150 blocks++;
151 i = 0;
152 } while (aad_len != 0);
153 }
154
155 // Per RFC 3610, section 2.6, the total number of block cipher operations done
156 // must not exceed 2^61. There are two block cipher operations remaining per
157 // message block, plus one block at the end to encrypt the MAC.
158 size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1;
159 if (plaintext_len + 15 < plaintext_len ||
160 remaining_blocks + blocks < blocks ||
161 (uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) {
162 return 0;
163 }
164
165 // Assemble the first block for encrypting and decrypting. The bottom |L|
166 // bytes are replaced with a counter and all bit the encoding of |L| is
167 // cleared in the first byte.
168 state->nonce.c[0] &= 7;
169 return 1;
170}
171
172static int ccm128_encrypt(const CCM128_CONTEXT *ctx, struct ccm128_state *state,
173 const AES_KEY *key, uint8_t *out, const uint8_t *in,
174 size_t len) {
175 // The counter for encryption begins at one.
176 for (unsigned i = 0; i < ctx->L; i++) {
177 state->nonce.c[15 - i] = 0;
178 }
179 state->nonce.c[15] = 1;
180
181 uint8_t partial_buf[16];
182 unsigned num = 0;
183 if (ctx->ctr != NULL) {
184 CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf,
185 &num, ctx->ctr);
186 } else {
187 CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num,
188 ctx->block);
189 }
190 return 1;
191}
192
193static int ccm128_compute_mac(const CCM128_CONTEXT *ctx,
194 struct ccm128_state *state, const AES_KEY *key,
195 uint8_t *out_tag, size_t tag_len,
196 const uint8_t *in, size_t len) {
197 block128_f block = ctx->block;
198 if (tag_len != ctx->M) {
199 return 0;
200 }
201
202 // Incorporate |in| into the MAC.
203 union {
204 uint64_t u[2];
205 uint8_t c[16];
206 } tmp;
207 while (len >= 16) {
208 OPENSSL_memcpy(tmp.c, in, 16);
209 state->cmac.u[0] ^= tmp.u[0];
210 state->cmac.u[1] ^= tmp.u[1];
211 (*block)(state->cmac.c, state->cmac.c, key);
212 in += 16;
213 len -= 16;
214 }
215 if (len > 0) {
216 for (size_t i = 0; i < len; i++) {
217 state->cmac.c[i] ^= in[i];
218 }
219 (*block)(state->cmac.c, state->cmac.c, key);
220 }
221
222 // Encrypt the MAC with counter zero.
223 for (unsigned i = 0; i < ctx->L; i++) {
224 state->nonce.c[15 - i] = 0;
225 }
226 (*block)(state->nonce.c, tmp.c, key);
227 state->cmac.u[0] ^= tmp.u[0];
228 state->cmac.u[1] ^= tmp.u[1];
229
230 OPENSSL_memcpy(out_tag, state->cmac.c, tag_len);
231 return 1;
232}
233
234int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const AES_KEY *key,
235 uint8_t *out, uint8_t *out_tag, size_t tag_len,
236 const uint8_t *nonce, size_t nonce_len,
237 const uint8_t *in, size_t len, const uint8_t *aad,
238 size_t aad_len) {
239 struct ccm128_state state;
240 return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
241 len) &&
242 ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) &&
243 ccm128_encrypt(ctx, &state, key, out, in, len);
244}
245
246int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const AES_KEY *key,
247 uint8_t *out, uint8_t *out_tag, size_t tag_len,
248 const uint8_t *nonce, size_t nonce_len,
249 const uint8_t *in, size_t len, const uint8_t *aad,
250 size_t aad_len) {
251 struct ccm128_state state;
252 return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
253 len) &&
254 ccm128_encrypt(ctx, &state, key, out, in, len) &&
255 ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len);
256}