1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15 #include "hitls_build.h"
16 #if defined(HITLS_CRYPTO_AES) && !defined(HITLS_CRYPTO_AES_PRECALC_TABLES)
17
18 #include "securec.h"
19 #include "bsl_err_internal.h"
20 #include "crypt_utils.h"
21 #include "crypt_errno.h"
22 #include "bsl_sal.h"
23 #include "crypt_aes.h"
24 #include "crypt_aes_sbox.h"
25
26 #define BYTE_BITS 8
27
28 static const uint8_t AES_S[256] = {
29 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
30 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
31 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
32 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
33 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
34 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
35 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
36 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
37 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
38 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
39 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
40 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
41 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
42 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
43 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
44 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
45 };
46
47 #define SEARCH_SBOX(t) \
48 ((AES_S[((t) >> 24)] << 24) | (AES_S[((t) >> 16) & 0xFF] << 16) | (AES_S[((t) >> 8) & 0xFF] << 8) | \
49 (AES_S[((t) >> 0) & 0xFF] << 0))
50
51 #define SEARCH_INVSBOX(t) \
52 ((InvSubSbox(((t) >> 24)) << 24) | (InvSubSbox(((t) >> 16) & 0xFF) << 16) | (InvSubSbox(((t) >> 8) & 0xFF) << 8) | \
53 (InvSubSbox(((t) >> 0) & 0xFF) << 0))
54
SetAesKeyExpansionSbox(CRYPT_AES_Key * ctx,uint32_t keyLenBits,const uint8_t * key)55 void SetAesKeyExpansionSbox(CRYPT_AES_Key *ctx, uint32_t keyLenBits, const uint8_t *key)
56 {
57 uint32_t *ekey = ctx->key;
58 uint32_t keyLenByte = keyLenBits / (sizeof(uint32_t) * BYTE_BITS);
59 uint32_t i = 0;
60 for (i = 0; i < keyLenByte; ++i) {
61 ekey[i] = GET_UINT32_BE(key, i * sizeof(uint32_t));
62 }
63
64 for (; i < 4 * (ctx->rounds + 1); ++i) {
65 if ((i % keyLenByte) == 0) {
66 ekey[i] = ekey[i - keyLenByte] ^ SEARCH_SBOX(ROTL32(ekey[i - 1], BYTE_BITS)) ^
67 RoundConstArray(i / keyLenByte - 1);
68 } else if (keyLenByte > 6 && (i % keyLenByte) == 4) {
69 ekey[i] = ekey[i - keyLenByte] ^ SEARCH_SBOX(ekey[i - 1]);
70 } else {
71 ekey[i] = ekey[i - keyLenByte] ^ ekey[i - 1];
72 }
73 }
74 }
75
AesAddRoundKey(uint32_t * state,const uint32_t * round,int nr)76 static void AesAddRoundKey(uint32_t *state, const uint32_t *round, int nr)
77 {
78 for (int i = 0; i < 4; ++i) {
79 state[i] ^= round[4 * nr + i];
80 }
81 }
82
AesSubBytes(uint32_t * state)83 static void AesSubBytes(uint32_t *state)
84 {
85 for (int i = 0; i < 4; ++i) {
86 state[i] = SEARCH_SBOX(state[i]);
87 }
88 }
89
AesShiftRows(uint32_t * state)90 static void AesShiftRows(uint32_t *state)
91 {
92 uint32_t s[4] = {0};
93 for (int32_t i = 0; i < 4; ++i) {
94 s[i] = state[i];
95 }
96
97 state[0] = (s[0] & 0xFF000000) | (s[1] & 0xFF0000) | (s[2] & 0xFF00) | (s[3] & 0xFF);
98 state[1] = (s[1] & 0xFF000000) | (s[2] & 0xFF0000) | (s[3] & 0xFF00) | (s[0] & 0xFF);
99 state[2] = (s[2] & 0xFF000000) | (s[3] & 0xFF0000) | (s[0] & 0xFF00) | (s[1] & 0xFF);
100 state[3] = (s[3] & 0xFF000000) | (s[0] & 0xFF0000) | (s[1] & 0xFF00) | (s[2] & 0xFF);
101 }
102
AesXtime(uint8_t x)103 static uint8_t AesXtime(uint8_t x)
104 {
105 return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
106 }
107
AesXtimes(uint8_t x,int ts)108 static uint8_t AesXtimes(uint8_t x, int ts)
109 {
110 uint8_t tmpX = x;
111 int tmpTs = ts;
112 while (tmpTs-- > 0) {
113 tmpX = AesXtime(tmpX);
114 }
115
116 return tmpX;
117 }
118
AesMul(uint8_t x,uint8_t y)119 static uint8_t AesMul(uint8_t x, uint8_t y)
120 {
121 return ((((y >> 0) & 1) * AesXtimes(x, 0)) ^ (((y >> 1) & 1) * AesXtimes(x, 1)) ^
122 (((y >> 2) & 1) * AesXtimes(x, 2)) ^ (((y >> 3) & 1) * AesXtimes(x, 3)) ^ (((y >> 4) & 1) * AesXtimes(x, 4)) ^
123 (((y >> 5) & 1) * AesXtimes(x, 5)) ^ (((y >> 6) & 1) * AesXtimes(x, 6)) ^ (((y >> 7) & 1) * AesXtimes(x, 7)));
124 }
125
AesMixColumns(uint32_t * state,bool isMixColumns)126 static void AesMixColumns(uint32_t *state, bool isMixColumns)
127 {
128 uint8_t ts[16] = {0};
129 for (int32_t i = 0; i < 4; ++i) {
130 PUT_UINT32_BE(state[i], ts, 4 * i);
131 }
132
133 uint8_t aesY[16] = {2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2};
134 uint8_t aesInvY[16] = {0x0e, 0x0b, 0x0d, 0x09, 0x09, 0x0e, 0x0b, 0x0d, 0x0d, 0x09, 0x0e, 0x0b, 0x0b, 0x0d, 0x09,
135 0x0e};
136 uint8_t s[4];
137 uint8_t *y = isMixColumns == true ? aesY : aesInvY;
138
139 for (int i = 0; i < 4; ++i) {
140 for (int r = 0; r < 4; ++r) {
141 s[r] = 0;
142 for (int j = 0; j < 4; ++j) {
143 s[r] = s[r] ^ AesMul(ts[i * 4 + j], y[r * 4 + j]);
144 }
145 }
146 for (int r = 0; r < 4; ++r) {
147 ts[i * 4 + r] = s[r];
148 }
149 }
150
151 for (int32_t i = 0; i < 4; ++i) {
152 state[i] = GET_UINT32_BE(ts, 4 * i);
153 }
154 }
155
156 // addRound + 9/11/13 * (sub + shiftRow + mix + addRound) + (sub + shiftRow + addRound)
CRYPT_AES_EncryptSbox(const CRYPT_AES_Key * ctx,const uint8_t * in,uint8_t * out,uint32_t len)157 void CRYPT_AES_EncryptSbox(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
158 {
159 (void)len;
160 uint32_t s[4] = {0};
161
162 for (int32_t i = 0; i < 4; ++i) {
163 s[i] = GET_UINT32_BE(in, 4 * i);
164 }
165 uint32_t nr = 0;
166 AesAddRoundKey(s, ctx->key, nr);
167 for (nr = 1; nr < ctx->rounds; ++nr) {
168 AesSubBytes(s);
169 AesShiftRows(s);
170 AesMixColumns(s, true);
171 AesAddRoundKey(s, ctx->key, nr);
172 }
173 AesSubBytes(s);
174 AesShiftRows(s);
175 AesAddRoundKey(s, ctx->key, nr);
176
177 for (int32_t i = 0; i < 4; ++i) {
178 PUT_UINT32_BE(s[i], out, 4 * i);
179 }
180 }
181
InvShiftRows(uint32_t * state)182 static void InvShiftRows(uint32_t *state)
183 {
184 uint32_t s[4] = {0};
185 for (int32_t i = 0; i < 4; ++i) {
186 s[i] = state[i];
187 }
188
189 state[0] = (s[0] & 0xFF000000) | (s[3] & 0xFF0000) | (s[2] & 0xFF00) | (s[1] & 0xFF);
190 state[1] = (s[1] & 0xFF000000) | (s[0] & 0xFF0000) | (s[3] & 0xFF00) | (s[2] & 0xFF);
191 state[2] = (s[2] & 0xFF000000) | (s[1] & 0xFF0000) | (s[0] & 0xFF00) | (s[3] & 0xFF);
192 state[3] = (s[3] & 0xFF000000) | (s[2] & 0xFF0000) | (s[1] & 0xFF00) | (s[0] & 0xFF);
193 }
194
InvSubBytes(uint32_t * state)195 static void InvSubBytes(uint32_t *state)
196 {
197 for (int i = 0; i < 4; ++i) {
198 state[i] = SEARCH_INVSBOX(state[i]);
199 }
200 }
201
202 // (addRound + InvShiftRow + InvSub) + 9/11/13 * (addRound + invMix + InvShiftRow + InvSub) + addRound
CRYPT_AES_DecryptSbox(const CRYPT_AES_Key * ctx,const uint8_t * in,uint8_t * out,uint32_t len)203 void CRYPT_AES_DecryptSbox(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
204 {
205 (void)len;
206 uint32_t s[4] = {0};
207
208 for (int32_t i = 0; i < 4; ++i) {
209 s[i] = GET_UINT32_BE(in, 4 * i);
210 }
211
212 uint32_t nr = ctx->rounds;
213 AesAddRoundKey(s, ctx->key, nr);
214 InvShiftRows(s);
215 InvSubBytes(s);
216 for (nr = ctx->rounds - 1; nr > 0; --nr) {
217 AesAddRoundKey(s, ctx->key, nr);
218 AesMixColumns(s, false);
219 InvShiftRows(s);
220 InvSubBytes(s);
221 }
222 AesAddRoundKey(s, ctx->key, nr);
223 for (int32_t i = 0; i < 4; ++i) {
224 PUT_UINT32_BE(s[i], out, 4 * i);
225 }
226 BSL_SAL_CleanseData(&s, 4 * sizeof(uint32_t));
227 }
228 #endif /* HITLS_CRYPTO_AES && !HITLS_CRYPTO_AES_PRECALC_TABLES */