Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / boringssl / crypto / fipsmodule / modes / ccm.c
1 /* ====================================================================
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
60 struct ccm128_state {
61   union {
62     uint64_t u[2];
63     uint8_t c[16];
64   } nonce, cmac;
65 };
66
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) {
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
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;
82 }
83
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;
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
172 static int ccm128_encrypt(const CCM128_CONTEXT *ctx, struct ccm128_state *state,
173                           const void *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
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) {
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
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,
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
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,
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 }