2 * crypto_helper.c - emulate v8 Crypto Extensions instructions
4 * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
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.
12 #include "qemu/osdep.h"
15 #include "exec/helper-proto.h"
16 #include "tcg/tcg-gvec-desc.h"
17 #include "crypto/aes-round.h"
18 #include "crypto/sm4.h"
19 #include "vec_internal.h"
28 #define CR_ST_BYTE(state, i) ((state).bytes[(15 - (i)) ^ 8])
29 #define CR_ST_WORD(state, i) ((state).words[(3 - (i)) ^ 2])
31 #define CR_ST_BYTE(state, i) ((state).bytes[i])
32 #define CR_ST_WORD(state, i) ((state).words[i])
36 * The caller has not been converted to full gvec, and so only
37 * modifies the low 16 bytes of the vector register.
39 static void clear_tail_16(void *vd
, uint32_t desc
)
41 int opr_sz
= simd_oprsz(desc
);
42 int max_sz
= simd_maxsz(desc
);
45 clear_tail(vd
, opr_sz
, max_sz
);
48 static const AESState aes_zero
= { };
50 void HELPER(crypto_aese
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
52 intptr_t i
, opr_sz
= simd_oprsz(desc
);
54 for (i
= 0; i
< opr_sz
; i
+= 16) {
55 AESState
*ad
= (AESState
*)(vd
+ i
);
56 AESState
*st
= (AESState
*)(vn
+ i
);
57 AESState
*rk
= (AESState
*)(vm
+ i
);
61 * Our uint64_t are in the wrong order for big-endian.
62 * The Arm AddRoundKey comes first, while the API AddRoundKey
63 * comes last: perform the xor here, and provide zero to API.
65 if (HOST_BIG_ENDIAN
) {
66 t
.d
[0] = st
->d
[1] ^ rk
->d
[1];
67 t
.d
[1] = st
->d
[0] ^ rk
->d
[0];
68 aesenc_SB_SR_AK(&t
, &t
, &aes_zero
, false);
73 aesenc_SB_SR_AK(ad
, &t
, &aes_zero
, false);
76 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
79 void HELPER(crypto_aesd
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
81 intptr_t i
, opr_sz
= simd_oprsz(desc
);
83 for (i
= 0; i
< opr_sz
; i
+= 16) {
84 AESState
*ad
= (AESState
*)(vd
+ i
);
85 AESState
*st
= (AESState
*)(vn
+ i
);
86 AESState
*rk
= (AESState
*)(vm
+ i
);
89 /* Our uint64_t are in the wrong order for big-endian. */
90 if (HOST_BIG_ENDIAN
) {
91 t
.d
[0] = st
->d
[1] ^ rk
->d
[1];
92 t
.d
[1] = st
->d
[0] ^ rk
->d
[0];
93 aesdec_ISB_ISR_AK(&t
, &t
, &aes_zero
, false);
98 aesdec_ISB_ISR_AK(ad
, &t
, &aes_zero
, false);
101 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
104 void HELPER(crypto_aesmc
)(void *vd
, void *vm
, uint32_t desc
)
106 intptr_t i
, opr_sz
= simd_oprsz(desc
);
108 for (i
= 0; i
< opr_sz
; i
+= 16) {
109 AESState
*ad
= (AESState
*)(vd
+ i
);
110 AESState
*st
= (AESState
*)(vm
+ i
);
113 /* Our uint64_t are in the wrong order for big-endian. */
114 if (HOST_BIG_ENDIAN
) {
117 aesenc_MC(&t
, &t
, false);
121 aesenc_MC(ad
, st
, false);
124 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
127 void HELPER(crypto_aesimc
)(void *vd
, void *vm
, uint32_t desc
)
129 intptr_t i
, opr_sz
= simd_oprsz(desc
);
131 for (i
= 0; i
< opr_sz
; i
+= 16) {
132 AESState
*ad
= (AESState
*)(vd
+ i
);
133 AESState
*st
= (AESState
*)(vm
+ i
);
136 /* Our uint64_t are in the wrong order for big-endian. */
137 if (HOST_BIG_ENDIAN
) {
140 aesdec_IMC(&t
, &t
, false);
144 aesdec_IMC(ad
, st
, false);
147 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
151 * SHA-1 logical functions
154 static uint32_t cho(uint32_t x
, uint32_t y
, uint32_t z
)
156 return (x
& (y
^ z
)) ^ z
;
159 static uint32_t par(uint32_t x
, uint32_t y
, uint32_t z
)
164 static uint32_t maj(uint32_t x
, uint32_t y
, uint32_t z
)
166 return (x
& y
) | ((x
| y
) & z
);
169 void HELPER(crypto_sha1su0
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
171 uint64_t *d
= vd
, *n
= vn
, *m
= vm
;
174 d0
= d
[1] ^ d
[0] ^ m
[0];
175 d1
= n
[0] ^ d
[1] ^ m
[1];
179 clear_tail_16(vd
, desc
);
182 static inline void crypto_sha1_3reg(uint64_t *rd
, uint64_t *rn
,
183 uint64_t *rm
, uint32_t desc
,
184 uint32_t (*fn
)(union CRYPTO_STATE
*d
))
186 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
187 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
188 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
191 for (i
= 0; i
< 4; i
++) {
194 t
+= rol32(CR_ST_WORD(d
, 0), 5) + CR_ST_WORD(n
, 0)
197 CR_ST_WORD(n
, 0) = CR_ST_WORD(d
, 3);
198 CR_ST_WORD(d
, 3) = CR_ST_WORD(d
, 2);
199 CR_ST_WORD(d
, 2) = ror32(CR_ST_WORD(d
, 1), 2);
200 CR_ST_WORD(d
, 1) = CR_ST_WORD(d
, 0);
201 CR_ST_WORD(d
, 0) = t
;
206 clear_tail_16(rd
, desc
);
209 static uint32_t do_sha1c(union CRYPTO_STATE
*d
)
211 return cho(CR_ST_WORD(*d
, 1), CR_ST_WORD(*d
, 2), CR_ST_WORD(*d
, 3));
214 void HELPER(crypto_sha1c
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
216 crypto_sha1_3reg(vd
, vn
, vm
, desc
, do_sha1c
);
219 static uint32_t do_sha1p(union CRYPTO_STATE
*d
)
221 return par(CR_ST_WORD(*d
, 1), CR_ST_WORD(*d
, 2), CR_ST_WORD(*d
, 3));
224 void HELPER(crypto_sha1p
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
226 crypto_sha1_3reg(vd
, vn
, vm
, desc
, do_sha1p
);
229 static uint32_t do_sha1m(union CRYPTO_STATE
*d
)
231 return maj(CR_ST_WORD(*d
, 1), CR_ST_WORD(*d
, 2), CR_ST_WORD(*d
, 3));
234 void HELPER(crypto_sha1m
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
236 crypto_sha1_3reg(vd
, vn
, vm
, desc
, do_sha1m
);
239 void HELPER(crypto_sha1h
)(void *vd
, void *vm
, uint32_t desc
)
243 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
245 CR_ST_WORD(m
, 0) = ror32(CR_ST_WORD(m
, 0), 2);
246 CR_ST_WORD(m
, 1) = CR_ST_WORD(m
, 2) = CR_ST_WORD(m
, 3) = 0;
251 clear_tail_16(vd
, desc
);
254 void HELPER(crypto_sha1su1
)(void *vd
, void *vm
, uint32_t desc
)
258 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
259 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
261 CR_ST_WORD(d
, 0) = rol32(CR_ST_WORD(d
, 0) ^ CR_ST_WORD(m
, 1), 1);
262 CR_ST_WORD(d
, 1) = rol32(CR_ST_WORD(d
, 1) ^ CR_ST_WORD(m
, 2), 1);
263 CR_ST_WORD(d
, 2) = rol32(CR_ST_WORD(d
, 2) ^ CR_ST_WORD(m
, 3), 1);
264 CR_ST_WORD(d
, 3) = rol32(CR_ST_WORD(d
, 3) ^ CR_ST_WORD(d
, 0), 1);
269 clear_tail_16(vd
, desc
);
273 * The SHA-256 logical functions, according to
274 * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
277 static uint32_t S0(uint32_t x
)
279 return ror32(x
, 2) ^ ror32(x
, 13) ^ ror32(x
, 22);
282 static uint32_t S1(uint32_t x
)
284 return ror32(x
, 6) ^ ror32(x
, 11) ^ ror32(x
, 25);
287 static uint32_t s0(uint32_t x
)
289 return ror32(x
, 7) ^ ror32(x
, 18) ^ (x
>> 3);
292 static uint32_t s1(uint32_t x
)
294 return ror32(x
, 17) ^ ror32(x
, 19) ^ (x
>> 10);
297 void HELPER(crypto_sha256h
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
302 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
303 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
304 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
307 for (i
= 0; i
< 4; i
++) {
308 uint32_t t
= cho(CR_ST_WORD(n
, 0), CR_ST_WORD(n
, 1), CR_ST_WORD(n
, 2))
309 + CR_ST_WORD(n
, 3) + S1(CR_ST_WORD(n
, 0))
312 CR_ST_WORD(n
, 3) = CR_ST_WORD(n
, 2);
313 CR_ST_WORD(n
, 2) = CR_ST_WORD(n
, 1);
314 CR_ST_WORD(n
, 1) = CR_ST_WORD(n
, 0);
315 CR_ST_WORD(n
, 0) = CR_ST_WORD(d
, 3) + t
;
317 t
+= maj(CR_ST_WORD(d
, 0), CR_ST_WORD(d
, 1), CR_ST_WORD(d
, 2))
318 + S0(CR_ST_WORD(d
, 0));
320 CR_ST_WORD(d
, 3) = CR_ST_WORD(d
, 2);
321 CR_ST_WORD(d
, 2) = CR_ST_WORD(d
, 1);
322 CR_ST_WORD(d
, 1) = CR_ST_WORD(d
, 0);
323 CR_ST_WORD(d
, 0) = t
;
329 clear_tail_16(vd
, desc
);
332 void HELPER(crypto_sha256h2
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
337 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
338 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
339 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
342 for (i
= 0; i
< 4; i
++) {
343 uint32_t t
= cho(CR_ST_WORD(d
, 0), CR_ST_WORD(d
, 1), CR_ST_WORD(d
, 2))
344 + CR_ST_WORD(d
, 3) + S1(CR_ST_WORD(d
, 0))
347 CR_ST_WORD(d
, 3) = CR_ST_WORD(d
, 2);
348 CR_ST_WORD(d
, 2) = CR_ST_WORD(d
, 1);
349 CR_ST_WORD(d
, 1) = CR_ST_WORD(d
, 0);
350 CR_ST_WORD(d
, 0) = CR_ST_WORD(n
, 3 - i
) + t
;
356 clear_tail_16(vd
, desc
);
359 void HELPER(crypto_sha256su0
)(void *vd
, void *vm
, uint32_t desc
)
363 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
364 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
366 CR_ST_WORD(d
, 0) += s0(CR_ST_WORD(d
, 1));
367 CR_ST_WORD(d
, 1) += s0(CR_ST_WORD(d
, 2));
368 CR_ST_WORD(d
, 2) += s0(CR_ST_WORD(d
, 3));
369 CR_ST_WORD(d
, 3) += s0(CR_ST_WORD(m
, 0));
374 clear_tail_16(vd
, desc
);
377 void HELPER(crypto_sha256su1
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
382 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
383 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
384 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
386 CR_ST_WORD(d
, 0) += s1(CR_ST_WORD(m
, 2)) + CR_ST_WORD(n
, 1);
387 CR_ST_WORD(d
, 1) += s1(CR_ST_WORD(m
, 3)) + CR_ST_WORD(n
, 2);
388 CR_ST_WORD(d
, 2) += s1(CR_ST_WORD(d
, 0)) + CR_ST_WORD(n
, 3);
389 CR_ST_WORD(d
, 3) += s1(CR_ST_WORD(d
, 1)) + CR_ST_WORD(m
, 0);
394 clear_tail_16(vd
, desc
);
398 * The SHA-512 logical functions (same as above but using 64-bit operands)
401 static uint64_t cho512(uint64_t x
, uint64_t y
, uint64_t z
)
403 return (x
& (y
^ z
)) ^ z
;
406 static uint64_t maj512(uint64_t x
, uint64_t y
, uint64_t z
)
408 return (x
& y
) | ((x
| y
) & z
);
411 static uint64_t S0_512(uint64_t x
)
413 return ror64(x
, 28) ^ ror64(x
, 34) ^ ror64(x
, 39);
416 static uint64_t S1_512(uint64_t x
)
418 return ror64(x
, 14) ^ ror64(x
, 18) ^ ror64(x
, 41);
421 static uint64_t s0_512(uint64_t x
)
423 return ror64(x
, 1) ^ ror64(x
, 8) ^ (x
>> 7);
426 static uint64_t s1_512(uint64_t x
)
428 return ror64(x
, 19) ^ ror64(x
, 61) ^ (x
>> 6);
431 void HELPER(crypto_sha512h
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
439 d1
+= S1_512(rm
[1]) + cho512(rm
[1], rn
[0], rn
[1]);
440 d0
+= S1_512(d1
+ rm
[0]) + cho512(d1
+ rm
[0], rm
[1], rn
[0]);
445 clear_tail_16(vd
, desc
);
448 void HELPER(crypto_sha512h2
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
456 d1
+= S0_512(rm
[0]) + maj512(rn
[0], rm
[1], rm
[0]);
457 d0
+= S0_512(d1
) + maj512(d1
, rm
[0], rm
[1]);
462 clear_tail_16(vd
, desc
);
465 void HELPER(crypto_sha512su0
)(void *vd
, void *vn
, uint32_t desc
)
478 clear_tail_16(vd
, desc
);
481 void HELPER(crypto_sha512su1
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
487 rd
[0] += s1_512(rn
[0]) + rm
[0];
488 rd
[1] += s1_512(rn
[1]) + rm
[1];
490 clear_tail_16(vd
, desc
);
493 void HELPER(crypto_sm3partw1
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
498 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
499 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
500 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
503 t
= CR_ST_WORD(d
, 0) ^ CR_ST_WORD(n
, 0) ^ ror32(CR_ST_WORD(m
, 1), 17);
504 CR_ST_WORD(d
, 0) = t
^ ror32(t
, 17) ^ ror32(t
, 9);
506 t
= CR_ST_WORD(d
, 1) ^ CR_ST_WORD(n
, 1) ^ ror32(CR_ST_WORD(m
, 2), 17);
507 CR_ST_WORD(d
, 1) = t
^ ror32(t
, 17) ^ ror32(t
, 9);
509 t
= CR_ST_WORD(d
, 2) ^ CR_ST_WORD(n
, 2) ^ ror32(CR_ST_WORD(m
, 3), 17);
510 CR_ST_WORD(d
, 2) = t
^ ror32(t
, 17) ^ ror32(t
, 9);
512 t
= CR_ST_WORD(d
, 3) ^ CR_ST_WORD(n
, 3) ^ ror32(CR_ST_WORD(d
, 0), 17);
513 CR_ST_WORD(d
, 3) = t
^ ror32(t
, 17) ^ ror32(t
, 9);
518 clear_tail_16(vd
, desc
);
521 void HELPER(crypto_sm3partw2
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
526 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
527 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
528 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
529 uint32_t t
= CR_ST_WORD(n
, 0) ^ ror32(CR_ST_WORD(m
, 0), 25);
531 CR_ST_WORD(d
, 0) ^= t
;
532 CR_ST_WORD(d
, 1) ^= CR_ST_WORD(n
, 1) ^ ror32(CR_ST_WORD(m
, 1), 25);
533 CR_ST_WORD(d
, 2) ^= CR_ST_WORD(n
, 2) ^ ror32(CR_ST_WORD(m
, 2), 25);
534 CR_ST_WORD(d
, 3) ^= CR_ST_WORD(n
, 3) ^ ror32(CR_ST_WORD(m
, 3), 25) ^
535 ror32(t
, 17) ^ ror32(t
, 2) ^ ror32(t
, 26);
540 clear_tail_16(vd
, desc
);
543 static inline void QEMU_ALWAYS_INLINE
544 crypto_sm3tt(uint64_t *rd
, uint64_t *rn
, uint64_t *rm
,
545 uint32_t desc
, uint32_t opcode
)
547 union CRYPTO_STATE d
= { .l
= { rd
[0], rd
[1] } };
548 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
549 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
550 uint32_t imm2
= simd_data(desc
);
555 if (opcode
== 0 || opcode
== 2) {
556 /* SM3TT1A, SM3TT2A */
557 t
= par(CR_ST_WORD(d
, 3), CR_ST_WORD(d
, 2), CR_ST_WORD(d
, 1));
558 } else if (opcode
== 1) {
560 t
= maj(CR_ST_WORD(d
, 3), CR_ST_WORD(d
, 2), CR_ST_WORD(d
, 1));
561 } else if (opcode
== 3) {
563 t
= cho(CR_ST_WORD(d
, 3), CR_ST_WORD(d
, 2), CR_ST_WORD(d
, 1));
565 qemu_build_not_reached();
568 t
+= CR_ST_WORD(d
, 0) + CR_ST_WORD(m
, imm2
);
570 CR_ST_WORD(d
, 0) = CR_ST_WORD(d
, 1);
573 /* SM3TT1A, SM3TT1B */
574 t
+= CR_ST_WORD(n
, 3) ^ ror32(CR_ST_WORD(d
, 3), 20);
576 CR_ST_WORD(d
, 1) = ror32(CR_ST_WORD(d
, 2), 23);
578 /* SM3TT2A, SM3TT2B */
579 t
+= CR_ST_WORD(n
, 3);
580 t
^= rol32(t
, 9) ^ rol32(t
, 17);
582 CR_ST_WORD(d
, 1) = ror32(CR_ST_WORD(d
, 2), 13);
585 CR_ST_WORD(d
, 2) = CR_ST_WORD(d
, 3);
586 CR_ST_WORD(d
, 3) = t
;
591 clear_tail_16(rd
, desc
);
594 #define DO_SM3TT(NAME, OPCODE) \
595 void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
596 { crypto_sm3tt(vd, vn, vm, desc, OPCODE); }
598 DO_SM3TT(crypto_sm3tt1a
, 0)
599 DO_SM3TT(crypto_sm3tt1b
, 1)
600 DO_SM3TT(crypto_sm3tt2a
, 2)
601 DO_SM3TT(crypto_sm3tt2b
, 3)
605 static void do_crypto_sm4e(uint64_t *rd
, uint64_t *rn
, uint64_t *rm
)
607 union CRYPTO_STATE d
= { .l
= { rn
[0], rn
[1] } };
608 union CRYPTO_STATE n
= { .l
= { rm
[0], rm
[1] } };
611 for (i
= 0; i
< 4; i
++) {
612 t
= CR_ST_WORD(d
, (i
+ 1) % 4) ^
613 CR_ST_WORD(d
, (i
+ 2) % 4) ^
614 CR_ST_WORD(d
, (i
+ 3) % 4) ^
619 CR_ST_WORD(d
, i
) ^= t
^ rol32(t
, 2) ^ rol32(t
, 10) ^ rol32(t
, 18) ^
627 void HELPER(crypto_sm4e
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
629 intptr_t i
, opr_sz
= simd_oprsz(desc
);
631 for (i
= 0; i
< opr_sz
; i
+= 16) {
632 do_crypto_sm4e(vd
+ i
, vn
+ i
, vm
+ i
);
634 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
637 static void do_crypto_sm4ekey(uint64_t *rd
, uint64_t *rn
, uint64_t *rm
)
639 union CRYPTO_STATE d
;
640 union CRYPTO_STATE n
= { .l
= { rn
[0], rn
[1] } };
641 union CRYPTO_STATE m
= { .l
= { rm
[0], rm
[1] } };
645 for (i
= 0; i
< 4; i
++) {
646 t
= CR_ST_WORD(d
, (i
+ 1) % 4) ^
647 CR_ST_WORD(d
, (i
+ 2) % 4) ^
648 CR_ST_WORD(d
, (i
+ 3) % 4) ^
653 CR_ST_WORD(d
, i
) ^= t
^ rol32(t
, 13) ^ rol32(t
, 23);
660 void HELPER(crypto_sm4ekey
)(void *vd
, void *vn
, void* vm
, uint32_t desc
)
662 intptr_t i
, opr_sz
= simd_oprsz(desc
);
664 for (i
= 0; i
< opr_sz
; i
+= 16) {
665 do_crypto_sm4ekey(vd
+ i
, vn
+ i
, vm
+ i
);
667 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));
670 void HELPER(crypto_rax1
)(void *vd
, void *vn
, void *vm
, uint32_t desc
)
672 intptr_t i
, opr_sz
= simd_oprsz(desc
);
673 uint64_t *d
= vd
, *n
= vn
, *m
= vm
;
675 for (i
= 0; i
< opr_sz
/ 8; ++i
) {
676 d
[i
] = n
[i
] ^ rol64(m
[i
], 1);
678 clear_tail(vd
, opr_sz
, simd_maxsz(desc
));