/src/BearSSL/src/symcipher/aes_ct_enc.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 | | static inline void |
28 | | add_round_key(uint32_t *q, const uint32_t *sk) |
29 | 346k | { |
30 | 346k | q[0] ^= sk[0]; |
31 | 346k | q[1] ^= sk[1]; |
32 | 346k | q[2] ^= sk[2]; |
33 | 346k | q[3] ^= sk[3]; |
34 | 346k | q[4] ^= sk[4]; |
35 | 346k | q[5] ^= sk[5]; |
36 | 346k | q[6] ^= sk[6]; |
37 | 346k | q[7] ^= sk[7]; |
38 | 346k | } |
39 | | |
40 | | static inline void |
41 | | shift_rows(uint32_t *q) |
42 | 318k | { |
43 | 318k | int i; |
44 | | |
45 | 2.86M | for (i = 0; i < 8; i ++) { |
46 | 2.54M | uint32_t x; |
47 | | |
48 | 2.54M | x = q[i]; |
49 | 2.54M | q[i] = (x & 0x000000FF) |
50 | 2.54M | | ((x & 0x0000FC00) >> 2) | ((x & 0x00000300) << 6) |
51 | 2.54M | | ((x & 0x00F00000) >> 4) | ((x & 0x000F0000) << 4) |
52 | 2.54M | | ((x & 0xC0000000) >> 6) | ((x & 0x3F000000) << 2); |
53 | 2.54M | } |
54 | 318k | } |
55 | | |
56 | | static inline uint32_t |
57 | | rotr16(uint32_t x) |
58 | 2.32M | { |
59 | 2.32M | return (x << 16) | (x >> 16); |
60 | 2.32M | } |
61 | | |
62 | | static inline void |
63 | | mix_columns(uint32_t *q) |
64 | 290k | { |
65 | 290k | uint32_t q0, q1, q2, q3, q4, q5, q6, q7; |
66 | 290k | uint32_t r0, r1, r2, r3, r4, r5, r6, r7; |
67 | | |
68 | 290k | q0 = q[0]; |
69 | 290k | q1 = q[1]; |
70 | 290k | q2 = q[2]; |
71 | 290k | q3 = q[3]; |
72 | 290k | q4 = q[4]; |
73 | 290k | q5 = q[5]; |
74 | 290k | q6 = q[6]; |
75 | 290k | q7 = q[7]; |
76 | 290k | r0 = (q0 >> 8) | (q0 << 24); |
77 | 290k | r1 = (q1 >> 8) | (q1 << 24); |
78 | 290k | r2 = (q2 >> 8) | (q2 << 24); |
79 | 290k | r3 = (q3 >> 8) | (q3 << 24); |
80 | 290k | r4 = (q4 >> 8) | (q4 << 24); |
81 | 290k | r5 = (q5 >> 8) | (q5 << 24); |
82 | 290k | r6 = (q6 >> 8) | (q6 << 24); |
83 | 290k | r7 = (q7 >> 8) | (q7 << 24); |
84 | | |
85 | 290k | q[0] = q7 ^ r7 ^ r0 ^ rotr16(q0 ^ r0); |
86 | 290k | q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr16(q1 ^ r1); |
87 | 290k | q[2] = q1 ^ r1 ^ r2 ^ rotr16(q2 ^ r2); |
88 | 290k | q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr16(q3 ^ r3); |
89 | 290k | q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr16(q4 ^ r4); |
90 | 290k | q[5] = q4 ^ r4 ^ r5 ^ rotr16(q5 ^ r5); |
91 | 290k | q[6] = q5 ^ r5 ^ r6 ^ rotr16(q6 ^ r6); |
92 | 290k | q[7] = q6 ^ r6 ^ r7 ^ rotr16(q7 ^ r7); |
93 | 290k | } |
94 | | |
95 | | /* see inner.h */ |
96 | | void |
97 | | br_aes_ct_bitslice_encrypt(unsigned num_rounds, |
98 | | const uint32_t *skey, uint32_t *q) |
99 | 28.4k | { |
100 | 28.4k | unsigned u; |
101 | | |
102 | 28.4k | add_round_key(q, skey); |
103 | 318k | for (u = 1; u < num_rounds; u ++) { |
104 | 290k | br_aes_ct_bitslice_Sbox(q); |
105 | 290k | shift_rows(q); |
106 | 290k | mix_columns(q); |
107 | 290k | add_round_key(q, skey + (u << 3)); |
108 | 290k | } |
109 | 28.4k | br_aes_ct_bitslice_Sbox(q); |
110 | 28.4k | shift_rows(q); |
111 | 28.4k | add_round_key(q, skey + (num_rounds << 3)); |
112 | 28.4k | } |