master
c 787 lines 20.6 KB
Raw
1 /*
2 * crypto_helper.c - emulate v8 Crypto Extensions instructions
3 *
4 * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 */
11
12 #include "qemu/osdep.h"
13 #include "qemu/bitops.h"
14
15 #include "tcg/tcg-gvec-desc.h"
16 #include "crypto/aes-round.h"
17 #include "crypto/sm4.h"
18 #include "helper.h"
19 #include "vec_internal.h"
20
21 union CRYPTO_STATE {
22 uint8_t bytes[16];
23 uint32_t words[4];
24 uint64_t l[2];
25 };
26
27 #if HOST_BIG_ENDIAN
28 #define CR_ST_BYTE(state, i) ((state).bytes[(15 - (i)) ^ 8])
29 #define CR_ST_WORD(state, i) ((state).words[(3 - (i)) ^ 2])
30 #else
31 #define CR_ST_BYTE(state, i) ((state).bytes[i])
32 #define CR_ST_WORD(state, i) ((state).words[i])
33 #endif
34
35 /*
36 * The caller has not been converted to full gvec, and so only
37 * modifies the low 16 bytes of the vector register.
38 */
39 static void clear_tail_16(void *vd, uint32_t desc)
40 {
41 int opr_sz = simd_oprsz(desc);
42 int max_sz = simd_maxsz(desc);
43
44 assert(opr_sz == 16);
45 clear_tail(vd, opr_sz, max_sz);
46 }
47
48 static const AESState aes_zero = { };
49
50 static void aese_kernel(AESState *ad, const AESState *st, const AESState *rk)
51 {
52 AESState t;
53
54 /*
55 * Our uint64_t are in the wrong order for big-endian.
56 * The Arm AddRoundKey comes first, while the API AddRoundKey
57 * comes last: perform the xor here, and provide zero to API.
58 */
59 if (HOST_BIG_ENDIAN) {
60 t.d[0] = st->d[1] ^ rk->d[1];
61 t.d[1] = st->d[0] ^ rk->d[0];
62 aesenc_SB_SR_AK(&t, &t, &aes_zero, false);
63 ad->d[0] = t.d[1];
64 ad->d[1] = t.d[0];
65 } else {
66 t.v = st->v ^ rk->v;
67 aesenc_SB_SR_AK(ad, &t, &aes_zero, false);
68 }
69 }
70
71 void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc)
72 {
73 intptr_t i, opr_sz = simd_oprsz(desc);
74
75 for (i = 0; i < opr_sz; i += 16) {
76 AESState *ad = (AESState *)(vd + i);
77 AESState *st = (AESState *)(vn + i);
78 AESState *rk = (AESState *)(vm + i);
79
80 aese_kernel(ad, st, rk);
81 }
82 clear_tail(vd, opr_sz, simd_maxsz(desc));
83 }
84
85 void HELPER(crypto_aese_idx)(void *vd, void *vn, void *vm, uint32_t desc)
86 {
87 intptr_t opr_sz = simd_oprsz(desc);
88 intptr_t idx = simd_data(desc);
89 void *vm_idx = vm + idx * 16;
90 intptr_t s = opr_sz - 16;
91
92 do {
93 intptr_t base = ROUND_DOWN(s, 4 * 16);
94 AESState rk = *(AESState *)(vm_idx + base);
95 do {
96 aese_kernel(vd + s, vn + s, &rk);
97 s -= 16;
98 } while (s >= base);
99 } while (s > 0);
100 }
101
102 static void aesd_kernel(AESState *ad, const AESState *st, const AESState *rk)
103 {
104 AESState t;
105
106 /* Our uint64_t are in the wrong order for big-endian. */
107 if (HOST_BIG_ENDIAN) {
108 t.d[0] = st->d[1] ^ rk->d[1];
109 t.d[1] = st->d[0] ^ rk->d[0];
110 aesdec_ISB_ISR_AK(&t, &t, &aes_zero, false);
111 ad->d[0] = t.d[1];
112 ad->d[1] = t.d[0];
113 } else {
114 t.v = st->v ^ rk->v;
115 aesdec_ISB_ISR_AK(ad, &t, &aes_zero, false);
116 }
117 }
118
119 void HELPER(crypto_aesd)(void *vd, void *vn, void *vm, uint32_t desc)
120 {
121 intptr_t i, opr_sz = simd_oprsz(desc);
122
123 for (i = 0; i < opr_sz; i += 16) {
124 AESState *ad = (AESState *)(vd + i);
125 AESState *st = (AESState *)(vn + i);
126 AESState *rk = (AESState *)(vm + i);
127
128 aesd_kernel(ad, st, rk);
129 }
130 clear_tail(vd, opr_sz, simd_maxsz(desc));
131 }
132
133 void HELPER(crypto_aesd_idx)(void *vd, void *vn, void *vm, uint32_t desc)
134 {
135 intptr_t opr_sz = simd_oprsz(desc);
136 intptr_t idx = simd_data(desc);
137 void *vm_idx = vm + idx * 16;
138 intptr_t s = opr_sz - 16;
139
140 do {
141 intptr_t base = ROUND_DOWN(s, 4 * 16);
142 AESState rk = *(AESState *)(vm_idx + base);
143 do {
144 aesd_kernel(vd + s, vn + s, &rk);
145 s -= 16;
146 } while (s >= base);
147 } while (s > 0);
148 }
149
150 void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t desc)
151 {
152 intptr_t i, opr_sz = simd_oprsz(desc);
153
154 for (i = 0; i < opr_sz; i += 16) {
155 AESState *ad = (AESState *)(vd + i);
156 AESState *st = (AESState *)(vm + i);
157 AESState t;
158
159 /* Our uint64_t are in the wrong order for big-endian. */
160 if (HOST_BIG_ENDIAN) {
161 t.d[0] = st->d[1];
162 t.d[1] = st->d[0];
163 aesenc_MC(&t, &t, false);
164 ad->d[0] = t.d[1];
165 ad->d[1] = t.d[0];
166 } else {
167 aesenc_MC(ad, st, false);
168 }
169 }
170 clear_tail(vd, opr_sz, simd_maxsz(desc));
171 }
172
173 void HELPER(crypto_aesimc)(void *vd, void *vm, uint32_t desc)
174 {
175 intptr_t i, opr_sz = simd_oprsz(desc);
176
177 for (i = 0; i < opr_sz; i += 16) {
178 AESState *ad = (AESState *)(vd + i);
179 AESState *st = (AESState *)(vm + i);
180 AESState t;
181
182 /* Our uint64_t are in the wrong order for big-endian. */
183 if (HOST_BIG_ENDIAN) {
184 t.d[0] = st->d[1];
185 t.d[1] = st->d[0];
186 aesdec_IMC(&t, &t, false);
187 ad->d[0] = t.d[1];
188 ad->d[1] = t.d[0];
189 } else {
190 aesdec_IMC(ad, st, false);
191 }
192 }
193 clear_tail(vd, opr_sz, simd_maxsz(desc));
194 }
195
196 void HELPER(crypto_aesemc)(void *vd, void *vn, void *vm, uint32_t desc)
197 {
198 intptr_t opr_sz = simd_oprsz(desc);
199 intptr_t idx = simd_data(desc);
200 void *vm_idx = vm + idx * 16;
201 intptr_t s = opr_sz - 16;
202
203 do {
204 intptr_t base = ROUND_DOWN(s, 4 * 16);
205 AESState rk = *(AESState *)(vm_idx + base);
206 do {
207 AESState *ad = (AESState *)(vd + s);
208 AESState *st = (AESState *)(vn + s);
209 AESState t;
210
211 /* Like above: Arm AK comes first; api AK comes last */
212 if (HOST_BIG_ENDIAN) {
213 t.d[0] = st->d[1] ^ rk.d[1];
214 t.d[1] = st->d[0] ^ rk.d[0];
215 aesenc_SB_SR_MC_AK(&t, &t, &aes_zero, false);
216 ad->d[0] = t.d[1];
217 ad->d[1] = t.d[0];
218 } else {
219 t.v = st->v ^ rk.v;
220 aesenc_SB_SR_MC_AK(ad, &t, &aes_zero, false);
221 }
222 s -= 16;
223 } while (s >= base);
224 } while (s > 0);
225 }
226
227 void HELPER(crypto_aesdimc)(void *vd, void *vn, void *vm, uint32_t desc)
228 {
229 intptr_t opr_sz = simd_oprsz(desc);
230 intptr_t idx = simd_data(desc);
231 void *vm_idx = vm + idx * 16;
232 intptr_t s = opr_sz - 16;
233
234 do {
235 intptr_t base = ROUND_DOWN(s, 4 * 16);
236 AESState rk = *(AESState *)(vm_idx + base);
237 do {
238 AESState *ad = (AESState *)(vd + s);
239 AESState *st = (AESState *)(vn + s);
240 AESState t;
241
242 /* Like above: Arm AK comes first; api AK comes last */
243 if (HOST_BIG_ENDIAN) {
244 t.d[0] = st->d[1] ^ rk.d[1];
245 t.d[1] = st->d[0] ^ rk.d[0];
246 aesdec_ISB_ISR_IMC_AK(&t, &t, &aes_zero, false);
247 ad->d[0] = t.d[1];
248 ad->d[1] = t.d[0];
249 } else {
250 t.v = st->v ^ rk.v;
251 aesdec_ISB_ISR_IMC_AK(ad, &t, &aes_zero, false);
252 }
253 s -= 16;
254 } while (s >= base);
255 } while (s > 0);
256 }
257
258 /*
259 * SHA-1 logical functions
260 */
261
262 static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
263 {
264 return (x & (y ^ z)) ^ z;
265 }
266
267 static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
268 {
269 return x ^ y ^ z;
270 }
271
272 static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
273 {
274 return (x & y) | ((x | y) & z);
275 }
276
277 void HELPER(crypto_sha1su0)(void *vd, void *vn, void *vm, uint32_t desc)
278 {
279 uint64_t *d = vd, *n = vn, *m = vm;
280 uint64_t d0, d1;
281
282 d0 = d[1] ^ d[0] ^ m[0];
283 d1 = n[0] ^ d[1] ^ m[1];
284 d[0] = d0;
285 d[1] = d1;
286
287 clear_tail_16(vd, desc);
288 }
289
290 static inline void crypto_sha1_3reg(uint64_t *rd, uint64_t *rn,
291 uint64_t *rm, uint32_t desc,
292 uint32_t (*fn)(union CRYPTO_STATE *d))
293 {
294 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
295 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
296 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
297 int i;
298
299 for (i = 0; i < 4; i++) {
300 uint32_t t = fn(&d);
301
302 t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
303 + CR_ST_WORD(m, i);
304
305 CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
306 CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
307 CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
308 CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
309 CR_ST_WORD(d, 0) = t;
310 }
311 rd[0] = d.l[0];
312 rd[1] = d.l[1];
313
314 clear_tail_16(rd, desc);
315 }
316
317 static uint32_t do_sha1c(union CRYPTO_STATE *d)
318 {
319 return cho(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
320 }
321
322 void HELPER(crypto_sha1c)(void *vd, void *vn, void *vm, uint32_t desc)
323 {
324 crypto_sha1_3reg(vd, vn, vm, desc, do_sha1c);
325 }
326
327 static uint32_t do_sha1p(union CRYPTO_STATE *d)
328 {
329 return par(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
330 }
331
332 void HELPER(crypto_sha1p)(void *vd, void *vn, void *vm, uint32_t desc)
333 {
334 crypto_sha1_3reg(vd, vn, vm, desc, do_sha1p);
335 }
336
337 static uint32_t do_sha1m(union CRYPTO_STATE *d)
338 {
339 return maj(CR_ST_WORD(*d, 1), CR_ST_WORD(*d, 2), CR_ST_WORD(*d, 3));
340 }
341
342 void HELPER(crypto_sha1m)(void *vd, void *vn, void *vm, uint32_t desc)
343 {
344 crypto_sha1_3reg(vd, vn, vm, desc, do_sha1m);
345 }
346
347 void HELPER(crypto_sha1h)(void *vd, void *vm, uint32_t desc)
348 {
349 uint64_t *rd = vd;
350 uint64_t *rm = vm;
351 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
352
353 CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
354 CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
355
356 rd[0] = m.l[0];
357 rd[1] = m.l[1];
358
359 clear_tail_16(vd, desc);
360 }
361
362 void HELPER(crypto_sha1su1)(void *vd, void *vm, uint32_t desc)
363 {
364 uint64_t *rd = vd;
365 uint64_t *rm = vm;
366 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
367 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
368
369 CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
370 CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
371 CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
372 CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
373
374 rd[0] = d.l[0];
375 rd[1] = d.l[1];
376
377 clear_tail_16(vd, desc);
378 }
379
380 /*
381 * The SHA-256 logical functions, according to
382 * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
383 */
384
385 static uint32_t S0(uint32_t x)
386 {
387 return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
388 }
389
390 static uint32_t S1(uint32_t x)
391 {
392 return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
393 }
394
395 static uint32_t s0(uint32_t x)
396 {
397 return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
398 }
399
400 static uint32_t s1(uint32_t x)
401 {
402 return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
403 }
404
405 void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm, uint32_t desc)
406 {
407 uint64_t *rd = vd;
408 uint64_t *rn = vn;
409 uint64_t *rm = vm;
410 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
411 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
412 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
413 int i;
414
415 for (i = 0; i < 4; i++) {
416 uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2))
417 + CR_ST_WORD(n, 3) + S1(CR_ST_WORD(n, 0))
418 + CR_ST_WORD(m, i);
419
420 CR_ST_WORD(n, 3) = CR_ST_WORD(n, 2);
421 CR_ST_WORD(n, 2) = CR_ST_WORD(n, 1);
422 CR_ST_WORD(n, 1) = CR_ST_WORD(n, 0);
423 CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3) + t;
424
425 t += maj(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
426 + S0(CR_ST_WORD(d, 0));
427
428 CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
429 CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
430 CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
431 CR_ST_WORD(d, 0) = t;
432 }
433
434 rd[0] = d.l[0];
435 rd[1] = d.l[1];
436
437 clear_tail_16(vd, desc);
438 }
439
440 void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm, uint32_t desc)
441 {
442 uint64_t *rd = vd;
443 uint64_t *rn = vn;
444 uint64_t *rm = vm;
445 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
446 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
447 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
448 int i;
449
450 for (i = 0; i < 4; i++) {
451 uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
452 + CR_ST_WORD(d, 3) + S1(CR_ST_WORD(d, 0))
453 + CR_ST_WORD(m, i);
454
455 CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
456 CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
457 CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
458 CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
459 }
460
461 rd[0] = d.l[0];
462 rd[1] = d.l[1];
463
464 clear_tail_16(vd, desc);
465 }
466
467 void HELPER(crypto_sha256su0)(void *vd, void *vm, uint32_t desc)
468 {
469 uint64_t *rd = vd;
470 uint64_t *rm = vm;
471 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
472 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
473
474 CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
475 CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
476 CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
477 CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
478
479 rd[0] = d.l[0];
480 rd[1] = d.l[1];
481
482 clear_tail_16(vd, desc);
483 }
484
485 void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm, uint32_t desc)
486 {
487 uint64_t *rd = vd;
488 uint64_t *rn = vn;
489 uint64_t *rm = vm;
490 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
491 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
492 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
493
494 CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
495 CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
496 CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
497 CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
498
499 rd[0] = d.l[0];
500 rd[1] = d.l[1];
501
502 clear_tail_16(vd, desc);
503 }
504
505 /*
506 * The SHA-512 logical functions (same as above but using 64-bit operands)
507 */
508
509 static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
510 {
511 return (x & (y ^ z)) ^ z;
512 }
513
514 static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
515 {
516 return (x & y) | ((x | y) & z);
517 }
518
519 static uint64_t S0_512(uint64_t x)
520 {
521 return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
522 }
523
524 static uint64_t S1_512(uint64_t x)
525 {
526 return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
527 }
528
529 static uint64_t s0_512(uint64_t x)
530 {
531 return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
532 }
533
534 static uint64_t s1_512(uint64_t x)
535 {
536 return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
537 }
538
539 void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm, uint32_t desc)
540 {
541 uint64_t *rd = vd;
542 uint64_t *rn = vn;
543 uint64_t *rm = vm;
544 uint64_t d0 = rd[0];
545 uint64_t d1 = rd[1];
546
547 d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
548 d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
549
550 rd[0] = d0;
551 rd[1] = d1;
552
553 clear_tail_16(vd, desc);
554 }
555
556 void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm, uint32_t desc)
557 {
558 uint64_t *rd = vd;
559 uint64_t *rn = vn;
560 uint64_t *rm = vm;
561 uint64_t d0 = rd[0];
562 uint64_t d1 = rd[1];
563
564 d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
565 d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
566
567 rd[0] = d0;
568 rd[1] = d1;
569
570 clear_tail_16(vd, desc);
571 }
572
573 void HELPER(crypto_sha512su0)(void *vd, void *vn, uint32_t desc)
574 {
575 uint64_t *rd = vd;
576 uint64_t *rn = vn;
577 uint64_t d0 = rd[0];
578 uint64_t d1 = rd[1];
579
580 d0 += s0_512(rd[1]);
581 d1 += s0_512(rn[0]);
582
583 rd[0] = d0;
584 rd[1] = d1;
585
586 clear_tail_16(vd, desc);
587 }
588
589 void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm, uint32_t desc)
590 {
591 uint64_t *rd = vd;
592 uint64_t *rn = vn;
593 uint64_t *rm = vm;
594
595 rd[0] += s1_512(rn[0]) + rm[0];
596 rd[1] += s1_512(rn[1]) + rm[1];
597
598 clear_tail_16(vd, desc);
599 }
600
601 void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm, uint32_t desc)
602 {
603 uint64_t *rd = vd;
604 uint64_t *rn = vn;
605 uint64_t *rm = vm;
606 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
607 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
608 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
609 uint32_t t;
610
611 t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
612 CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
613
614 t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
615 CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
616
617 t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
618 CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
619
620 t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
621 CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
622
623 rd[0] = d.l[0];
624 rd[1] = d.l[1];
625
626 clear_tail_16(vd, desc);
627 }
628
629 void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm, uint32_t desc)
630 {
631 uint64_t *rd = vd;
632 uint64_t *rn = vn;
633 uint64_t *rm = vm;
634 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
635 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
636 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
637 uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
638
639 CR_ST_WORD(d, 0) ^= t;
640 CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
641 CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
642 CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
643 ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
644
645 rd[0] = d.l[0];
646 rd[1] = d.l[1];
647
648 clear_tail_16(vd, desc);
649 }
650
651 static inline void QEMU_ALWAYS_INLINE
652 crypto_sm3tt(uint64_t *rd, uint64_t *rn, uint64_t *rm,
653 uint32_t desc, uint32_t opcode)
654 {
655 union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
656 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
657 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
658 uint32_t imm2 = simd_data(desc);
659 uint32_t t;
660
661 assert(imm2 < 4);
662
663 if (opcode == 0 || opcode == 2) {
664 /* SM3TT1A, SM3TT2A */
665 t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
666 } else if (opcode == 1) {
667 /* SM3TT1B */
668 t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
669 } else if (opcode == 3) {
670 /* SM3TT2B */
671 t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
672 } else {
673 qemu_build_not_reached();
674 }
675
676 t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
677
678 CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
679
680 if (opcode < 2) {
681 /* SM3TT1A, SM3TT1B */
682 t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
683
684 CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
685 } else {
686 /* SM3TT2A, SM3TT2B */
687 t += CR_ST_WORD(n, 3);
688 t ^= rol32(t, 9) ^ rol32(t, 17);
689
690 CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
691 }
692
693 CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
694 CR_ST_WORD(d, 3) = t;
695
696 rd[0] = d.l[0];
697 rd[1] = d.l[1];
698
699 clear_tail_16(rd, desc);
700 }
701
702 #define DO_SM3TT(NAME, OPCODE) \
703 void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
704 { crypto_sm3tt(vd, vn, vm, desc, OPCODE); }
705
706 DO_SM3TT(crypto_sm3tt1a, 0)
707 DO_SM3TT(crypto_sm3tt1b, 1)
708 DO_SM3TT(crypto_sm3tt2a, 2)
709 DO_SM3TT(crypto_sm3tt2b, 3)
710
711 #undef DO_SM3TT
712
713 static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
714 {
715 union CRYPTO_STATE d = { .l = { rn[0], rn[1] } };
716 union CRYPTO_STATE n = { .l = { rm[0], rm[1] } };
717 uint32_t t, i;
718
719 for (i = 0; i < 4; i++) {
720 t = CR_ST_WORD(d, (i + 1) % 4) ^
721 CR_ST_WORD(d, (i + 2) % 4) ^
722 CR_ST_WORD(d, (i + 3) % 4) ^
723 CR_ST_WORD(n, i);
724
725 t = sm4_subword(t);
726
727 CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
728 rol32(t, 24);
729 }
730
731 rd[0] = d.l[0];
732 rd[1] = d.l[1];
733 }
734
735 void HELPER(crypto_sm4e)(void *vd, void *vn, void *vm, uint32_t desc)
736 {
737 intptr_t i, opr_sz = simd_oprsz(desc);
738
739 for (i = 0; i < opr_sz; i += 16) {
740 do_crypto_sm4e(vd + i, vn + i, vm + i);
741 }
742 clear_tail(vd, opr_sz, simd_maxsz(desc));
743 }
744
745 static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
746 {
747 union CRYPTO_STATE d;
748 union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
749 union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
750 uint32_t t, i;
751
752 d = n;
753 for (i = 0; i < 4; i++) {
754 t = CR_ST_WORD(d, (i + 1) % 4) ^
755 CR_ST_WORD(d, (i + 2) % 4) ^
756 CR_ST_WORD(d, (i + 3) % 4) ^
757 CR_ST_WORD(m, i);
758
759 t = sm4_subword(t);
760
761 CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
762 }
763
764 rd[0] = d.l[0];
765 rd[1] = d.l[1];
766 }
767
768 void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc)
769 {
770 intptr_t i, opr_sz = simd_oprsz(desc);
771
772 for (i = 0; i < opr_sz; i += 16) {
773 do_crypto_sm4ekey(vd + i, vn + i, vm + i);
774 }
775 clear_tail(vd, opr_sz, simd_maxsz(desc));
776 }
777
778 void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc)
779 {
780 intptr_t i, opr_sz = simd_oprsz(desc);
781 uint64_t *d = vd, *n = vn, *m = vm;
782
783 for (i = 0; i < opr_sz / 8; ++i) {
784 d[i] = n[i] ^ rol64(m[i], 1);
785 }
786 clear_tail(vd, opr_sz, simd_maxsz(desc));
787 }