summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2025-01-22 09:53:16 +0000
committerjsing <>2025-01-22 09:53:16 +0000
commitbd450906a6797685e2415f6b369eaba032238591 (patch)
tree436e2cdca73589a5b6b9f96145e05c14be5fafb7 /src
parent6f44126c7264feafe48bccc5665f7db2a225ecb8 (diff)
downloadopenbsd-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.c108
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}
178LCRYPTO_ALIAS(SM4_set_key); 178LCRYPTO_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
188void 180void
189SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) 181SM4_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);