xref: /qemu/target/arm/tcg/crypto_helper.c (revision 80d6f4c6bbb718f343a832df8dee15329cc7686c)
19d935509SArd Biesheuvel /*
29d935509SArd Biesheuvel  * crypto_helper.c - emulate v8 Crypto Extensions instructions
39d935509SArd Biesheuvel  *
490b827d1SArd Biesheuvel  * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
59d935509SArd Biesheuvel  *
69d935509SArd Biesheuvel  * This library is free software; you can redistribute it and/or
79d935509SArd Biesheuvel  * modify it under the terms of the GNU Lesser General Public
89d935509SArd Biesheuvel  * License as published by the Free Software Foundation; either
99d935509SArd Biesheuvel  * version 2 of the License, or (at your option) any later version.
109d935509SArd Biesheuvel  */
119d935509SArd Biesheuvel 
1274c21bd0SPeter Maydell #include "qemu/osdep.h"
139d935509SArd Biesheuvel 
149d935509SArd Biesheuvel #include "cpu.h"
159d935509SArd Biesheuvel #include "exec/exec-all.h"
162ef6175aSRichard Henderson #include "exec/helper-proto.h"
176f2945cdSDaniel P. Berrange #include "crypto/aes.h"
189d935509SArd Biesheuvel 
19f1ecb913SArd Biesheuvel union CRYPTO_STATE {
209d935509SArd Biesheuvel     uint8_t    bytes[16];
21f1ecb913SArd Biesheuvel     uint32_t   words[4];
229d935509SArd Biesheuvel     uint64_t   l[2];
239d935509SArd Biesheuvel };
249d935509SArd Biesheuvel 
25b449ca3cSArd Biesheuvel #ifdef HOST_WORDS_BIGENDIAN
26b449ca3cSArd Biesheuvel #define CR_ST_BYTE(state, i)   (state.bytes[(15 - (i)) ^ 8])
27b449ca3cSArd Biesheuvel #define CR_ST_WORD(state, i)   (state.words[(3 - (i)) ^ 2])
28b449ca3cSArd Biesheuvel #else
29b449ca3cSArd Biesheuvel #define CR_ST_BYTE(state, i)   (state.bytes[i])
30b449ca3cSArd Biesheuvel #define CR_ST_WORD(state, i)   (state.words[i])
31b449ca3cSArd Biesheuvel #endif
32b449ca3cSArd Biesheuvel 
331a66ac61SRichard Henderson void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
349d935509SArd Biesheuvel {
3559dcd29aSTom Musta     static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
3659dcd29aSTom Musta     static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
371a66ac61SRichard Henderson     uint64_t *rd = vd;
381a66ac61SRichard Henderson     uint64_t *rm = vm;
391a66ac61SRichard Henderson     union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
401a66ac61SRichard Henderson     union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
419d935509SArd Biesheuvel     int i;
429d935509SArd Biesheuvel 
439d935509SArd Biesheuvel     assert(decrypt < 2);
449d935509SArd Biesheuvel 
459d935509SArd Biesheuvel     /* xor state vector with round key */
469d935509SArd Biesheuvel     rk.l[0] ^= st.l[0];
479d935509SArd Biesheuvel     rk.l[1] ^= st.l[1];
489d935509SArd Biesheuvel 
499d935509SArd Biesheuvel     /* combine ShiftRows operation and sbox substitution */
509d935509SArd Biesheuvel     for (i = 0; i < 16; i++) {
51b449ca3cSArd Biesheuvel         CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
529d935509SArd Biesheuvel     }
539d935509SArd Biesheuvel 
541a66ac61SRichard Henderson     rd[0] = st.l[0];
551a66ac61SRichard Henderson     rd[1] = st.l[1];
569d935509SArd Biesheuvel }
579d935509SArd Biesheuvel 
581a66ac61SRichard Henderson void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
599d935509SArd Biesheuvel {
609d935509SArd Biesheuvel     static uint32_t const mc[][256] = { {
619d935509SArd Biesheuvel         /* MixColumns lookup table */
629d935509SArd Biesheuvel         0x00000000, 0x03010102, 0x06020204, 0x05030306,
639d935509SArd Biesheuvel         0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
649d935509SArd Biesheuvel         0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
659d935509SArd Biesheuvel         0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
669d935509SArd Biesheuvel         0x30101020, 0x33111122, 0x36121224, 0x35131326,
679d935509SArd Biesheuvel         0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
689d935509SArd Biesheuvel         0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
699d935509SArd Biesheuvel         0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
709d935509SArd Biesheuvel         0x60202040, 0x63212142, 0x66222244, 0x65232346,
719d935509SArd Biesheuvel         0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
729d935509SArd Biesheuvel         0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
739d935509SArd Biesheuvel         0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
749d935509SArd Biesheuvel         0x50303060, 0x53313162, 0x56323264, 0x55333366,
759d935509SArd Biesheuvel         0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
769d935509SArd Biesheuvel         0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
779d935509SArd Biesheuvel         0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
789d935509SArd Biesheuvel         0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
799d935509SArd Biesheuvel         0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
809d935509SArd Biesheuvel         0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
819d935509SArd Biesheuvel         0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
829d935509SArd Biesheuvel         0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
839d935509SArd Biesheuvel         0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
849d935509SArd Biesheuvel         0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
859d935509SArd Biesheuvel         0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
869d935509SArd Biesheuvel         0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
879d935509SArd Biesheuvel         0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
889d935509SArd Biesheuvel         0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
899d935509SArd Biesheuvel         0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
909d935509SArd Biesheuvel         0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
919d935509SArd Biesheuvel         0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
929d935509SArd Biesheuvel         0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
939d935509SArd Biesheuvel         0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
949d935509SArd Biesheuvel         0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
959d935509SArd Biesheuvel         0x97848413, 0x94858511, 0x91868617, 0x92878715,
969d935509SArd Biesheuvel         0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
979d935509SArd Biesheuvel         0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
989d935509SArd Biesheuvel         0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
999d935509SArd Biesheuvel         0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
1009d935509SArd Biesheuvel         0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
1019d935509SArd Biesheuvel         0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
1029d935509SArd Biesheuvel         0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
1039d935509SArd Biesheuvel         0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
1049d935509SArd Biesheuvel         0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
1059d935509SArd Biesheuvel         0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
1069d935509SArd Biesheuvel         0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
1079d935509SArd Biesheuvel         0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
1089d935509SArd Biesheuvel         0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
1099d935509SArd Biesheuvel         0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
1109d935509SArd Biesheuvel         0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
1119d935509SArd Biesheuvel         0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
1129d935509SArd Biesheuvel         0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
1139d935509SArd Biesheuvel         0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
1149d935509SArd Biesheuvel         0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
1159d935509SArd Biesheuvel         0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
1169d935509SArd Biesheuvel         0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
1179d935509SArd Biesheuvel         0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
1189d935509SArd Biesheuvel         0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
1199d935509SArd Biesheuvel         0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
1209d935509SArd Biesheuvel         0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
1219d935509SArd Biesheuvel         0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
1229d935509SArd Biesheuvel         0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
1239d935509SArd Biesheuvel         0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
1249d935509SArd Biesheuvel         0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
1259d935509SArd Biesheuvel         0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
1269d935509SArd Biesheuvel     }, {
1279d935509SArd Biesheuvel         /* Inverse MixColumns lookup table */
1289d935509SArd Biesheuvel         0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
1299d935509SArd Biesheuvel         0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
1309d935509SArd Biesheuvel         0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
1319d935509SArd Biesheuvel         0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
1329d935509SArd Biesheuvel         0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
1339d935509SArd Biesheuvel         0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
1349d935509SArd Biesheuvel         0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
1359d935509SArd Biesheuvel         0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
1369d935509SArd Biesheuvel         0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
1379d935509SArd Biesheuvel         0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
1389d935509SArd Biesheuvel         0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
1399d935509SArd Biesheuvel         0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
1409d935509SArd Biesheuvel         0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
1419d935509SArd Biesheuvel         0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
1429d935509SArd Biesheuvel         0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
1439d935509SArd Biesheuvel         0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
1449d935509SArd Biesheuvel         0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
1459d935509SArd Biesheuvel         0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
1469d935509SArd Biesheuvel         0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
1479d935509SArd Biesheuvel         0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
1489d935509SArd Biesheuvel         0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
1499d935509SArd Biesheuvel         0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
1509d935509SArd Biesheuvel         0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
1519d935509SArd Biesheuvel         0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
1529d935509SArd Biesheuvel         0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
1539d935509SArd Biesheuvel         0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
1549d935509SArd Biesheuvel         0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
1559d935509SArd Biesheuvel         0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
1569d935509SArd Biesheuvel         0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
1579d935509SArd Biesheuvel         0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
1589d935509SArd Biesheuvel         0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
1599d935509SArd Biesheuvel         0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
1609d935509SArd Biesheuvel         0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
1619d935509SArd Biesheuvel         0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
1629d935509SArd Biesheuvel         0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
1639d935509SArd Biesheuvel         0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
1649d935509SArd Biesheuvel         0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
1659d935509SArd Biesheuvel         0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
1669d935509SArd Biesheuvel         0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
1679d935509SArd Biesheuvel         0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
1689d935509SArd Biesheuvel         0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
1699d935509SArd Biesheuvel         0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
1709d935509SArd Biesheuvel         0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
1719d935509SArd Biesheuvel         0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
1729d935509SArd Biesheuvel         0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
1739d935509SArd Biesheuvel         0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
1749d935509SArd Biesheuvel         0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
1759d935509SArd Biesheuvel         0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
1769d935509SArd Biesheuvel         0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
1779d935509SArd Biesheuvel         0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
1789d935509SArd Biesheuvel         0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
1799d935509SArd Biesheuvel         0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
1809d935509SArd Biesheuvel         0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
1819d935509SArd Biesheuvel         0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
1829d935509SArd Biesheuvel         0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
1839d935509SArd Biesheuvel         0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
1849d935509SArd Biesheuvel         0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
1859d935509SArd Biesheuvel         0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
1869d935509SArd Biesheuvel         0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
1879d935509SArd Biesheuvel         0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
1889d935509SArd Biesheuvel         0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
1899d935509SArd Biesheuvel         0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
1909d935509SArd Biesheuvel         0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
1919d935509SArd Biesheuvel         0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
1929d935509SArd Biesheuvel     } };
1931a66ac61SRichard Henderson 
1941a66ac61SRichard Henderson     uint64_t *rd = vd;
1951a66ac61SRichard Henderson     uint64_t *rm = vm;
1961a66ac61SRichard Henderson     union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
1979d935509SArd Biesheuvel     int i;
1989d935509SArd Biesheuvel 
1999d935509SArd Biesheuvel     assert(decrypt < 2);
2009d935509SArd Biesheuvel 
2019d935509SArd Biesheuvel     for (i = 0; i < 16; i += 4) {
202b449ca3cSArd Biesheuvel         CR_ST_WORD(st, i >> 2) =
203b449ca3cSArd Biesheuvel             mc[decrypt][CR_ST_BYTE(st, i)] ^
204b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 1)], 8) ^
205b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 2)], 16) ^
206b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
2079d935509SArd Biesheuvel     }
2089d935509SArd Biesheuvel 
2091a66ac61SRichard Henderson     rd[0] = st.l[0];
2101a66ac61SRichard Henderson     rd[1] = st.l[1];
2119d935509SArd Biesheuvel }
212f1ecb913SArd Biesheuvel 
213f1ecb913SArd Biesheuvel /*
214f1ecb913SArd Biesheuvel  * SHA-1 logical functions
215f1ecb913SArd Biesheuvel  */
216f1ecb913SArd Biesheuvel 
217f1ecb913SArd Biesheuvel static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
218f1ecb913SArd Biesheuvel {
219f1ecb913SArd Biesheuvel     return (x & (y ^ z)) ^ z;
220f1ecb913SArd Biesheuvel }
221f1ecb913SArd Biesheuvel 
222f1ecb913SArd Biesheuvel static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
223f1ecb913SArd Biesheuvel {
224f1ecb913SArd Biesheuvel     return x ^ y ^ z;
225f1ecb913SArd Biesheuvel }
226f1ecb913SArd Biesheuvel 
227f1ecb913SArd Biesheuvel static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
228f1ecb913SArd Biesheuvel {
229f1ecb913SArd Biesheuvel     return (x & y) | ((x | y) & z);
230f1ecb913SArd Biesheuvel }
231f1ecb913SArd Biesheuvel 
2321a66ac61SRichard Henderson void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
233f1ecb913SArd Biesheuvel {
2341a66ac61SRichard Henderson     uint64_t *rd = vd;
2351a66ac61SRichard Henderson     uint64_t *rn = vn;
2361a66ac61SRichard Henderson     uint64_t *rm = vm;
2371a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
2381a66ac61SRichard Henderson     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
2391a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
240f1ecb913SArd Biesheuvel 
241f1ecb913SArd Biesheuvel     if (op == 3) { /* sha1su0 */
242f1ecb913SArd Biesheuvel         d.l[0] ^= d.l[1] ^ m.l[0];
243f1ecb913SArd Biesheuvel         d.l[1] ^= n.l[0] ^ m.l[1];
244f1ecb913SArd Biesheuvel     } else {
245f1ecb913SArd Biesheuvel         int i;
246f1ecb913SArd Biesheuvel 
247f1ecb913SArd Biesheuvel         for (i = 0; i < 4; i++) {
248f1ecb913SArd Biesheuvel             uint32_t t;
249f1ecb913SArd Biesheuvel 
250f1ecb913SArd Biesheuvel             switch (op) {
251f1ecb913SArd Biesheuvel             case 0: /* sha1c */
252b449ca3cSArd Biesheuvel                 t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
253f1ecb913SArd Biesheuvel                 break;
254f1ecb913SArd Biesheuvel             case 1: /* sha1p */
255b449ca3cSArd Biesheuvel                 t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
256f1ecb913SArd Biesheuvel                 break;
257f1ecb913SArd Biesheuvel             case 2: /* sha1m */
258b449ca3cSArd Biesheuvel                 t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
259f1ecb913SArd Biesheuvel                 break;
260f1ecb913SArd Biesheuvel             default:
261f1ecb913SArd Biesheuvel                 g_assert_not_reached();
262f1ecb913SArd Biesheuvel             }
263b449ca3cSArd Biesheuvel             t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
264b449ca3cSArd Biesheuvel                  + CR_ST_WORD(m, i);
265f1ecb913SArd Biesheuvel 
266b449ca3cSArd Biesheuvel             CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
267b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
268b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
269b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
270b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 0) = t;
271f1ecb913SArd Biesheuvel         }
272f1ecb913SArd Biesheuvel     }
2731a66ac61SRichard Henderson     rd[0] = d.l[0];
2741a66ac61SRichard Henderson     rd[1] = d.l[1];
275f1ecb913SArd Biesheuvel }
276f1ecb913SArd Biesheuvel 
2771a66ac61SRichard Henderson void HELPER(crypto_sha1h)(void *vd, void *vm)
278f1ecb913SArd Biesheuvel {
2791a66ac61SRichard Henderson     uint64_t *rd = vd;
2801a66ac61SRichard Henderson     uint64_t *rm = vm;
2811a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
282f1ecb913SArd Biesheuvel 
283b449ca3cSArd Biesheuvel     CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
284b449ca3cSArd Biesheuvel     CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
285f1ecb913SArd Biesheuvel 
2861a66ac61SRichard Henderson     rd[0] = m.l[0];
2871a66ac61SRichard Henderson     rd[1] = m.l[1];
288f1ecb913SArd Biesheuvel }
289f1ecb913SArd Biesheuvel 
2901a66ac61SRichard Henderson void HELPER(crypto_sha1su1)(void *vd, void *vm)
291f1ecb913SArd Biesheuvel {
2921a66ac61SRichard Henderson     uint64_t *rd = vd;
2931a66ac61SRichard Henderson     uint64_t *rm = vm;
2941a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
2951a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
296f1ecb913SArd Biesheuvel 
297b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
298b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
299b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
300b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
301f1ecb913SArd Biesheuvel 
3021a66ac61SRichard Henderson     rd[0] = d.l[0];
3031a66ac61SRichard Henderson     rd[1] = d.l[1];
304f1ecb913SArd Biesheuvel }
305f1ecb913SArd Biesheuvel 
306f1ecb913SArd Biesheuvel /*
307f1ecb913SArd Biesheuvel  * The SHA-256 logical functions, according to
308f1ecb913SArd Biesheuvel  * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
309f1ecb913SArd Biesheuvel  */
310f1ecb913SArd Biesheuvel 
311f1ecb913SArd Biesheuvel static uint32_t S0(uint32_t x)
312f1ecb913SArd Biesheuvel {
313f1ecb913SArd Biesheuvel     return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
314f1ecb913SArd Biesheuvel }
315f1ecb913SArd Biesheuvel 
316f1ecb913SArd Biesheuvel static uint32_t S1(uint32_t x)
317f1ecb913SArd Biesheuvel {
318f1ecb913SArd Biesheuvel     return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
319f1ecb913SArd Biesheuvel }
320f1ecb913SArd Biesheuvel 
321f1ecb913SArd Biesheuvel static uint32_t s0(uint32_t x)
322f1ecb913SArd Biesheuvel {
323f1ecb913SArd Biesheuvel     return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
324f1ecb913SArd Biesheuvel }
325f1ecb913SArd Biesheuvel 
326f1ecb913SArd Biesheuvel static uint32_t s1(uint32_t x)
327f1ecb913SArd Biesheuvel {
328f1ecb913SArd Biesheuvel     return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
329f1ecb913SArd Biesheuvel }
330f1ecb913SArd Biesheuvel 
3311a66ac61SRichard Henderson void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
332f1ecb913SArd Biesheuvel {
3331a66ac61SRichard Henderson     uint64_t *rd = vd;
3341a66ac61SRichard Henderson     uint64_t *rn = vn;
3351a66ac61SRichard Henderson     uint64_t *rm = vm;
3361a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
3371a66ac61SRichard Henderson     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
3381a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
339f1ecb913SArd Biesheuvel     int i;
340f1ecb913SArd Biesheuvel 
341f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
342b449ca3cSArd Biesheuvel         uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2))
343b449ca3cSArd Biesheuvel                      + CR_ST_WORD(n, 3) + S1(CR_ST_WORD(n, 0))
344b449ca3cSArd Biesheuvel                      + CR_ST_WORD(m, i);
345f1ecb913SArd Biesheuvel 
346b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 3) = CR_ST_WORD(n, 2);
347b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 2) = CR_ST_WORD(n, 1);
348b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 1) = CR_ST_WORD(n, 0);
349b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3) + t;
350f1ecb913SArd Biesheuvel 
351b449ca3cSArd Biesheuvel         t += maj(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
352b449ca3cSArd Biesheuvel              + S0(CR_ST_WORD(d, 0));
353f1ecb913SArd Biesheuvel 
354b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
355b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
356b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
357b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 0) = t;
358f1ecb913SArd Biesheuvel     }
359f1ecb913SArd Biesheuvel 
3601a66ac61SRichard Henderson     rd[0] = d.l[0];
3611a66ac61SRichard Henderson     rd[1] = d.l[1];
362f1ecb913SArd Biesheuvel }
363f1ecb913SArd Biesheuvel 
3641a66ac61SRichard Henderson void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
365f1ecb913SArd Biesheuvel {
3661a66ac61SRichard Henderson     uint64_t *rd = vd;
3671a66ac61SRichard Henderson     uint64_t *rn = vn;
3681a66ac61SRichard Henderson     uint64_t *rm = vm;
3691a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
3701a66ac61SRichard Henderson     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
3711a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
372f1ecb913SArd Biesheuvel     int i;
373f1ecb913SArd Biesheuvel 
374f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
375b449ca3cSArd Biesheuvel         uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
376b449ca3cSArd Biesheuvel                      + CR_ST_WORD(d, 3) + S1(CR_ST_WORD(d, 0))
377b449ca3cSArd Biesheuvel                      + CR_ST_WORD(m, i);
378f1ecb913SArd Biesheuvel 
379b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
380b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
381b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
382b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
383f1ecb913SArd Biesheuvel     }
384f1ecb913SArd Biesheuvel 
3851a66ac61SRichard Henderson     rd[0] = d.l[0];
3861a66ac61SRichard Henderson     rd[1] = d.l[1];
387f1ecb913SArd Biesheuvel }
388f1ecb913SArd Biesheuvel 
3891a66ac61SRichard Henderson void HELPER(crypto_sha256su0)(void *vd, void *vm)
390f1ecb913SArd Biesheuvel {
3911a66ac61SRichard Henderson     uint64_t *rd = vd;
3921a66ac61SRichard Henderson     uint64_t *rm = vm;
3931a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
3941a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
395f1ecb913SArd Biesheuvel 
396b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
397b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
398b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
399b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
400f1ecb913SArd Biesheuvel 
4011a66ac61SRichard Henderson     rd[0] = d.l[0];
4021a66ac61SRichard Henderson     rd[1] = d.l[1];
403f1ecb913SArd Biesheuvel }
404f1ecb913SArd Biesheuvel 
4051a66ac61SRichard Henderson void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
406f1ecb913SArd Biesheuvel {
4071a66ac61SRichard Henderson     uint64_t *rd = vd;
4081a66ac61SRichard Henderson     uint64_t *rn = vn;
4091a66ac61SRichard Henderson     uint64_t *rm = vm;
4101a66ac61SRichard Henderson     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
4111a66ac61SRichard Henderson     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
4121a66ac61SRichard Henderson     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
413f1ecb913SArd Biesheuvel 
414b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
415b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
416b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
417b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
418f1ecb913SArd Biesheuvel 
4191a66ac61SRichard Henderson     rd[0] = d.l[0];
4201a66ac61SRichard Henderson     rd[1] = d.l[1];
421f1ecb913SArd Biesheuvel }
42290b827d1SArd Biesheuvel 
42390b827d1SArd Biesheuvel /*
42490b827d1SArd Biesheuvel  * The SHA-512 logical functions (same as above but using 64-bit operands)
42590b827d1SArd Biesheuvel  */
42690b827d1SArd Biesheuvel 
42790b827d1SArd Biesheuvel static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
42890b827d1SArd Biesheuvel {
42990b827d1SArd Biesheuvel     return (x & (y ^ z)) ^ z;
43090b827d1SArd Biesheuvel }
43190b827d1SArd Biesheuvel 
43290b827d1SArd Biesheuvel static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
43390b827d1SArd Biesheuvel {
43490b827d1SArd Biesheuvel     return (x & y) | ((x | y) & z);
43590b827d1SArd Biesheuvel }
43690b827d1SArd Biesheuvel 
43790b827d1SArd Biesheuvel static uint64_t S0_512(uint64_t x)
43890b827d1SArd Biesheuvel {
43990b827d1SArd Biesheuvel     return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
44090b827d1SArd Biesheuvel }
44190b827d1SArd Biesheuvel 
44290b827d1SArd Biesheuvel static uint64_t S1_512(uint64_t x)
44390b827d1SArd Biesheuvel {
44490b827d1SArd Biesheuvel     return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
44590b827d1SArd Biesheuvel }
44690b827d1SArd Biesheuvel 
44790b827d1SArd Biesheuvel static uint64_t s0_512(uint64_t x)
44890b827d1SArd Biesheuvel {
44990b827d1SArd Biesheuvel     return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
45090b827d1SArd Biesheuvel }
45190b827d1SArd Biesheuvel 
45290b827d1SArd Biesheuvel static uint64_t s1_512(uint64_t x)
45390b827d1SArd Biesheuvel {
45490b827d1SArd Biesheuvel     return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
45590b827d1SArd Biesheuvel }
45690b827d1SArd Biesheuvel 
45790b827d1SArd Biesheuvel void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
45890b827d1SArd Biesheuvel {
45990b827d1SArd Biesheuvel     uint64_t *rd = vd;
46090b827d1SArd Biesheuvel     uint64_t *rn = vn;
46190b827d1SArd Biesheuvel     uint64_t *rm = vm;
46290b827d1SArd Biesheuvel     uint64_t d0 = rd[0];
46390b827d1SArd Biesheuvel     uint64_t d1 = rd[1];
46490b827d1SArd Biesheuvel 
46590b827d1SArd Biesheuvel     d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
46690b827d1SArd Biesheuvel     d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
46790b827d1SArd Biesheuvel 
46890b827d1SArd Biesheuvel     rd[0] = d0;
46990b827d1SArd Biesheuvel     rd[1] = d1;
47090b827d1SArd Biesheuvel }
47190b827d1SArd Biesheuvel 
47290b827d1SArd Biesheuvel void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
47390b827d1SArd Biesheuvel {
47490b827d1SArd Biesheuvel     uint64_t *rd = vd;
47590b827d1SArd Biesheuvel     uint64_t *rn = vn;
47690b827d1SArd Biesheuvel     uint64_t *rm = vm;
47790b827d1SArd Biesheuvel     uint64_t d0 = rd[0];
47890b827d1SArd Biesheuvel     uint64_t d1 = rd[1];
47990b827d1SArd Biesheuvel 
48090b827d1SArd Biesheuvel     d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
48190b827d1SArd Biesheuvel     d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
48290b827d1SArd Biesheuvel 
48390b827d1SArd Biesheuvel     rd[0] = d0;
48490b827d1SArd Biesheuvel     rd[1] = d1;
48590b827d1SArd Biesheuvel }
48690b827d1SArd Biesheuvel 
48790b827d1SArd Biesheuvel void HELPER(crypto_sha512su0)(void *vd, void *vn)
48890b827d1SArd Biesheuvel {
48990b827d1SArd Biesheuvel     uint64_t *rd = vd;
49090b827d1SArd Biesheuvel     uint64_t *rn = vn;
49190b827d1SArd Biesheuvel     uint64_t d0 = rd[0];
49290b827d1SArd Biesheuvel     uint64_t d1 = rd[1];
49390b827d1SArd Biesheuvel 
49490b827d1SArd Biesheuvel     d0 += s0_512(rd[1]);
49590b827d1SArd Biesheuvel     d1 += s0_512(rn[0]);
49690b827d1SArd Biesheuvel 
49790b827d1SArd Biesheuvel     rd[0] = d0;
49890b827d1SArd Biesheuvel     rd[1] = d1;
49990b827d1SArd Biesheuvel }
50090b827d1SArd Biesheuvel 
50190b827d1SArd Biesheuvel void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
50290b827d1SArd Biesheuvel {
50390b827d1SArd Biesheuvel     uint64_t *rd = vd;
50490b827d1SArd Biesheuvel     uint64_t *rn = vn;
50590b827d1SArd Biesheuvel     uint64_t *rm = vm;
50690b827d1SArd Biesheuvel 
50790b827d1SArd Biesheuvel     rd[0] += s1_512(rn[0]) + rm[0];
50890b827d1SArd Biesheuvel     rd[1] += s1_512(rn[1]) + rm[1];
50990b827d1SArd Biesheuvel }
510*80d6f4c6SArd Biesheuvel 
511*80d6f4c6SArd Biesheuvel void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
512*80d6f4c6SArd Biesheuvel {
513*80d6f4c6SArd Biesheuvel     uint64_t *rd = vd;
514*80d6f4c6SArd Biesheuvel     uint64_t *rn = vn;
515*80d6f4c6SArd Biesheuvel     uint64_t *rm = vm;
516*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
517*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
518*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
519*80d6f4c6SArd Biesheuvel     uint32_t t;
520*80d6f4c6SArd Biesheuvel 
521*80d6f4c6SArd Biesheuvel     t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
522*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
523*80d6f4c6SArd Biesheuvel 
524*80d6f4c6SArd Biesheuvel     t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
525*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
526*80d6f4c6SArd Biesheuvel 
527*80d6f4c6SArd Biesheuvel     t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
528*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
529*80d6f4c6SArd Biesheuvel 
530*80d6f4c6SArd Biesheuvel     t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
531*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
532*80d6f4c6SArd Biesheuvel 
533*80d6f4c6SArd Biesheuvel     rd[0] = d.l[0];
534*80d6f4c6SArd Biesheuvel     rd[1] = d.l[1];
535*80d6f4c6SArd Biesheuvel }
536*80d6f4c6SArd Biesheuvel 
537*80d6f4c6SArd Biesheuvel void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
538*80d6f4c6SArd Biesheuvel {
539*80d6f4c6SArd Biesheuvel     uint64_t *rd = vd;
540*80d6f4c6SArd Biesheuvel     uint64_t *rn = vn;
541*80d6f4c6SArd Biesheuvel     uint64_t *rm = vm;
542*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
543*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
544*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
545*80d6f4c6SArd Biesheuvel     uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
546*80d6f4c6SArd Biesheuvel 
547*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 0) ^= t;
548*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
549*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
550*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
551*80d6f4c6SArd Biesheuvel                         ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
552*80d6f4c6SArd Biesheuvel 
553*80d6f4c6SArd Biesheuvel     rd[0] = d.l[0];
554*80d6f4c6SArd Biesheuvel     rd[1] = d.l[1];
555*80d6f4c6SArd Biesheuvel }
556*80d6f4c6SArd Biesheuvel 
557*80d6f4c6SArd Biesheuvel void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
558*80d6f4c6SArd Biesheuvel                           uint32_t opcode)
559*80d6f4c6SArd Biesheuvel {
560*80d6f4c6SArd Biesheuvel     uint64_t *rd = vd;
561*80d6f4c6SArd Biesheuvel     uint64_t *rn = vn;
562*80d6f4c6SArd Biesheuvel     uint64_t *rm = vm;
563*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
564*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
565*80d6f4c6SArd Biesheuvel     union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
566*80d6f4c6SArd Biesheuvel     uint32_t t;
567*80d6f4c6SArd Biesheuvel 
568*80d6f4c6SArd Biesheuvel     assert(imm2 < 4);
569*80d6f4c6SArd Biesheuvel 
570*80d6f4c6SArd Biesheuvel     if (opcode == 0 || opcode == 2) {
571*80d6f4c6SArd Biesheuvel         /* SM3TT1A, SM3TT2A */
572*80d6f4c6SArd Biesheuvel         t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
573*80d6f4c6SArd Biesheuvel     } else if (opcode == 1) {
574*80d6f4c6SArd Biesheuvel         /* SM3TT1B */
575*80d6f4c6SArd Biesheuvel         t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
576*80d6f4c6SArd Biesheuvel     } else if (opcode == 3) {
577*80d6f4c6SArd Biesheuvel         /* SM3TT2B */
578*80d6f4c6SArd Biesheuvel         t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
579*80d6f4c6SArd Biesheuvel     } else {
580*80d6f4c6SArd Biesheuvel         g_assert_not_reached();
581*80d6f4c6SArd Biesheuvel     }
582*80d6f4c6SArd Biesheuvel 
583*80d6f4c6SArd Biesheuvel     t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
584*80d6f4c6SArd Biesheuvel 
585*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
586*80d6f4c6SArd Biesheuvel 
587*80d6f4c6SArd Biesheuvel     if (opcode < 2) {
588*80d6f4c6SArd Biesheuvel         /* SM3TT1A, SM3TT1B */
589*80d6f4c6SArd Biesheuvel         t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
590*80d6f4c6SArd Biesheuvel 
591*80d6f4c6SArd Biesheuvel         CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
592*80d6f4c6SArd Biesheuvel     } else {
593*80d6f4c6SArd Biesheuvel         /* SM3TT2A, SM3TT2B */
594*80d6f4c6SArd Biesheuvel         t += CR_ST_WORD(n, 3);
595*80d6f4c6SArd Biesheuvel         t ^= rol32(t, 9) ^ rol32(t, 17);
596*80d6f4c6SArd Biesheuvel 
597*80d6f4c6SArd Biesheuvel         CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
598*80d6f4c6SArd Biesheuvel     }
599*80d6f4c6SArd Biesheuvel 
600*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
601*80d6f4c6SArd Biesheuvel     CR_ST_WORD(d, 3) = t;
602*80d6f4c6SArd Biesheuvel 
603*80d6f4c6SArd Biesheuvel     rd[0] = d.l[0];
604*80d6f4c6SArd Biesheuvel     rd[1] = d.l[1];
605*80d6f4c6SArd Biesheuvel }
606