]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/src/symcipher/aes_ct64_ctrcbc.c
Add libbearssl
[FreeBSD/FreeBSD.git] / contrib / bearssl / src / symcipher / aes_ct64_ctrcbc.c
1 /*
2  * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining 
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be 
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 #include "inner.h"
26
27 /* see bearssl_block.h */
28 void
29 br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx,
30         const void *key, size_t len)
31 {
32         ctx->vtable = &br_aes_ct64_ctrcbc_vtable;
33         ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len);
34 }
35
36 static void
37 xorbuf(void *dst, const void *src, size_t len)
38 {
39         unsigned char *d;
40         const unsigned char *s;
41
42         d = dst;
43         s = src;
44         while (len -- > 0) {
45                 *d ++ ^= *s ++;
46         }
47 }
48
49 /* see bearssl_block.h */
50 void
51 br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx,
52         void *ctr, void *data, size_t len)
53 {
54         unsigned char *buf;
55         unsigned char *ivbuf;
56         uint32_t iv0, iv1, iv2, iv3;
57         uint64_t sk_exp[120];
58
59         br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
60
61         /*
62          * We keep the counter as four 32-bit values, with big-endian
63          * convention, because that's what is expected for purposes of
64          * incrementing the counter value.
65          */
66         ivbuf = ctr;
67         iv0 = br_dec32be(ivbuf +  0);
68         iv1 = br_dec32be(ivbuf +  4);
69         iv2 = br_dec32be(ivbuf +  8);
70         iv3 = br_dec32be(ivbuf + 12);
71
72         buf = data;
73         while (len > 0) {
74                 uint64_t q[8];
75                 uint32_t w[16];
76                 unsigned char tmp[64];
77                 int i, j;
78
79                 /*
80                  * The bitslice implementation expects values in
81                  * little-endian convention, so we have to byteswap them.
82                  */
83                 j = (len >= 64) ? 16 : (int)(len >> 2);
84                 for (i = 0; i < j; i += 4) {
85                         uint32_t carry;
86
87                         w[i + 0] = br_swap32(iv0);
88                         w[i + 1] = br_swap32(iv1);
89                         w[i + 2] = br_swap32(iv2);
90                         w[i + 3] = br_swap32(iv3);
91                         iv3 ++;
92                         carry = ~(iv3 | -iv3) >> 31;
93                         iv2 += carry;
94                         carry &= -(~(iv2 | -iv2) >> 31);
95                         iv1 += carry;
96                         carry &= -(~(iv1 | -iv1) >> 31);
97                         iv0 += carry;
98                 }
99                 memset(w + i, 0, (16 - i) * sizeof(uint32_t));
100
101                 for (i = 0; i < 4; i ++) {
102                         br_aes_ct64_interleave_in(
103                                 &q[i], &q[i + 4], w + (i << 2));
104                 }
105                 br_aes_ct64_ortho(q);
106                 br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
107                 br_aes_ct64_ortho(q);
108                 for (i = 0; i < 4; i ++) {
109                         br_aes_ct64_interleave_out(
110                                 w + (i << 2), q[i], q[i + 4]);
111                 }
112
113                 br_range_enc32le(tmp, w, 16);
114                 if (len <= 64) {
115                         xorbuf(buf, tmp, len);
116                         break;
117                 }
118                 xorbuf(buf, tmp, 64);
119                 buf += 64;
120                 len -= 64;
121         }
122         br_enc32be(ivbuf +  0, iv0);
123         br_enc32be(ivbuf +  4, iv1);
124         br_enc32be(ivbuf +  8, iv2);
125         br_enc32be(ivbuf + 12, iv3);
126 }
127
128 /* see bearssl_block.h */
129 void
130 br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx,
131         void *cbcmac, const void *data, size_t len)
132 {
133         const unsigned char *buf;
134         uint32_t cm0, cm1, cm2, cm3;
135         uint64_t q[8];
136         uint64_t sk_exp[120];
137
138         br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
139
140         cm0 = br_dec32le((unsigned char *)cbcmac +  0);
141         cm1 = br_dec32le((unsigned char *)cbcmac +  4);
142         cm2 = br_dec32le((unsigned char *)cbcmac +  8);
143         cm3 = br_dec32le((unsigned char *)cbcmac + 12);
144
145         buf = data;
146         memset(q, 0, sizeof q);
147         while (len > 0) {
148                 uint32_t w[4];
149
150                 w[0] = cm0 ^ br_dec32le(buf +  0);
151                 w[1] = cm1 ^ br_dec32le(buf +  4);
152                 w[2] = cm2 ^ br_dec32le(buf +  8);
153                 w[3] = cm3 ^ br_dec32le(buf + 12);
154
155                 br_aes_ct64_interleave_in(&q[0], &q[4], w);
156                 br_aes_ct64_ortho(q);
157                 br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
158                 br_aes_ct64_ortho(q);
159                 br_aes_ct64_interleave_out(w, q[0], q[4]);
160
161                 cm0 = w[0];
162                 cm1 = w[1];
163                 cm2 = w[2];
164                 cm3 = w[3];
165                 buf += 16;
166                 len -= 16;
167         }
168
169         br_enc32le((unsigned char *)cbcmac +  0, cm0);
170         br_enc32le((unsigned char *)cbcmac +  4, cm1);
171         br_enc32le((unsigned char *)cbcmac +  8, cm2);
172         br_enc32le((unsigned char *)cbcmac + 12, cm3);
173 }
174
175 /* see bearssl_block.h */
176 void
177 br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx,
178         void *ctr, void *cbcmac, void *data, size_t len)
179 {
180         /*
181          * When encrypting, the CBC-MAC processing must be lagging by
182          * one block, since it operates on the encrypted values, so
183          * it must wait for that encryption to complete.
184          */
185
186         unsigned char *buf;
187         unsigned char *ivbuf;
188         uint32_t iv0, iv1, iv2, iv3;
189         uint32_t cm0, cm1, cm2, cm3;
190         uint64_t sk_exp[120];
191         uint64_t q[8];
192         int first_iter;
193
194         br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
195
196         /*
197          * We keep the counter as four 32-bit values, with big-endian
198          * convention, because that's what is expected for purposes of
199          * incrementing the counter value.
200          */
201         ivbuf = ctr;
202         iv0 = br_dec32be(ivbuf +  0);
203         iv1 = br_dec32be(ivbuf +  4);
204         iv2 = br_dec32be(ivbuf +  8);
205         iv3 = br_dec32be(ivbuf + 12);
206
207         /*
208          * The current CBC-MAC value is kept in little-endian convention.
209          */
210         cm0 = br_dec32le((unsigned char *)cbcmac +  0);
211         cm1 = br_dec32le((unsigned char *)cbcmac +  4);
212         cm2 = br_dec32le((unsigned char *)cbcmac +  8);
213         cm3 = br_dec32le((unsigned char *)cbcmac + 12);
214
215         buf = data;
216         first_iter = 1;
217         memset(q, 0, sizeof q);
218         while (len > 0) {
219                 uint32_t w[8], carry;
220
221                 /*
222                  * The bitslice implementation expects values in
223                  * little-endian convention, so we have to byteswap them.
224                  */
225                 w[0] = br_swap32(iv0);
226                 w[1] = br_swap32(iv1);
227                 w[2] = br_swap32(iv2);
228                 w[3] = br_swap32(iv3);
229                 iv3 ++;
230                 carry = ~(iv3 | -iv3) >> 31;
231                 iv2 += carry;
232                 carry &= -(~(iv2 | -iv2) >> 31);
233                 iv1 += carry;
234                 carry &= -(~(iv1 | -iv1) >> 31);
235                 iv0 += carry;
236
237                 /*
238                  * The block for CBC-MAC.
239                  */
240                 w[4] = cm0;
241                 w[5] = cm1;
242                 w[6] = cm2;
243                 w[7] = cm3;
244
245                 br_aes_ct64_interleave_in(&q[0], &q[4], w);
246                 br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
247                 br_aes_ct64_ortho(q);
248                 br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
249                 br_aes_ct64_ortho(q);
250                 br_aes_ct64_interleave_out(w, q[0], q[4]);
251                 br_aes_ct64_interleave_out(w + 4, q[1], q[5]);
252
253                 /*
254                  * We do the XOR with the plaintext in 32-bit registers,
255                  * so that the value are available for CBC-MAC processing
256                  * as well.
257                  */
258                 w[0] ^= br_dec32le(buf +  0);
259                 w[1] ^= br_dec32le(buf +  4);
260                 w[2] ^= br_dec32le(buf +  8);
261                 w[3] ^= br_dec32le(buf + 12);
262                 br_enc32le(buf +  0, w[0]);
263                 br_enc32le(buf +  4, w[1]);
264                 br_enc32le(buf +  8, w[2]);
265                 br_enc32le(buf + 12, w[3]);
266
267                 buf += 16;
268                 len -= 16;
269
270                 /*
271                  * We set the cm* values to the block to encrypt in the
272                  * next iteration.
273                  */
274                 if (first_iter) {
275                         first_iter = 0;
276                         cm0 ^= w[0];
277                         cm1 ^= w[1];
278                         cm2 ^= w[2];
279                         cm3 ^= w[3];
280                 } else {
281                         cm0 = w[0] ^ w[4];
282                         cm1 = w[1] ^ w[5];
283                         cm2 = w[2] ^ w[6];
284                         cm3 = w[3] ^ w[7];
285                 }
286
287                 /*
288                  * If this was the last iteration, then compute the
289                  * extra block encryption to complete CBC-MAC.
290                  */
291                 if (len == 0) {
292                         w[0] = cm0;
293                         w[1] = cm1;
294                         w[2] = cm2;
295                         w[3] = cm3;
296                         br_aes_ct64_interleave_in(&q[0], &q[4], w);
297                         br_aes_ct64_ortho(q);
298                         br_aes_ct64_bitslice_encrypt(
299                                 ctx->num_rounds, sk_exp, q);
300                         br_aes_ct64_ortho(q);
301                         br_aes_ct64_interleave_out(w, q[0], q[4]);
302                         cm0 = w[0];
303                         cm1 = w[1];
304                         cm2 = w[2];
305                         cm3 = w[3];
306                         break;
307                 }
308         }
309
310         br_enc32be(ivbuf +  0, iv0);
311         br_enc32be(ivbuf +  4, iv1);
312         br_enc32be(ivbuf +  8, iv2);
313         br_enc32be(ivbuf + 12, iv3);
314         br_enc32le((unsigned char *)cbcmac +  0, cm0);
315         br_enc32le((unsigned char *)cbcmac +  4, cm1);
316         br_enc32le((unsigned char *)cbcmac +  8, cm2);
317         br_enc32le((unsigned char *)cbcmac + 12, cm3);
318 }
319
320 /* see bearssl_block.h */
321 void
322 br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx,
323         void *ctr, void *cbcmac, void *data, size_t len)
324 {
325         unsigned char *buf;
326         unsigned char *ivbuf;
327         uint32_t iv0, iv1, iv2, iv3;
328         uint32_t cm0, cm1, cm2, cm3;
329         uint64_t sk_exp[120];
330         uint64_t q[8];
331
332         br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
333
334         /*
335          * We keep the counter as four 32-bit values, with big-endian
336          * convention, because that's what is expected for purposes of
337          * incrementing the counter value.
338          */
339         ivbuf = ctr;
340         iv0 = br_dec32be(ivbuf +  0);
341         iv1 = br_dec32be(ivbuf +  4);
342         iv2 = br_dec32be(ivbuf +  8);
343         iv3 = br_dec32be(ivbuf + 12);
344
345         /*
346          * The current CBC-MAC value is kept in little-endian convention.
347          */
348         cm0 = br_dec32le((unsigned char *)cbcmac +  0);
349         cm1 = br_dec32le((unsigned char *)cbcmac +  4);
350         cm2 = br_dec32le((unsigned char *)cbcmac +  8);
351         cm3 = br_dec32le((unsigned char *)cbcmac + 12);
352
353         buf = data;
354         memset(q, 0, sizeof q);
355         while (len > 0) {
356                 uint32_t w[8], carry;
357                 unsigned char tmp[16];
358
359                 /*
360                  * The bitslice implementation expects values in
361                  * little-endian convention, so we have to byteswap them.
362                  */
363                 w[0] = br_swap32(iv0);
364                 w[1] = br_swap32(iv1);
365                 w[2] = br_swap32(iv2);
366                 w[3] = br_swap32(iv3);
367                 iv3 ++;
368                 carry = ~(iv3 | -iv3) >> 31;
369                 iv2 += carry;
370                 carry &= -(~(iv2 | -iv2) >> 31);
371                 iv1 += carry;
372                 carry &= -(~(iv1 | -iv1) >> 31);
373                 iv0 += carry;
374
375                 /*
376                  * The block for CBC-MAC.
377                  */
378                 w[4] = cm0 ^ br_dec32le(buf +  0);
379                 w[5] = cm1 ^ br_dec32le(buf +  4);
380                 w[6] = cm2 ^ br_dec32le(buf +  8);
381                 w[7] = cm3 ^ br_dec32le(buf + 12);
382
383                 br_aes_ct64_interleave_in(&q[0], &q[4], w);
384                 br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
385                 br_aes_ct64_ortho(q);
386                 br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
387                 br_aes_ct64_ortho(q);
388                 br_aes_ct64_interleave_out(w, q[0], q[4]);
389                 br_aes_ct64_interleave_out(w + 4, q[1], q[5]);
390
391                 br_enc32le(tmp +  0, w[0]);
392                 br_enc32le(tmp +  4, w[1]);
393                 br_enc32le(tmp +  8, w[2]);
394                 br_enc32le(tmp + 12, w[3]);
395                 xorbuf(buf, tmp, 16);
396                 cm0 = w[4];
397                 cm1 = w[5];
398                 cm2 = w[6];
399                 cm3 = w[7];
400                 buf += 16;
401                 len -= 16;
402         }
403
404         br_enc32be(ivbuf +  0, iv0);
405         br_enc32be(ivbuf +  4, iv1);
406         br_enc32be(ivbuf +  8, iv2);
407         br_enc32be(ivbuf + 12, iv3);
408         br_enc32le((unsigned char *)cbcmac +  0, cm0);
409         br_enc32le((unsigned char *)cbcmac +  4, cm1);
410         br_enc32le((unsigned char *)cbcmac +  8, cm2);
411         br_enc32le((unsigned char *)cbcmac + 12, cm3);
412 }
413
414 /* see bearssl_block.h */
415 const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable = {
416         sizeof(br_aes_ct64_ctrcbc_keys),
417         16,
418         4,
419         (void (*)(const br_block_ctrcbc_class **, const void *, size_t))
420                 &br_aes_ct64_ctrcbc_init,
421         (void (*)(const br_block_ctrcbc_class *const *,
422                 void *, void *, void *, size_t))
423                 &br_aes_ct64_ctrcbc_encrypt,
424         (void (*)(const br_block_ctrcbc_class *const *,
425                 void *, void *, void *, size_t))
426                 &br_aes_ct64_ctrcbc_decrypt,
427         (void (*)(const br_block_ctrcbc_class *const *,
428                 void *, void *, size_t))
429                 &br_aes_ct64_ctrcbc_ctr,
430         (void (*)(const br_block_ctrcbc_class *const *,
431                 void *, const void *, size_t))
432                 &br_aes_ct64_ctrcbc_mac
433 };