/src/BearSSL/src/symcipher/aes_ct_ctrcbc.c
Line | Count | Source |
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_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, |
30 | | const void *key, size_t len) |
31 | 293 | { |
32 | 293 | ctx->vtable = &br_aes_ct_ctrcbc_vtable; |
33 | 293 | ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); |
34 | 293 | } |
35 | | |
36 | | static void |
37 | | xorbuf(void *dst, const void *src, size_t len) |
38 | 1.33k | { |
39 | 1.33k | unsigned char *d; |
40 | 1.33k | const unsigned char *s; |
41 | | |
42 | 1.33k | d = dst; |
43 | 1.33k | s = src; |
44 | 22.6k | while (len -- > 0) { |
45 | 21.3k | *d ++ ^= *s ++; |
46 | 21.3k | } |
47 | 1.33k | } |
48 | | |
49 | | /* see bearssl_block.h */ |
50 | | void |
51 | | br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, |
52 | | void *ctr, void *data, size_t len) |
53 | 829 | { |
54 | 829 | unsigned char *buf; |
55 | 829 | unsigned char *ivbuf; |
56 | 829 | uint32_t iv0, iv1, iv2, iv3; |
57 | 829 | uint32_t sk_exp[120]; |
58 | | |
59 | 829 | br_aes_ct_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 | 829 | ivbuf = ctr; |
67 | 829 | iv0 = br_dec32be(ivbuf + 0); |
68 | 829 | iv1 = br_dec32be(ivbuf + 4); |
69 | 829 | iv2 = br_dec32be(ivbuf + 8); |
70 | 829 | iv3 = br_dec32be(ivbuf + 12); |
71 | | |
72 | 829 | buf = data; |
73 | 829 | while (len > 0) { |
74 | 829 | uint32_t q[8], carry; |
75 | 829 | unsigned char tmp[32]; |
76 | | |
77 | | /* |
78 | | * The bitslice implementation expects values in |
79 | | * little-endian convention, so we have to byteswap them. |
80 | | */ |
81 | 829 | q[0] = br_swap32(iv0); |
82 | 829 | q[2] = br_swap32(iv1); |
83 | 829 | q[4] = br_swap32(iv2); |
84 | 829 | q[6] = br_swap32(iv3); |
85 | 829 | iv3 ++; |
86 | 829 | carry = ~(iv3 | -iv3) >> 31; |
87 | 829 | iv2 += carry; |
88 | 829 | carry &= -(~(iv2 | -iv2) >> 31); |
89 | 829 | iv1 += carry; |
90 | 829 | carry &= -(~(iv1 | -iv1) >> 31); |
91 | 829 | iv0 += carry; |
92 | 829 | q[1] = br_swap32(iv0); |
93 | 829 | q[3] = br_swap32(iv1); |
94 | 829 | q[5] = br_swap32(iv2); |
95 | 829 | q[7] = br_swap32(iv3); |
96 | 829 | if (len > 16) { |
97 | 0 | iv3 ++; |
98 | 0 | carry = ~(iv3 | -iv3) >> 31; |
99 | 0 | iv2 += carry; |
100 | 0 | carry &= -(~(iv2 | -iv2) >> 31); |
101 | 0 | iv1 += carry; |
102 | 0 | carry &= -(~(iv1 | -iv1) >> 31); |
103 | 0 | iv0 += carry; |
104 | 0 | } |
105 | | |
106 | 829 | br_aes_ct_ortho(q); |
107 | 829 | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
108 | 829 | br_aes_ct_ortho(q); |
109 | | |
110 | 829 | br_enc32le(tmp, q[0]); |
111 | 829 | br_enc32le(tmp + 4, q[2]); |
112 | 829 | br_enc32le(tmp + 8, q[4]); |
113 | 829 | br_enc32le(tmp + 12, q[6]); |
114 | 829 | br_enc32le(tmp + 16, q[1]); |
115 | 829 | br_enc32le(tmp + 20, q[3]); |
116 | 829 | br_enc32le(tmp + 24, q[5]); |
117 | 829 | br_enc32le(tmp + 28, q[7]); |
118 | | |
119 | 829 | if (len <= 32) { |
120 | 829 | xorbuf(buf, tmp, len); |
121 | 829 | break; |
122 | 829 | } |
123 | 0 | xorbuf(buf, tmp, 32); |
124 | 0 | buf += 32; |
125 | 0 | len -= 32; |
126 | 0 | } |
127 | 829 | br_enc32be(ivbuf + 0, iv0); |
128 | 829 | br_enc32be(ivbuf + 4, iv1); |
129 | 829 | br_enc32be(ivbuf + 8, iv2); |
130 | 829 | br_enc32be(ivbuf + 12, iv3); |
131 | 829 | } |
132 | | |
133 | | /* see bearssl_block.h */ |
134 | | void |
135 | | br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, |
136 | | void *cbcmac, const void *data, size_t len) |
137 | 1.17k | { |
138 | 1.17k | const unsigned char *buf; |
139 | 1.17k | uint32_t cm0, cm1, cm2, cm3; |
140 | 1.17k | uint32_t q[8]; |
141 | 1.17k | uint32_t sk_exp[120]; |
142 | | |
143 | 1.17k | br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); |
144 | | |
145 | 1.17k | buf = data; |
146 | 1.17k | cm0 = br_dec32le((unsigned char *)cbcmac + 0); |
147 | 1.17k | cm1 = br_dec32le((unsigned char *)cbcmac + 4); |
148 | 1.17k | cm2 = br_dec32le((unsigned char *)cbcmac + 8); |
149 | 1.17k | cm3 = br_dec32le((unsigned char *)cbcmac + 12); |
150 | 1.17k | q[1] = 0; |
151 | 1.17k | q[3] = 0; |
152 | 1.17k | q[5] = 0; |
153 | 1.17k | q[7] = 0; |
154 | | |
155 | 2.33k | while (len > 0) { |
156 | 1.16k | q[0] = cm0 ^ br_dec32le(buf + 0); |
157 | 1.16k | q[2] = cm1 ^ br_dec32le(buf + 4); |
158 | 1.16k | q[4] = cm2 ^ br_dec32le(buf + 8); |
159 | 1.16k | q[6] = cm3 ^ br_dec32le(buf + 12); |
160 | | |
161 | 1.16k | br_aes_ct_ortho(q); |
162 | 1.16k | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
163 | 1.16k | br_aes_ct_ortho(q); |
164 | | |
165 | 1.16k | cm0 = q[0]; |
166 | 1.16k | cm1 = q[2]; |
167 | 1.16k | cm2 = q[4]; |
168 | 1.16k | cm3 = q[6]; |
169 | 1.16k | buf += 16; |
170 | 1.16k | len -= 16; |
171 | 1.16k | } |
172 | | |
173 | 1.17k | br_enc32le((unsigned char *)cbcmac + 0, cm0); |
174 | 1.17k | br_enc32le((unsigned char *)cbcmac + 4, cm1); |
175 | 1.17k | br_enc32le((unsigned char *)cbcmac + 8, cm2); |
176 | 1.17k | br_enc32le((unsigned char *)cbcmac + 12, cm3); |
177 | 1.17k | } |
178 | | |
179 | | /* see bearssl_block.h */ |
180 | | void |
181 | | br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, |
182 | | void *ctr, void *cbcmac, void *data, size_t len) |
183 | 713 | { |
184 | | /* |
185 | | * When encrypting, the CBC-MAC processing must be lagging by |
186 | | * one block, since it operates on the encrypted values, so |
187 | | * it must wait for that encryption to complete. |
188 | | */ |
189 | | |
190 | 713 | unsigned char *buf; |
191 | 713 | unsigned char *ivbuf; |
192 | 713 | uint32_t iv0, iv1, iv2, iv3; |
193 | 713 | uint32_t cm0, cm1, cm2, cm3; |
194 | 713 | uint32_t sk_exp[120]; |
195 | 713 | int first_iter; |
196 | | |
197 | 713 | br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); |
198 | | |
199 | | /* |
200 | | * We keep the counter as four 32-bit values, with big-endian |
201 | | * convention, because that's what is expected for purposes of |
202 | | * incrementing the counter value. |
203 | | */ |
204 | 713 | ivbuf = ctr; |
205 | 713 | iv0 = br_dec32be(ivbuf + 0); |
206 | 713 | iv1 = br_dec32be(ivbuf + 4); |
207 | 713 | iv2 = br_dec32be(ivbuf + 8); |
208 | 713 | iv3 = br_dec32be(ivbuf + 12); |
209 | | |
210 | | /* |
211 | | * The current CBC-MAC value is kept in little-endian convention. |
212 | | */ |
213 | 713 | cm0 = br_dec32le((unsigned char *)cbcmac + 0); |
214 | 713 | cm1 = br_dec32le((unsigned char *)cbcmac + 4); |
215 | 713 | cm2 = br_dec32le((unsigned char *)cbcmac + 8); |
216 | 713 | cm3 = br_dec32le((unsigned char *)cbcmac + 12); |
217 | | |
218 | 713 | buf = data; |
219 | 713 | first_iter = 1; |
220 | 1.67k | while (len > 0) { |
221 | 1.25k | uint32_t q[8], carry; |
222 | | |
223 | | /* |
224 | | * The bitslice implementation expects values in |
225 | | * little-endian convention, so we have to byteswap them. |
226 | | */ |
227 | 1.25k | q[0] = br_swap32(iv0); |
228 | 1.25k | q[2] = br_swap32(iv1); |
229 | 1.25k | q[4] = br_swap32(iv2); |
230 | 1.25k | q[6] = br_swap32(iv3); |
231 | 1.25k | iv3 ++; |
232 | 1.25k | carry = ~(iv3 | -iv3) >> 31; |
233 | 1.25k | iv2 += carry; |
234 | 1.25k | carry &= -(~(iv2 | -iv2) >> 31); |
235 | 1.25k | iv1 += carry; |
236 | 1.25k | carry &= -(~(iv1 | -iv1) >> 31); |
237 | 1.25k | iv0 += carry; |
238 | | |
239 | | /* |
240 | | * The odd values are used for CBC-MAC. |
241 | | */ |
242 | 1.25k | q[1] = cm0; |
243 | 1.25k | q[3] = cm1; |
244 | 1.25k | q[5] = cm2; |
245 | 1.25k | q[7] = cm3; |
246 | | |
247 | 1.25k | br_aes_ct_ortho(q); |
248 | 1.25k | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
249 | 1.25k | br_aes_ct_ortho(q); |
250 | | |
251 | | /* |
252 | | * We do the XOR with the plaintext in 32-bit registers, |
253 | | * so that the value are available for CBC-MAC processing |
254 | | * as well. |
255 | | */ |
256 | 1.25k | q[0] ^= br_dec32le(buf + 0); |
257 | 1.25k | q[2] ^= br_dec32le(buf + 4); |
258 | 1.25k | q[4] ^= br_dec32le(buf + 8); |
259 | 1.25k | q[6] ^= br_dec32le(buf + 12); |
260 | 1.25k | br_enc32le(buf + 0, q[0]); |
261 | 1.25k | br_enc32le(buf + 4, q[2]); |
262 | 1.25k | br_enc32le(buf + 8, q[4]); |
263 | 1.25k | br_enc32le(buf + 12, q[6]); |
264 | | |
265 | 1.25k | buf += 16; |
266 | 1.25k | len -= 16; |
267 | | |
268 | | /* |
269 | | * We set the cm* values to the block to encrypt in the |
270 | | * next iteration. |
271 | | */ |
272 | 1.25k | if (first_iter) { |
273 | 297 | first_iter = 0; |
274 | 297 | cm0 ^= q[0]; |
275 | 297 | cm1 ^= q[2]; |
276 | 297 | cm2 ^= q[4]; |
277 | 297 | cm3 ^= q[6]; |
278 | 962 | } else { |
279 | 962 | cm0 = q[0] ^ q[1]; |
280 | 962 | cm1 = q[2] ^ q[3]; |
281 | 962 | cm2 = q[4] ^ q[5]; |
282 | 962 | cm3 = q[6] ^ q[7]; |
283 | 962 | } |
284 | | |
285 | | /* |
286 | | * If this was the last iteration, then compute the |
287 | | * extra block encryption to complete CBC-MAC. |
288 | | */ |
289 | 1.25k | if (len == 0) { |
290 | 297 | q[0] = cm0; |
291 | 297 | q[2] = cm1; |
292 | 297 | q[4] = cm2; |
293 | 297 | q[6] = cm3; |
294 | 297 | br_aes_ct_ortho(q); |
295 | 297 | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
296 | 297 | br_aes_ct_ortho(q); |
297 | 297 | cm0 = q[0]; |
298 | 297 | cm1 = q[2]; |
299 | 297 | cm2 = q[4]; |
300 | 297 | cm3 = q[6]; |
301 | 297 | break; |
302 | 297 | } |
303 | 1.25k | } |
304 | | |
305 | 713 | br_enc32be(ivbuf + 0, iv0); |
306 | 713 | br_enc32be(ivbuf + 4, iv1); |
307 | 713 | br_enc32be(ivbuf + 8, iv2); |
308 | 713 | br_enc32be(ivbuf + 12, iv3); |
309 | 713 | br_enc32le((unsigned char *)cbcmac + 0, cm0); |
310 | 713 | br_enc32le((unsigned char *)cbcmac + 4, cm1); |
311 | 713 | br_enc32le((unsigned char *)cbcmac + 8, cm2); |
312 | 713 | br_enc32le((unsigned char *)cbcmac + 12, cm3); |
313 | 713 | } |
314 | | |
315 | | /* see bearssl_block.h */ |
316 | | void |
317 | | br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, |
318 | | void *ctr, void *cbcmac, void *data, size_t len) |
319 | 471 | { |
320 | 471 | unsigned char *buf; |
321 | 471 | unsigned char *ivbuf; |
322 | 471 | uint32_t iv0, iv1, iv2, iv3; |
323 | 471 | uint32_t cm0, cm1, cm2, cm3; |
324 | 471 | uint32_t sk_exp[120]; |
325 | | |
326 | 471 | br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); |
327 | | |
328 | | /* |
329 | | * We keep the counter as four 32-bit values, with big-endian |
330 | | * convention, because that's what is expected for purposes of |
331 | | * incrementing the counter value. |
332 | | */ |
333 | 471 | ivbuf = ctr; |
334 | 471 | iv0 = br_dec32be(ivbuf + 0); |
335 | 471 | iv1 = br_dec32be(ivbuf + 4); |
336 | 471 | iv2 = br_dec32be(ivbuf + 8); |
337 | 471 | iv3 = br_dec32be(ivbuf + 12); |
338 | | |
339 | | /* |
340 | | * The current CBC-MAC value is kept in little-endian convention. |
341 | | */ |
342 | 471 | cm0 = br_dec32le((unsigned char *)cbcmac + 0); |
343 | 471 | cm1 = br_dec32le((unsigned char *)cbcmac + 4); |
344 | 471 | cm2 = br_dec32le((unsigned char *)cbcmac + 8); |
345 | 471 | cm3 = br_dec32le((unsigned char *)cbcmac + 12); |
346 | | |
347 | 471 | buf = data; |
348 | 974 | while (len > 0) { |
349 | 503 | uint32_t q[8], carry; |
350 | 503 | unsigned char tmp[16]; |
351 | | |
352 | | /* |
353 | | * The bitslice implementation expects values in |
354 | | * little-endian convention, so we have to byteswap them. |
355 | | */ |
356 | 503 | q[0] = br_swap32(iv0); |
357 | 503 | q[2] = br_swap32(iv1); |
358 | 503 | q[4] = br_swap32(iv2); |
359 | 503 | q[6] = br_swap32(iv3); |
360 | 503 | iv3 ++; |
361 | 503 | carry = ~(iv3 | -iv3) >> 31; |
362 | 503 | iv2 += carry; |
363 | 503 | carry &= -(~(iv2 | -iv2) >> 31); |
364 | 503 | iv1 += carry; |
365 | 503 | carry &= -(~(iv1 | -iv1) >> 31); |
366 | 503 | iv0 += carry; |
367 | | |
368 | | /* |
369 | | * The odd values are used for CBC-MAC. |
370 | | */ |
371 | 503 | q[1] = cm0 ^ br_dec32le(buf + 0); |
372 | 503 | q[3] = cm1 ^ br_dec32le(buf + 4); |
373 | 503 | q[5] = cm2 ^ br_dec32le(buf + 8); |
374 | 503 | q[7] = cm3 ^ br_dec32le(buf + 12); |
375 | | |
376 | 503 | br_aes_ct_ortho(q); |
377 | 503 | br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); |
378 | 503 | br_aes_ct_ortho(q); |
379 | | |
380 | 503 | br_enc32le(tmp + 0, q[0]); |
381 | 503 | br_enc32le(tmp + 4, q[2]); |
382 | 503 | br_enc32le(tmp + 8, q[4]); |
383 | 503 | br_enc32le(tmp + 12, q[6]); |
384 | 503 | xorbuf(buf, tmp, 16); |
385 | 503 | cm0 = q[1]; |
386 | 503 | cm1 = q[3]; |
387 | 503 | cm2 = q[5]; |
388 | 503 | cm3 = q[7]; |
389 | 503 | buf += 16; |
390 | 503 | len -= 16; |
391 | 503 | } |
392 | | |
393 | 471 | br_enc32be(ivbuf + 0, iv0); |
394 | 471 | br_enc32be(ivbuf + 4, iv1); |
395 | 471 | br_enc32be(ivbuf + 8, iv2); |
396 | 471 | br_enc32be(ivbuf + 12, iv3); |
397 | 471 | br_enc32le((unsigned char *)cbcmac + 0, cm0); |
398 | 471 | br_enc32le((unsigned char *)cbcmac + 4, cm1); |
399 | 471 | br_enc32le((unsigned char *)cbcmac + 8, cm2); |
400 | 471 | br_enc32le((unsigned char *)cbcmac + 12, cm3); |
401 | 471 | } |
402 | | |
403 | | /* see bearssl_block.h */ |
404 | | const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable = { |
405 | | sizeof(br_aes_ct_ctrcbc_keys), |
406 | | 16, |
407 | | 4, |
408 | | (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) |
409 | | &br_aes_ct_ctrcbc_init, |
410 | | (void (*)(const br_block_ctrcbc_class *const *, |
411 | | void *, void *, void *, size_t)) |
412 | | &br_aes_ct_ctrcbc_encrypt, |
413 | | (void (*)(const br_block_ctrcbc_class *const *, |
414 | | void *, void *, void *, size_t)) |
415 | | &br_aes_ct_ctrcbc_decrypt, |
416 | | (void (*)(const br_block_ctrcbc_class *const *, |
417 | | void *, void *, size_t)) |
418 | | &br_aes_ct_ctrcbc_ctr, |
419 | | (void (*)(const br_block_ctrcbc_class *const *, |
420 | | void *, const void *, size_t)) |
421 | | &br_aes_ct_ctrcbc_mac |
422 | | }; |