1 /* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
53 #include <openssl/cpu.h>
54 #include <openssl/mem.h>
56 #include "../../internal.h"
67 int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const void *key, block128_f block,
68 ctr128_f ctr, unsigned M, unsigned L) {
69 if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) {
79 size_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;
84 static int ccm128_init_state(const CCM128_CONTEXT *ctx,
85 struct ccm128_state *state, const void *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;
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) {
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);
103 state->nonce.c[0] |= 0x40; // Set AAD Flag
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));
110 (*block)(state->nonce.c, state->cmac.c, key);
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;
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;
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;
144 for (; i < 16 && aad_len != 0; i++) {
145 state->cmac.c[i] ^= *aad;
149 (*block)(state->cmac.c, state->cmac.c, key);
152 } while (aad_len != 0);
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) {
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;
172 static int ccm128_encrypt(const CCM128_CONTEXT *ctx, struct ccm128_state *state,
173 const void *key, uint8_t *out, const uint8_t *in,
175 // The counter for encryption begins at one.
176 for (unsigned i = 0; i < ctx->L; i++) {
177 state->nonce.c[15 - i] = 0;
179 state->nonce.c[15] = 1;
181 uint8_t partial_buf[16];
183 if (ctx->ctr != NULL) {
184 CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf,
187 CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num,
193 static int ccm128_compute_mac(const CCM128_CONTEXT *ctx,
194 struct ccm128_state *state, const void *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) {
202 // Incorporate |in| into the MAC.
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);
216 for (size_t i = 0; i < len; i++) {
217 state->cmac.c[i] ^= in[i];
219 (*block)(state->cmac.c, state->cmac.c, key);
222 // Encrypt the MAC with counter zero.
223 for (unsigned i = 0; i < ctx->L; i++) {
224 state->nonce.c[15 - i] = 0;
226 (*block)(state->nonce.c, tmp.c, key);
227 state->cmac.u[0] ^= tmp.u[0];
228 state->cmac.u[1] ^= tmp.u[1];
230 OPENSSL_memcpy(out_tag, state->cmac.c, tag_len);
234 int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const void *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,
239 struct ccm128_state state;
240 return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
242 ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) &&
243 ccm128_encrypt(ctx, &state, key, out, in, len);
246 int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const void *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,
251 struct ccm128_state state;
252 return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
254 ccm128_encrypt(ctx, &state, key, out, in, len) &&
255 ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len);