File Coverage

src/symcipher/aes_ct64_ctrcbc.c
Criterion Covered Total %
statement 0 221 0.0
branch 0 24 0.0
condition n/a
subroutine n/a
pod n/a
total 0 245 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2017 Thomas Pornin
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 0           br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx,
30             const void *key, size_t len)
31             {
32 0           ctx->vtable = &br_aes_ct64_ctrcbc_vtable;
33 0           ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len);
34 0           }
35              
36             static void
37 0           xorbuf(void *dst, const void *src, size_t len)
38             {
39             unsigned char *d;
40             const unsigned char *s;
41              
42 0           d = dst;
43 0           s = src;
44 0 0         while (len -- > 0) {
45 0           *d ++ ^= *s ++;
46             }
47 0           }
48              
49             /* see bearssl_block.h */
50             void
51 0           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 0           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 0           ivbuf = ctr;
67 0           iv0 = br_dec32be(ivbuf + 0);
68 0           iv1 = br_dec32be(ivbuf + 4);
69 0           iv2 = br_dec32be(ivbuf + 8);
70 0           iv3 = br_dec32be(ivbuf + 12);
71              
72 0           buf = data;
73 0 0         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 0 0         j = (len >= 64) ? 16 : (int)(len >> 2);
84 0 0         for (i = 0; i < j; i += 4) {
85             uint32_t carry;
86              
87 0           w[i + 0] = br_swap32(iv0);
88 0           w[i + 1] = br_swap32(iv1);
89 0           w[i + 2] = br_swap32(iv2);
90 0           w[i + 3] = br_swap32(iv3);
91 0           iv3 ++;
92 0           carry = ~(iv3 | -iv3) >> 31;
93 0           iv2 += carry;
94 0           carry &= -(~(iv2 | -iv2) >> 31);
95 0           iv1 += carry;
96 0           carry &= -(~(iv1 | -iv1) >> 31);
97 0           iv0 += carry;
98             }
99 0           memset(w + i, 0, (16 - i) * sizeof(uint32_t));
100              
101 0 0         for (i = 0; i < 4; i ++) {
102 0           br_aes_ct64_interleave_in(
103 0           &q[i], &q[i + 4], w + (i << 2));
104             }
105 0           br_aes_ct64_ortho(q);
106 0           br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
107 0           br_aes_ct64_ortho(q);
108 0 0         for (i = 0; i < 4; i ++) {
109 0           br_aes_ct64_interleave_out(
110 0           w + (i << 2), q[i], q[i + 4]);
111             }
112              
113 0           br_range_enc32le(tmp, w, 16);
114 0 0         if (len <= 64) {
115 0           xorbuf(buf, tmp, len);
116 0           break;
117             }
118 0           xorbuf(buf, tmp, 64);
119 0           buf += 64;
120 0           len -= 64;
121             }
122 0           br_enc32be(ivbuf + 0, iv0);
123 0           br_enc32be(ivbuf + 4, iv1);
124 0           br_enc32be(ivbuf + 8, iv2);
125 0           br_enc32be(ivbuf + 12, iv3);
126 0           }
127              
128             /* see bearssl_block.h */
129             void
130 0           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 0           br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
139              
140 0           cm0 = br_dec32le((unsigned char *)cbcmac + 0);
141 0           cm1 = br_dec32le((unsigned char *)cbcmac + 4);
142 0           cm2 = br_dec32le((unsigned char *)cbcmac + 8);
143 0           cm3 = br_dec32le((unsigned char *)cbcmac + 12);
144              
145 0           buf = data;
146 0           memset(q, 0, sizeof q);
147 0 0         while (len > 0) {
148             uint32_t w[4];
149              
150 0           w[0] = cm0 ^ br_dec32le(buf + 0);
151 0           w[1] = cm1 ^ br_dec32le(buf + 4);
152 0           w[2] = cm2 ^ br_dec32le(buf + 8);
153 0           w[3] = cm3 ^ br_dec32le(buf + 12);
154              
155 0           br_aes_ct64_interleave_in(&q[0], &q[4], w);
156 0           br_aes_ct64_ortho(q);
157 0           br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
158 0           br_aes_ct64_ortho(q);
159 0           br_aes_ct64_interleave_out(w, q[0], q[4]);
160              
161 0           cm0 = w[0];
162 0           cm1 = w[1];
163 0           cm2 = w[2];
164 0           cm3 = w[3];
165 0           buf += 16;
166 0           len -= 16;
167             }
168              
169 0           br_enc32le((unsigned char *)cbcmac + 0, cm0);
170 0           br_enc32le((unsigned char *)cbcmac + 4, cm1);
171 0           br_enc32le((unsigned char *)cbcmac + 8, cm2);
172 0           br_enc32le((unsigned char *)cbcmac + 12, cm3);
173 0           }
174              
175             /* see bearssl_block.h */
176             void
177 0           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 0           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 0           ivbuf = ctr;
202 0           iv0 = br_dec32be(ivbuf + 0);
203 0           iv1 = br_dec32be(ivbuf + 4);
204 0           iv2 = br_dec32be(ivbuf + 8);
205 0           iv3 = br_dec32be(ivbuf + 12);
206              
207             /*
208             * The current CBC-MAC value is kept in little-endian convention.
209             */
210 0           cm0 = br_dec32le((unsigned char *)cbcmac + 0);
211 0           cm1 = br_dec32le((unsigned char *)cbcmac + 4);
212 0           cm2 = br_dec32le((unsigned char *)cbcmac + 8);
213 0           cm3 = br_dec32le((unsigned char *)cbcmac + 12);
214              
215 0           buf = data;
216 0           first_iter = 1;
217 0           memset(q, 0, sizeof q);
218 0 0         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 0           w[0] = br_swap32(iv0);
226 0           w[1] = br_swap32(iv1);
227 0           w[2] = br_swap32(iv2);
228 0           w[3] = br_swap32(iv3);
229 0           iv3 ++;
230 0           carry = ~(iv3 | -iv3) >> 31;
231 0           iv2 += carry;
232 0           carry &= -(~(iv2 | -iv2) >> 31);
233 0           iv1 += carry;
234 0           carry &= -(~(iv1 | -iv1) >> 31);
235 0           iv0 += carry;
236              
237             /*
238             * The block for CBC-MAC.
239             */
240 0           w[4] = cm0;
241 0           w[5] = cm1;
242 0           w[6] = cm2;
243 0           w[7] = cm3;
244              
245 0           br_aes_ct64_interleave_in(&q[0], &q[4], w);
246 0           br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
247 0           br_aes_ct64_ortho(q);
248 0           br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
249 0           br_aes_ct64_ortho(q);
250 0           br_aes_ct64_interleave_out(w, q[0], q[4]);
251 0           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 0           w[0] ^= br_dec32le(buf + 0);
259 0           w[1] ^= br_dec32le(buf + 4);
260 0           w[2] ^= br_dec32le(buf + 8);
261 0           w[3] ^= br_dec32le(buf + 12);
262 0           br_enc32le(buf + 0, w[0]);
263 0           br_enc32le(buf + 4, w[1]);
264 0           br_enc32le(buf + 8, w[2]);
265 0           br_enc32le(buf + 12, w[3]);
266              
267 0           buf += 16;
268 0           len -= 16;
269              
270             /*
271             * We set the cm* values to the block to encrypt in the
272             * next iteration.
273             */
274 0 0         if (first_iter) {
275 0           first_iter = 0;
276 0           cm0 ^= w[0];
277 0           cm1 ^= w[1];
278 0           cm2 ^= w[2];
279 0           cm3 ^= w[3];
280             } else {
281 0           cm0 = w[0] ^ w[4];
282 0           cm1 = w[1] ^ w[5];
283 0           cm2 = w[2] ^ w[6];
284 0           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 0 0         if (len == 0) {
292 0           w[0] = cm0;
293 0           w[1] = cm1;
294 0           w[2] = cm2;
295 0           w[3] = cm3;
296 0           br_aes_ct64_interleave_in(&q[0], &q[4], w);
297 0           br_aes_ct64_ortho(q);
298 0           br_aes_ct64_bitslice_encrypt(
299 0           ctx->num_rounds, sk_exp, q);
300 0           br_aes_ct64_ortho(q);
301 0           br_aes_ct64_interleave_out(w, q[0], q[4]);
302 0           cm0 = w[0];
303 0           cm1 = w[1];
304 0           cm2 = w[2];
305 0           cm3 = w[3];
306 0           break;
307             }
308             }
309              
310 0           br_enc32be(ivbuf + 0, iv0);
311 0           br_enc32be(ivbuf + 4, iv1);
312 0           br_enc32be(ivbuf + 8, iv2);
313 0           br_enc32be(ivbuf + 12, iv3);
314 0           br_enc32le((unsigned char *)cbcmac + 0, cm0);
315 0           br_enc32le((unsigned char *)cbcmac + 4, cm1);
316 0           br_enc32le((unsigned char *)cbcmac + 8, cm2);
317 0           br_enc32le((unsigned char *)cbcmac + 12, cm3);
318 0           }
319              
320             /* see bearssl_block.h */
321             void
322 0           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 0           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 0           ivbuf = ctr;
340 0           iv0 = br_dec32be(ivbuf + 0);
341 0           iv1 = br_dec32be(ivbuf + 4);
342 0           iv2 = br_dec32be(ivbuf + 8);
343 0           iv3 = br_dec32be(ivbuf + 12);
344              
345             /*
346             * The current CBC-MAC value is kept in little-endian convention.
347             */
348 0           cm0 = br_dec32le((unsigned char *)cbcmac + 0);
349 0           cm1 = br_dec32le((unsigned char *)cbcmac + 4);
350 0           cm2 = br_dec32le((unsigned char *)cbcmac + 8);
351 0           cm3 = br_dec32le((unsigned char *)cbcmac + 12);
352              
353 0           buf = data;
354 0           memset(q, 0, sizeof q);
355 0 0         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 0           w[0] = br_swap32(iv0);
364 0           w[1] = br_swap32(iv1);
365 0           w[2] = br_swap32(iv2);
366 0           w[3] = br_swap32(iv3);
367 0           iv3 ++;
368 0           carry = ~(iv3 | -iv3) >> 31;
369 0           iv2 += carry;
370 0           carry &= -(~(iv2 | -iv2) >> 31);
371 0           iv1 += carry;
372 0           carry &= -(~(iv1 | -iv1) >> 31);
373 0           iv0 += carry;
374              
375             /*
376             * The block for CBC-MAC.
377             */
378 0           w[4] = cm0 ^ br_dec32le(buf + 0);
379 0           w[5] = cm1 ^ br_dec32le(buf + 4);
380 0           w[6] = cm2 ^ br_dec32le(buf + 8);
381 0           w[7] = cm3 ^ br_dec32le(buf + 12);
382              
383 0           br_aes_ct64_interleave_in(&q[0], &q[4], w);
384 0           br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
385 0           br_aes_ct64_ortho(q);
386 0           br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
387 0           br_aes_ct64_ortho(q);
388 0           br_aes_ct64_interleave_out(w, q[0], q[4]);
389 0           br_aes_ct64_interleave_out(w + 4, q[1], q[5]);
390              
391 0           br_enc32le(tmp + 0, w[0]);
392 0           br_enc32le(tmp + 4, w[1]);
393 0           br_enc32le(tmp + 8, w[2]);
394 0           br_enc32le(tmp + 12, w[3]);
395 0           xorbuf(buf, tmp, 16);
396 0           cm0 = w[4];
397 0           cm1 = w[5];
398 0           cm2 = w[6];
399 0           cm3 = w[7];
400 0           buf += 16;
401 0           len -= 16;
402             }
403              
404 0           br_enc32be(ivbuf + 0, iv0);
405 0           br_enc32be(ivbuf + 4, iv1);
406 0           br_enc32be(ivbuf + 8, iv2);
407 0           br_enc32be(ivbuf + 12, iv3);
408 0           br_enc32le((unsigned char *)cbcmac + 0, cm0);
409 0           br_enc32le((unsigned char *)cbcmac + 4, cm1);
410 0           br_enc32le((unsigned char *)cbcmac + 8, cm2);
411 0           br_enc32le((unsigned char *)cbcmac + 12, cm3);
412 0           }
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             };