diff options
author | jsing <> | 2025-01-22 09:53:16 +0000 |
---|---|---|
committer | jsing <> | 2025-01-22 09:53:16 +0000 |
commit | bd450906a6797685e2415f6b369eaba032238591 (patch) | |
tree | 436e2cdca73589a5b6b9f96145e05c14be5fafb7 /src | |
parent | 6f44126c7264feafe48bccc5665f7db2a225ecb8 (diff) | |
download | openbsd-bd450906a6797685e2415f6b369eaba032238591.tar.gz openbsd-bd450906a6797685e2415f6b369eaba032238591.tar.bz2 openbsd-bd450906a6797685e2415f6b369eaba032238591.zip |
Expand the SM4_ROUNDS macro.
This macro references variable names that are in the consuming function and
are not actually passed to the macro. Expanding it makes the logic clearer.
If we wanted to reduce code the middle six group of rounds could be
implemented using a for loop (which the compiler can then choose to
unroll).
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/sm4/sm4.c | 108 |
1 files changed, 83 insertions, 25 deletions
diff --git a/src/lib/libcrypto/sm4/sm4.c b/src/lib/libcrypto/sm4/sm4.c index 31acac11f6..6e90fa19dd 100644 --- a/src/lib/libcrypto/sm4/sm4.c +++ b/src/lib/libcrypto/sm4/sm4.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sm4.c,v 1.5 2025/01/22 09:46:26 jsing Exp $ */ | 1 | /* $OpenBSD: sm4.c,v 1.6 2025/01/22 09:53:16 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2017, 2019 Ribose Inc | 3 | * Copyright (c) 2017, 2019 Ribose Inc |
4 | * | 4 | * |
@@ -177,14 +177,6 @@ SM4_set_key(const uint8_t *key, SM4_KEY *k) | |||
177 | } | 177 | } |
178 | LCRYPTO_ALIAS(SM4_set_key); | 178 | LCRYPTO_ALIAS(SM4_set_key); |
179 | 179 | ||
180 | #define SM4_ROUNDS(k0, k1, k2, k3, F) \ | ||
181 | do { \ | ||
182 | B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \ | ||
183 | B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \ | ||
184 | B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \ | ||
185 | B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \ | ||
186 | } while(0) | ||
187 | |||
188 | void | 180 | void |
189 | SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) | 181 | SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) |
190 | { | 182 | { |
@@ -200,14 +192,45 @@ SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) | |||
200 | * Uses byte-wise sbox in the first and last rounds to provide some | 192 | * Uses byte-wise sbox in the first and last rounds to provide some |
201 | * protection from cache based side channels. | 193 | * protection from cache based side channels. |
202 | */ | 194 | */ |
203 | SM4_ROUNDS( 0, 1, 2, 3, SM4_T_slow); | 195 | B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[0]); |
204 | SM4_ROUNDS( 4, 5, 6, 7, SM4_T); | 196 | B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[1]); |
205 | SM4_ROUNDS( 8, 9, 10, 11, SM4_T); | 197 | B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[2]); |
206 | SM4_ROUNDS(12, 13, 14, 15, SM4_T); | 198 | B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[3]); |
207 | SM4_ROUNDS(16, 17, 18, 19, SM4_T); | 199 | |
208 | SM4_ROUNDS(20, 21, 22, 23, SM4_T); | 200 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[4]); |
209 | SM4_ROUNDS(24, 25, 26, 27, SM4_T); | 201 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[5]); |
210 | SM4_ROUNDS(28, 29, 30, 31, SM4_T_slow); | 202 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[6]); |
203 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[7]); | ||
204 | |||
205 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[8]); | ||
206 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[9]); | ||
207 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[10]); | ||
208 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[11]); | ||
209 | |||
210 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[12]); | ||
211 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[13]); | ||
212 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[14]); | ||
213 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[15]); | ||
214 | |||
215 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[16]); | ||
216 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[17]); | ||
217 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[18]); | ||
218 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[19]); | ||
219 | |||
220 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[20]); | ||
221 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[21]); | ||
222 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[22]); | ||
223 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[23]); | ||
224 | |||
225 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[24]); | ||
226 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[25]); | ||
227 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[26]); | ||
228 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[27]); | ||
229 | |||
230 | B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[28]); | ||
231 | B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[29]); | ||
232 | B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[30]); | ||
233 | B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[31]); | ||
211 | 234 | ||
212 | crypto_store_htobe32(&out[0 * 4], B3); | 235 | crypto_store_htobe32(&out[0 * 4], B3); |
213 | crypto_store_htobe32(&out[1 * 4], B2); | 236 | crypto_store_htobe32(&out[1 * 4], B2); |
@@ -227,14 +250,49 @@ SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) | |||
227 | B2 = crypto_load_be32toh(&in[2 * 4]); | 250 | B2 = crypto_load_be32toh(&in[2 * 4]); |
228 | B3 = crypto_load_be32toh(&in[3 * 4]); | 251 | B3 = crypto_load_be32toh(&in[3 * 4]); |
229 | 252 | ||
230 | SM4_ROUNDS(31, 30, 29, 28, SM4_T_slow); | 253 | /* |
231 | SM4_ROUNDS(27, 26, 25, 24, SM4_T); | 254 | * Uses byte-wise sbox in the first and last rounds to provide some |
232 | SM4_ROUNDS(23, 22, 21, 20, SM4_T); | 255 | * protection from cache based side channels. |
233 | SM4_ROUNDS(19, 18, 17, 16, SM4_T); | 256 | */ |
234 | SM4_ROUNDS(15, 14, 13, 12, SM4_T); | 257 | B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[31]); |
235 | SM4_ROUNDS(11, 10, 9, 8, SM4_T); | 258 | B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[30]); |
236 | SM4_ROUNDS( 7, 6, 5, 4, SM4_T); | 259 | B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[29]); |
237 | SM4_ROUNDS( 3, 2, 1, 0, SM4_T_slow); | 260 | B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[28]); |
261 | |||
262 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[27]); | ||
263 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[26]); | ||
264 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[25]); | ||
265 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[24]); | ||
266 | |||
267 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[23]); | ||
268 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[22]); | ||
269 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[21]); | ||
270 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[20]); | ||
271 | |||
272 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[19]); | ||
273 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[18]); | ||
274 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[17]); | ||
275 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[16]); | ||
276 | |||
277 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[15]); | ||
278 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[14]); | ||
279 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[13]); | ||
280 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[12]); | ||
281 | |||
282 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[11]); | ||
283 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[10]); | ||
284 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[9]); | ||
285 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[8]); | ||
286 | |||
287 | B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[7]); | ||
288 | B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[6]); | ||
289 | B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[5]); | ||
290 | B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[4]); | ||
291 | |||
292 | B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[3]); | ||
293 | B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[2]); | ||
294 | B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[1]); | ||
295 | B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[0]); | ||
238 | 296 | ||
239 | crypto_store_htobe32(&out[0 * 4], B3); | 297 | crypto_store_htobe32(&out[0 * 4], B3); |
240 | crypto_store_htobe32(&out[1 * 4], B2); | 298 | crypto_store_htobe32(&out[1 * 4], B2); |