Coverage Report

Created: 2024-06-28 06:08

/src/BearSSL/src/symcipher/aes_ct64_ctrcbc.c
Line
Count
Source (jump to first uncovered line)
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
743
{
32
743
  ctx->vtable = &br_aes_ct64_ctrcbc_vtable;
33
743
  ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len);
34
743
}
35
36
static void
37
xorbuf(void *dst, const void *src, size_t len)
38
3.86k
{
39
3.86k
  unsigned char *d;
40
3.86k
  const unsigned char *s;
41
42
3.86k
  d = dst;
43
3.86k
  s = src;
44
65.7k
  while (len -- > 0) {
45
61.8k
    *d ++ ^= *s ++;
46
61.8k
  }
47
3.86k
}
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
1.69k
{
54
1.69k
  unsigned char *buf;
55
1.69k
  unsigned char *ivbuf;
56
1.69k
  uint32_t iv0, iv1, iv2, iv3;
57
1.69k
  uint64_t sk_exp[120];
58
59
1.69k
  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
1.69k
  ivbuf = ctr;
67
1.69k
  iv0 = br_dec32be(ivbuf +  0);
68
1.69k
  iv1 = br_dec32be(ivbuf +  4);
69
1.69k
  iv2 = br_dec32be(ivbuf +  8);
70
1.69k
  iv3 = br_dec32be(ivbuf + 12);
71
72
1.69k
  buf = data;
73
1.69k
  while (len > 0) {
74
1.69k
    uint64_t q[8];
75
1.69k
    uint32_t w[16];
76
1.69k
    unsigned char tmp[64];
77
1.69k
    int i, j;
78
79
    /*
80
     * The bitslice implementation expects values in
81
     * little-endian convention, so we have to byteswap them.
82
     */
83
1.69k
    j = (len >= 64) ? 16 : (int)(len >> 2);
84
3.39k
    for (i = 0; i < j; i += 4) {
85
1.69k
      uint32_t carry;
86
87
1.69k
      w[i + 0] = br_swap32(iv0);
88
1.69k
      w[i + 1] = br_swap32(iv1);
89
1.69k
      w[i + 2] = br_swap32(iv2);
90
1.69k
      w[i + 3] = br_swap32(iv3);
91
1.69k
      iv3 ++;
92
1.69k
      carry = ~(iv3 | -iv3) >> 31;
93
1.69k
      iv2 += carry;
94
1.69k
      carry &= -(~(iv2 | -iv2) >> 31);
95
1.69k
      iv1 += carry;
96
1.69k
      carry &= -(~(iv1 | -iv1) >> 31);
97
1.69k
      iv0 += carry;
98
1.69k
    }
99
1.69k
    memset(w + i, 0, (16 - i) * sizeof(uint32_t));
100
101
8.49k
    for (i = 0; i < 4; i ++) {
102
6.79k
      br_aes_ct64_interleave_in(
103
6.79k
        &q[i], &q[i + 4], w + (i << 2));
104
6.79k
    }
105
1.69k
    br_aes_ct64_ortho(q);
106
1.69k
    br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
107
1.69k
    br_aes_ct64_ortho(q);
108
8.49k
    for (i = 0; i < 4; i ++) {
109
6.79k
      br_aes_ct64_interleave_out(
110
6.79k
        w + (i << 2), q[i], q[i + 4]);
111
6.79k
    }
112
113
1.69k
    br_range_enc32le(tmp, w, 16);
114
1.69k
    if (len <= 64) {
115
1.69k
      xorbuf(buf, tmp, len);
116
1.69k
      break;
117
1.69k
    }
118
0
    xorbuf(buf, tmp, 64);
119
0
    buf += 64;
120
0
    len -= 64;
121
0
  }
122
1.69k
  br_enc32be(ivbuf +  0, iv0);
123
1.69k
  br_enc32be(ivbuf +  4, iv1);
124
1.69k
  br_enc32be(ivbuf +  8, iv2);
125
1.69k
  br_enc32be(ivbuf + 12, iv3);
126
1.69k
}
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
2.25k
{
133
2.25k
  const unsigned char *buf;
134
2.25k
  uint32_t cm0, cm1, cm2, cm3;
135
2.25k
  uint64_t q[8];
136
2.25k
  uint64_t sk_exp[120];
137
138
2.25k
  br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
139
140
2.25k
  cm0 = br_dec32le((unsigned char *)cbcmac +  0);
141
2.25k
  cm1 = br_dec32le((unsigned char *)cbcmac +  4);
142
2.25k
  cm2 = br_dec32le((unsigned char *)cbcmac +  8);
143
2.25k
  cm3 = br_dec32le((unsigned char *)cbcmac + 12);
144
145
2.25k
  buf = data;
146
2.25k
  memset(q, 0, sizeof q);
147
4.31k
  while (len > 0) {
148
2.06k
    uint32_t w[4];
149
150
2.06k
    w[0] = cm0 ^ br_dec32le(buf +  0);
151
2.06k
    w[1] = cm1 ^ br_dec32le(buf +  4);
152
2.06k
    w[2] = cm2 ^ br_dec32le(buf +  8);
153
2.06k
    w[3] = cm3 ^ br_dec32le(buf + 12);
154
155
2.06k
    br_aes_ct64_interleave_in(&q[0], &q[4], w);
156
2.06k
    br_aes_ct64_ortho(q);
157
2.06k
    br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
158
2.06k
    br_aes_ct64_ortho(q);
159
2.06k
    br_aes_ct64_interleave_out(w, q[0], q[4]);
160
161
2.06k
    cm0 = w[0];
162
2.06k
    cm1 = w[1];
163
2.06k
    cm2 = w[2];
164
2.06k
    cm3 = w[3];
165
2.06k
    buf += 16;
166
2.06k
    len -= 16;
167
2.06k
  }
168
169
2.25k
  br_enc32le((unsigned char *)cbcmac +  0, cm0);
170
2.25k
  br_enc32le((unsigned char *)cbcmac +  4, cm1);
171
2.25k
  br_enc32le((unsigned char *)cbcmac +  8, cm2);
172
2.25k
  br_enc32le((unsigned char *)cbcmac + 12, cm3);
173
2.25k
}
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
3.75k
{
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
3.75k
  unsigned char *buf;
187
3.75k
  unsigned char *ivbuf;
188
3.75k
  uint32_t iv0, iv1, iv2, iv3;
189
3.75k
  uint32_t cm0, cm1, cm2, cm3;
190
3.75k
  uint64_t sk_exp[120];
191
3.75k
  uint64_t q[8];
192
3.75k
  int first_iter;
193
194
3.75k
  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
3.75k
  ivbuf = ctr;
202
3.75k
  iv0 = br_dec32be(ivbuf +  0);
203
3.75k
  iv1 = br_dec32be(ivbuf +  4);
204
3.75k
  iv2 = br_dec32be(ivbuf +  8);
205
3.75k
  iv3 = br_dec32be(ivbuf + 12);
206
207
  /*
208
   * The current CBC-MAC value is kept in little-endian convention.
209
   */
210
3.75k
  cm0 = br_dec32le((unsigned char *)cbcmac +  0);
211
3.75k
  cm1 = br_dec32le((unsigned char *)cbcmac +  4);
212
3.75k
  cm2 = br_dec32le((unsigned char *)cbcmac +  8);
213
3.75k
  cm3 = br_dec32le((unsigned char *)cbcmac + 12);
214
215
3.75k
  buf = data;
216
3.75k
  first_iter = 1;
217
3.75k
  memset(q, 0, sizeof q);
218
8.17k
  while (len > 0) {
219
5.03k
    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
5.03k
    w[0] = br_swap32(iv0);
226
5.03k
    w[1] = br_swap32(iv1);
227
5.03k
    w[2] = br_swap32(iv2);
228
5.03k
    w[3] = br_swap32(iv3);
229
5.03k
    iv3 ++;
230
5.03k
    carry = ~(iv3 | -iv3) >> 31;
231
5.03k
    iv2 += carry;
232
5.03k
    carry &= -(~(iv2 | -iv2) >> 31);
233
5.03k
    iv1 += carry;
234
5.03k
    carry &= -(~(iv1 | -iv1) >> 31);
235
5.03k
    iv0 += carry;
236
237
    /*
238
     * The block for CBC-MAC.
239
     */
240
5.03k
    w[4] = cm0;
241
5.03k
    w[5] = cm1;
242
5.03k
    w[6] = cm2;
243
5.03k
    w[7] = cm3;
244
245
5.03k
    br_aes_ct64_interleave_in(&q[0], &q[4], w);
246
5.03k
    br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
247
5.03k
    br_aes_ct64_ortho(q);
248
5.03k
    br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
249
5.03k
    br_aes_ct64_ortho(q);
250
5.03k
    br_aes_ct64_interleave_out(w, q[0], q[4]);
251
5.03k
    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
5.03k
    w[0] ^= br_dec32le(buf +  0);
259
5.03k
    w[1] ^= br_dec32le(buf +  4);
260
5.03k
    w[2] ^= br_dec32le(buf +  8);
261
5.03k
    w[3] ^= br_dec32le(buf + 12);
262
5.03k
    br_enc32le(buf +  0, w[0]);
263
5.03k
    br_enc32le(buf +  4, w[1]);
264
5.03k
    br_enc32le(buf +  8, w[2]);
265
5.03k
    br_enc32le(buf + 12, w[3]);
266
267
5.03k
    buf += 16;
268
5.03k
    len -= 16;
269
270
    /*
271
     * We set the cm* values to the block to encrypt in the
272
     * next iteration.
273
     */
274
5.03k
    if (first_iter) {
275
611
      first_iter = 0;
276
611
      cm0 ^= w[0];
277
611
      cm1 ^= w[1];
278
611
      cm2 ^= w[2];
279
611
      cm3 ^= w[3];
280
4.42k
    } else {
281
4.42k
      cm0 = w[0] ^ w[4];
282
4.42k
      cm1 = w[1] ^ w[5];
283
4.42k
      cm2 = w[2] ^ w[6];
284
4.42k
      cm3 = w[3] ^ w[7];
285
4.42k
    }
286
287
    /*
288
     * If this was the last iteration, then compute the
289
     * extra block encryption to complete CBC-MAC.
290
     */
291
5.03k
    if (len == 0) {
292
611
      w[0] = cm0;
293
611
      w[1] = cm1;
294
611
      w[2] = cm2;
295
611
      w[3] = cm3;
296
611
      br_aes_ct64_interleave_in(&q[0], &q[4], w);
297
611
      br_aes_ct64_ortho(q);
298
611
      br_aes_ct64_bitslice_encrypt(
299
611
        ctx->num_rounds, sk_exp, q);
300
611
      br_aes_ct64_ortho(q);
301
611
      br_aes_ct64_interleave_out(w, q[0], q[4]);
302
611
      cm0 = w[0];
303
611
      cm1 = w[1];
304
611
      cm2 = w[2];
305
611
      cm3 = w[3];
306
611
      break;
307
611
    }
308
5.03k
  }
309
310
3.75k
  br_enc32be(ivbuf +  0, iv0);
311
3.75k
  br_enc32be(ivbuf +  4, iv1);
312
3.75k
  br_enc32be(ivbuf +  8, iv2);
313
3.75k
  br_enc32be(ivbuf + 12, iv3);
314
3.75k
  br_enc32le((unsigned char *)cbcmac +  0, cm0);
315
3.75k
  br_enc32le((unsigned char *)cbcmac +  4, cm1);
316
3.75k
  br_enc32le((unsigned char *)cbcmac +  8, cm2);
317
3.75k
  br_enc32le((unsigned char *)cbcmac + 12, cm3);
318
3.75k
}
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
665
{
325
665
  unsigned char *buf;
326
665
  unsigned char *ivbuf;
327
665
  uint32_t iv0, iv1, iv2, iv3;
328
665
  uint32_t cm0, cm1, cm2, cm3;
329
665
  uint64_t sk_exp[120];
330
665
  uint64_t q[8];
331
332
665
  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
665
  ivbuf = ctr;
340
665
  iv0 = br_dec32be(ivbuf +  0);
341
665
  iv1 = br_dec32be(ivbuf +  4);
342
665
  iv2 = br_dec32be(ivbuf +  8);
343
665
  iv3 = br_dec32be(ivbuf + 12);
344
345
  /*
346
   * The current CBC-MAC value is kept in little-endian convention.
347
   */
348
665
  cm0 = br_dec32le((unsigned char *)cbcmac +  0);
349
665
  cm1 = br_dec32le((unsigned char *)cbcmac +  4);
350
665
  cm2 = br_dec32le((unsigned char *)cbcmac +  8);
351
665
  cm3 = br_dec32le((unsigned char *)cbcmac + 12);
352
353
665
  buf = data;
354
665
  memset(q, 0, sizeof q);
355
2.83k
  while (len > 0) {
356
2.16k
    uint32_t w[8], carry;
357
2.16k
    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
2.16k
    w[0] = br_swap32(iv0);
364
2.16k
    w[1] = br_swap32(iv1);
365
2.16k
    w[2] = br_swap32(iv2);
366
2.16k
    w[3] = br_swap32(iv3);
367
2.16k
    iv3 ++;
368
2.16k
    carry = ~(iv3 | -iv3) >> 31;
369
2.16k
    iv2 += carry;
370
2.16k
    carry &= -(~(iv2 | -iv2) >> 31);
371
2.16k
    iv1 += carry;
372
2.16k
    carry &= -(~(iv1 | -iv1) >> 31);
373
2.16k
    iv0 += carry;
374
375
    /*
376
     * The block for CBC-MAC.
377
     */
378
2.16k
    w[4] = cm0 ^ br_dec32le(buf +  0);
379
2.16k
    w[5] = cm1 ^ br_dec32le(buf +  4);
380
2.16k
    w[6] = cm2 ^ br_dec32le(buf +  8);
381
2.16k
    w[7] = cm3 ^ br_dec32le(buf + 12);
382
383
2.16k
    br_aes_ct64_interleave_in(&q[0], &q[4], w);
384
2.16k
    br_aes_ct64_interleave_in(&q[1], &q[5], w + 4);
385
2.16k
    br_aes_ct64_ortho(q);
386
2.16k
    br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q);
387
2.16k
    br_aes_ct64_ortho(q);
388
2.16k
    br_aes_ct64_interleave_out(w, q[0], q[4]);
389
2.16k
    br_aes_ct64_interleave_out(w + 4, q[1], q[5]);
390
391
2.16k
    br_enc32le(tmp +  0, w[0]);
392
2.16k
    br_enc32le(tmp +  4, w[1]);
393
2.16k
    br_enc32le(tmp +  8, w[2]);
394
2.16k
    br_enc32le(tmp + 12, w[3]);
395
2.16k
    xorbuf(buf, tmp, 16);
396
2.16k
    cm0 = w[4];
397
2.16k
    cm1 = w[5];
398
2.16k
    cm2 = w[6];
399
2.16k
    cm3 = w[7];
400
2.16k
    buf += 16;
401
2.16k
    len -= 16;
402
2.16k
  }
403
404
665
  br_enc32be(ivbuf +  0, iv0);
405
665
  br_enc32be(ivbuf +  4, iv1);
406
665
  br_enc32be(ivbuf +  8, iv2);
407
665
  br_enc32be(ivbuf + 12, iv3);
408
665
  br_enc32le((unsigned char *)cbcmac +  0, cm0);
409
665
  br_enc32le((unsigned char *)cbcmac +  4, cm1);
410
665
  br_enc32le((unsigned char *)cbcmac +  8, cm2);
411
665
  br_enc32le((unsigned char *)cbcmac + 12, cm3);
412
665
}
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
};