/src/BearSSL/src/symcipher/aes_ct_ctr.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2016 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_ct_ctr_init(br_aes_ct_ctr_keys *ctx, |
30 | | const void *key, size_t len) |
31 | 2.54k | { |
32 | 2.54k | ctx->vtable = &br_aes_ct_ctr_vtable; |
33 | 2.54k | ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); |
34 | 2.54k | } |
35 | | |
36 | | static void |
37 | | xorbuf(void *dst, const void *src, size_t len) |
38 | 28.0k | { |
39 | 28.0k | unsigned char *d; |
40 | 28.0k | const unsigned char *s; |
41 | | |
42 | 28.0k | d = dst; |
43 | 28.0k | s = src; |
44 | 818k | while (len -- > 0) { |
45 | 790k | *d ++ ^= *s ++; |
46 | 790k | } |
47 | 28.0k | } |
48 | | |
49 | | /* see bearssl_block.h */ |
50 | | uint32_t |
51 | | br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, |
52 | | const void *iv, uint32_t cc, void *data, size_t len) |
53 | 24.2k | { |
54 | 24.2k | unsigned char *buf; |
55 | 24.2k | const unsigned char *ivbuf; |
56 | 24.2k | uint32_t iv0, iv1, iv2; |
57 | 24.2k | uint32_t sk_exp[120]; |
58 | | |
59 | 24.2k | br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); |
60 | 24.2k | ivbuf = iv; |
61 | 24.2k | iv0 = br_dec32le(ivbuf); |
62 | 24.2k | iv1 = br_dec32le(ivbuf + 4); |
63 | 24.2k | iv2 = br_dec32le(ivbuf + 8); |
64 | 24.2k | buf = data; |
65 | 45.0k | while (len > 0) { |
66 | 28.0k | uint32_t q[8]; |
67 | 28.0k | unsigned char tmp[32]; |
68 | | |
69 | | /* |
70 | | * TODO: see if we can save on the first br_aes_ct_ortho() |
71 | | * call, since iv0/iv1/iv2 are constant for the whole run. |
72 | | */ |
73 | 28.0k | q[0] = q[1] = iv0; |
74 | 28.0k | q[2] = q[3] = iv1; |
75 | 28.0k | q[4] = q[5] = iv2; |
76 | 28.0k | q[6] = br_swap32(cc); |
77 | 28.0k | q[7] = br_swap32(cc + 1); |
78 | 28.0k | br_aes_ct_ortho(q); |
79 | 28.0k | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
80 | 28.0k | br_aes_ct_ortho(q); |
81 | 28.0k | br_enc32le(tmp, q[0]); |
82 | 28.0k | br_enc32le(tmp + 4, q[2]); |
83 | 28.0k | br_enc32le(tmp + 8, q[4]); |
84 | 28.0k | br_enc32le(tmp + 12, q[6]); |
85 | 28.0k | br_enc32le(tmp + 16, q[1]); |
86 | 28.0k | br_enc32le(tmp + 20, q[3]); |
87 | 28.0k | br_enc32le(tmp + 24, q[5]); |
88 | 28.0k | br_enc32le(tmp + 28, q[7]); |
89 | | |
90 | 28.0k | if (len <= 32) { |
91 | 7.29k | xorbuf(buf, tmp, len); |
92 | 7.29k | cc ++; |
93 | 7.29k | if (len > 16) { |
94 | 618 | cc ++; |
95 | 618 | } |
96 | 7.29k | break; |
97 | 7.29k | } |
98 | 20.7k | xorbuf(buf, tmp, 32); |
99 | 20.7k | buf += 32; |
100 | 20.7k | len -= 32; |
101 | 20.7k | cc += 2; |
102 | 20.7k | } |
103 | 24.2k | return cc; |
104 | 24.2k | } |
105 | | |
106 | | /* see bearssl_block.h */ |
107 | | const br_block_ctr_class br_aes_ct_ctr_vtable = { |
108 | | sizeof(br_aes_ct_ctr_keys), |
109 | | 16, |
110 | | 4, |
111 | | (void (*)(const br_block_ctr_class **, const void *, size_t)) |
112 | | &br_aes_ct_ctr_init, |
113 | | (uint32_t (*)(const br_block_ctr_class *const *, |
114 | | const void *, uint32_t, void *, size_t)) |
115 | | &br_aes_ct_ctr_run |
116 | | }; |