xref: /qemu/target/arm/tcg/crypto_helper.c (revision 6f2945cde60545aae7f31ab9d5ef29531efbc94f)
19d935509SArd Biesheuvel /*
29d935509SArd Biesheuvel  * crypto_helper.c - emulate v8 Crypto Extensions instructions
39d935509SArd Biesheuvel  *
4f1ecb913SArd Biesheuvel  * Copyright (C) 2013 - 2014 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 
129d935509SArd Biesheuvel #include <stdlib.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 
339d935509SArd Biesheuvel void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
349d935509SArd Biesheuvel                          uint32_t decrypt)
359d935509SArd Biesheuvel {
3659dcd29aSTom Musta     static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
3759dcd29aSTom Musta     static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
3859dcd29aSTom Musta 
39f1ecb913SArd Biesheuvel     union CRYPTO_STATE rk = { .l = {
409d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
419d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
429d935509SArd Biesheuvel     } };
43f1ecb913SArd Biesheuvel     union CRYPTO_STATE st = { .l = {
449d935509SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
459d935509SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
469d935509SArd Biesheuvel     } };
479d935509SArd Biesheuvel     int i;
489d935509SArd Biesheuvel 
499d935509SArd Biesheuvel     assert(decrypt < 2);
509d935509SArd Biesheuvel 
519d935509SArd Biesheuvel     /* xor state vector with round key */
529d935509SArd Biesheuvel     rk.l[0] ^= st.l[0];
539d935509SArd Biesheuvel     rk.l[1] ^= st.l[1];
549d935509SArd Biesheuvel 
559d935509SArd Biesheuvel     /* combine ShiftRows operation and sbox substitution */
569d935509SArd Biesheuvel     for (i = 0; i < 16; i++) {
57b449ca3cSArd Biesheuvel         CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
589d935509SArd Biesheuvel     }
599d935509SArd Biesheuvel 
609d935509SArd Biesheuvel     env->vfp.regs[rd] = make_float64(st.l[0]);
619d935509SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(st.l[1]);
629d935509SArd Biesheuvel }
639d935509SArd Biesheuvel 
649d935509SArd Biesheuvel void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
659d935509SArd Biesheuvel                           uint32_t decrypt)
669d935509SArd Biesheuvel {
679d935509SArd Biesheuvel     static uint32_t const mc[][256] = { {
689d935509SArd Biesheuvel         /* MixColumns lookup table */
699d935509SArd Biesheuvel         0x00000000, 0x03010102, 0x06020204, 0x05030306,
709d935509SArd Biesheuvel         0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
719d935509SArd Biesheuvel         0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
729d935509SArd Biesheuvel         0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
739d935509SArd Biesheuvel         0x30101020, 0x33111122, 0x36121224, 0x35131326,
749d935509SArd Biesheuvel         0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
759d935509SArd Biesheuvel         0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
769d935509SArd Biesheuvel         0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
779d935509SArd Biesheuvel         0x60202040, 0x63212142, 0x66222244, 0x65232346,
789d935509SArd Biesheuvel         0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
799d935509SArd Biesheuvel         0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
809d935509SArd Biesheuvel         0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
819d935509SArd Biesheuvel         0x50303060, 0x53313162, 0x56323264, 0x55333366,
829d935509SArd Biesheuvel         0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
839d935509SArd Biesheuvel         0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
849d935509SArd Biesheuvel         0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
859d935509SArd Biesheuvel         0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
869d935509SArd Biesheuvel         0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
879d935509SArd Biesheuvel         0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
889d935509SArd Biesheuvel         0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
899d935509SArd Biesheuvel         0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
909d935509SArd Biesheuvel         0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
919d935509SArd Biesheuvel         0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
929d935509SArd Biesheuvel         0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
939d935509SArd Biesheuvel         0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
949d935509SArd Biesheuvel         0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
959d935509SArd Biesheuvel         0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
969d935509SArd Biesheuvel         0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
979d935509SArd Biesheuvel         0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
989d935509SArd Biesheuvel         0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
999d935509SArd Biesheuvel         0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
1009d935509SArd Biesheuvel         0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
1019d935509SArd Biesheuvel         0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
1029d935509SArd Biesheuvel         0x97848413, 0x94858511, 0x91868617, 0x92878715,
1039d935509SArd Biesheuvel         0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
1049d935509SArd Biesheuvel         0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
1059d935509SArd Biesheuvel         0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
1069d935509SArd Biesheuvel         0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
1079d935509SArd Biesheuvel         0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
1089d935509SArd Biesheuvel         0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
1099d935509SArd Biesheuvel         0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
1109d935509SArd Biesheuvel         0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
1119d935509SArd Biesheuvel         0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
1129d935509SArd Biesheuvel         0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
1139d935509SArd Biesheuvel         0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
1149d935509SArd Biesheuvel         0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
1159d935509SArd Biesheuvel         0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
1169d935509SArd Biesheuvel         0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
1179d935509SArd Biesheuvel         0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
1189d935509SArd Biesheuvel         0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
1199d935509SArd Biesheuvel         0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
1209d935509SArd Biesheuvel         0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
1219d935509SArd Biesheuvel         0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
1229d935509SArd Biesheuvel         0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
1239d935509SArd Biesheuvel         0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
1249d935509SArd Biesheuvel         0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
1259d935509SArd Biesheuvel         0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
1269d935509SArd Biesheuvel         0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
1279d935509SArd Biesheuvel         0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
1289d935509SArd Biesheuvel         0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
1299d935509SArd Biesheuvel         0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
1309d935509SArd Biesheuvel         0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
1319d935509SArd Biesheuvel         0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
1329d935509SArd Biesheuvel         0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
1339d935509SArd Biesheuvel     }, {
1349d935509SArd Biesheuvel         /* Inverse MixColumns lookup table */
1359d935509SArd Biesheuvel         0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
1369d935509SArd Biesheuvel         0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
1379d935509SArd Biesheuvel         0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
1389d935509SArd Biesheuvel         0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
1399d935509SArd Biesheuvel         0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
1409d935509SArd Biesheuvel         0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
1419d935509SArd Biesheuvel         0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
1429d935509SArd Biesheuvel         0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
1439d935509SArd Biesheuvel         0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
1449d935509SArd Biesheuvel         0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
1459d935509SArd Biesheuvel         0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
1469d935509SArd Biesheuvel         0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
1479d935509SArd Biesheuvel         0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
1489d935509SArd Biesheuvel         0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
1499d935509SArd Biesheuvel         0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
1509d935509SArd Biesheuvel         0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
1519d935509SArd Biesheuvel         0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
1529d935509SArd Biesheuvel         0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
1539d935509SArd Biesheuvel         0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
1549d935509SArd Biesheuvel         0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
1559d935509SArd Biesheuvel         0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
1569d935509SArd Biesheuvel         0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
1579d935509SArd Biesheuvel         0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
1589d935509SArd Biesheuvel         0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
1599d935509SArd Biesheuvel         0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
1609d935509SArd Biesheuvel         0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
1619d935509SArd Biesheuvel         0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
1629d935509SArd Biesheuvel         0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
1639d935509SArd Biesheuvel         0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
1649d935509SArd Biesheuvel         0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
1659d935509SArd Biesheuvel         0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
1669d935509SArd Biesheuvel         0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
1679d935509SArd Biesheuvel         0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
1689d935509SArd Biesheuvel         0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
1699d935509SArd Biesheuvel         0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
1709d935509SArd Biesheuvel         0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
1719d935509SArd Biesheuvel         0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
1729d935509SArd Biesheuvel         0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
1739d935509SArd Biesheuvel         0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
1749d935509SArd Biesheuvel         0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
1759d935509SArd Biesheuvel         0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
1769d935509SArd Biesheuvel         0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
1779d935509SArd Biesheuvel         0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
1789d935509SArd Biesheuvel         0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
1799d935509SArd Biesheuvel         0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
1809d935509SArd Biesheuvel         0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
1819d935509SArd Biesheuvel         0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
1829d935509SArd Biesheuvel         0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
1839d935509SArd Biesheuvel         0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
1849d935509SArd Biesheuvel         0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
1859d935509SArd Biesheuvel         0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
1869d935509SArd Biesheuvel         0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
1879d935509SArd Biesheuvel         0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
1889d935509SArd Biesheuvel         0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
1899d935509SArd Biesheuvel         0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
1909d935509SArd Biesheuvel         0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
1919d935509SArd Biesheuvel         0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
1929d935509SArd Biesheuvel         0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
1939d935509SArd Biesheuvel         0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
1949d935509SArd Biesheuvel         0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
1959d935509SArd Biesheuvel         0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
1969d935509SArd Biesheuvel         0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
1979d935509SArd Biesheuvel         0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
1989d935509SArd Biesheuvel         0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
1999d935509SArd Biesheuvel     } };
200f1ecb913SArd Biesheuvel     union CRYPTO_STATE st = { .l = {
2019d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
2029d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
2039d935509SArd Biesheuvel     } };
2049d935509SArd Biesheuvel     int i;
2059d935509SArd Biesheuvel 
2069d935509SArd Biesheuvel     assert(decrypt < 2);
2079d935509SArd Biesheuvel 
2089d935509SArd Biesheuvel     for (i = 0; i < 16; i += 4) {
209b449ca3cSArd Biesheuvel         CR_ST_WORD(st, i >> 2) =
210b449ca3cSArd Biesheuvel             mc[decrypt][CR_ST_BYTE(st, i)] ^
211b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 1)], 8) ^
212b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 2)], 16) ^
213b449ca3cSArd Biesheuvel             rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
2149d935509SArd Biesheuvel     }
2159d935509SArd Biesheuvel 
2169d935509SArd Biesheuvel     env->vfp.regs[rd] = make_float64(st.l[0]);
2179d935509SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(st.l[1]);
2189d935509SArd Biesheuvel }
219f1ecb913SArd Biesheuvel 
220f1ecb913SArd Biesheuvel /*
221f1ecb913SArd Biesheuvel  * SHA-1 logical functions
222f1ecb913SArd Biesheuvel  */
223f1ecb913SArd Biesheuvel 
224f1ecb913SArd Biesheuvel static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
225f1ecb913SArd Biesheuvel {
226f1ecb913SArd Biesheuvel     return (x & (y ^ z)) ^ z;
227f1ecb913SArd Biesheuvel }
228f1ecb913SArd Biesheuvel 
229f1ecb913SArd Biesheuvel static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
230f1ecb913SArd Biesheuvel {
231f1ecb913SArd Biesheuvel     return x ^ y ^ z;
232f1ecb913SArd Biesheuvel }
233f1ecb913SArd Biesheuvel 
234f1ecb913SArd Biesheuvel static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
235f1ecb913SArd Biesheuvel {
236f1ecb913SArd Biesheuvel     return (x & y) | ((x | y) & z);
237f1ecb913SArd Biesheuvel }
238f1ecb913SArd Biesheuvel 
239f1ecb913SArd Biesheuvel void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
240f1ecb913SArd Biesheuvel                               uint32_t rm, uint32_t op)
241f1ecb913SArd Biesheuvel {
242f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
243f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
244f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
245f1ecb913SArd Biesheuvel     } };
246f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
247f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
248f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
249f1ecb913SArd Biesheuvel     } };
250f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
251f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
252f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
253f1ecb913SArd Biesheuvel     } };
254f1ecb913SArd Biesheuvel 
255f1ecb913SArd Biesheuvel     if (op == 3) { /* sha1su0 */
256f1ecb913SArd Biesheuvel         d.l[0] ^= d.l[1] ^ m.l[0];
257f1ecb913SArd Biesheuvel         d.l[1] ^= n.l[0] ^ m.l[1];
258f1ecb913SArd Biesheuvel     } else {
259f1ecb913SArd Biesheuvel         int i;
260f1ecb913SArd Biesheuvel 
261f1ecb913SArd Biesheuvel         for (i = 0; i < 4; i++) {
262f1ecb913SArd Biesheuvel             uint32_t t;
263f1ecb913SArd Biesheuvel 
264f1ecb913SArd Biesheuvel             switch (op) {
265f1ecb913SArd Biesheuvel             case 0: /* sha1c */
266b449ca3cSArd Biesheuvel                 t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
267f1ecb913SArd Biesheuvel                 break;
268f1ecb913SArd Biesheuvel             case 1: /* sha1p */
269b449ca3cSArd Biesheuvel                 t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
270f1ecb913SArd Biesheuvel                 break;
271f1ecb913SArd Biesheuvel             case 2: /* sha1m */
272b449ca3cSArd Biesheuvel                 t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
273f1ecb913SArd Biesheuvel                 break;
274f1ecb913SArd Biesheuvel             default:
275f1ecb913SArd Biesheuvel                 g_assert_not_reached();
276f1ecb913SArd Biesheuvel             }
277b449ca3cSArd Biesheuvel             t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
278b449ca3cSArd Biesheuvel                  + CR_ST_WORD(m, i);
279f1ecb913SArd Biesheuvel 
280b449ca3cSArd Biesheuvel             CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
281b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
282b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
283b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
284b449ca3cSArd Biesheuvel             CR_ST_WORD(d, 0) = t;
285f1ecb913SArd Biesheuvel         }
286f1ecb913SArd Biesheuvel     }
287f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
288f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
289f1ecb913SArd Biesheuvel }
290f1ecb913SArd Biesheuvel 
291f1ecb913SArd Biesheuvel void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm)
292f1ecb913SArd Biesheuvel {
293f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
294f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
295f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
296f1ecb913SArd Biesheuvel     } };
297f1ecb913SArd Biesheuvel 
298b449ca3cSArd Biesheuvel     CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
299b449ca3cSArd Biesheuvel     CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
300f1ecb913SArd Biesheuvel 
301f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(m.l[0]);
302f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(m.l[1]);
303f1ecb913SArd Biesheuvel }
304f1ecb913SArd Biesheuvel 
305f1ecb913SArd Biesheuvel void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm)
306f1ecb913SArd Biesheuvel {
307f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
308f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
309f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
310f1ecb913SArd Biesheuvel     } };
311f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
312f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
313f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
314f1ecb913SArd Biesheuvel     } };
315f1ecb913SArd Biesheuvel 
316b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
317b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
318b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
319b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
320f1ecb913SArd Biesheuvel 
321f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
322f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
323f1ecb913SArd Biesheuvel }
324f1ecb913SArd Biesheuvel 
325f1ecb913SArd Biesheuvel /*
326f1ecb913SArd Biesheuvel  * The SHA-256 logical functions, according to
327f1ecb913SArd Biesheuvel  * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
328f1ecb913SArd Biesheuvel  */
329f1ecb913SArd Biesheuvel 
330f1ecb913SArd Biesheuvel static uint32_t S0(uint32_t x)
331f1ecb913SArd Biesheuvel {
332f1ecb913SArd Biesheuvel     return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
333f1ecb913SArd Biesheuvel }
334f1ecb913SArd Biesheuvel 
335f1ecb913SArd Biesheuvel static uint32_t S1(uint32_t x)
336f1ecb913SArd Biesheuvel {
337f1ecb913SArd Biesheuvel     return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
338f1ecb913SArd Biesheuvel }
339f1ecb913SArd Biesheuvel 
340f1ecb913SArd Biesheuvel static uint32_t s0(uint32_t x)
341f1ecb913SArd Biesheuvel {
342f1ecb913SArd Biesheuvel     return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
343f1ecb913SArd Biesheuvel }
344f1ecb913SArd Biesheuvel 
345f1ecb913SArd Biesheuvel static uint32_t s1(uint32_t x)
346f1ecb913SArd Biesheuvel {
347f1ecb913SArd Biesheuvel     return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
348f1ecb913SArd Biesheuvel }
349f1ecb913SArd Biesheuvel 
350f1ecb913SArd Biesheuvel void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
351f1ecb913SArd Biesheuvel                             uint32_t rm)
352f1ecb913SArd Biesheuvel {
353f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
354f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
355f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
356f1ecb913SArd Biesheuvel     } };
357f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
358f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
359f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
360f1ecb913SArd Biesheuvel     } };
361f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
362f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
363f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
364f1ecb913SArd Biesheuvel     } };
365f1ecb913SArd Biesheuvel     int i;
366f1ecb913SArd Biesheuvel 
367f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
368b449ca3cSArd Biesheuvel         uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2))
369b449ca3cSArd Biesheuvel                      + CR_ST_WORD(n, 3) + S1(CR_ST_WORD(n, 0))
370b449ca3cSArd Biesheuvel                      + CR_ST_WORD(m, i);
371f1ecb913SArd Biesheuvel 
372b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 3) = CR_ST_WORD(n, 2);
373b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 2) = CR_ST_WORD(n, 1);
374b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 1) = CR_ST_WORD(n, 0);
375b449ca3cSArd Biesheuvel         CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3) + t;
376f1ecb913SArd Biesheuvel 
377b449ca3cSArd Biesheuvel         t += maj(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
378b449ca3cSArd Biesheuvel              + S0(CR_ST_WORD(d, 0));
379f1ecb913SArd Biesheuvel 
380b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
381b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
382b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
383b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 0) = t;
384f1ecb913SArd Biesheuvel     }
385f1ecb913SArd Biesheuvel 
386f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
387f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
388f1ecb913SArd Biesheuvel }
389f1ecb913SArd Biesheuvel 
390f1ecb913SArd Biesheuvel void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
391f1ecb913SArd Biesheuvel                              uint32_t rm)
392f1ecb913SArd Biesheuvel {
393f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
394f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
395f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
396f1ecb913SArd Biesheuvel     } };
397f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
398f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
399f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
400f1ecb913SArd Biesheuvel     } };
401f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
402f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
403f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
404f1ecb913SArd Biesheuvel     } };
405f1ecb913SArd Biesheuvel     int i;
406f1ecb913SArd Biesheuvel 
407f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
408b449ca3cSArd Biesheuvel         uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
409b449ca3cSArd Biesheuvel                      + CR_ST_WORD(d, 3) + S1(CR_ST_WORD(d, 0))
410b449ca3cSArd Biesheuvel                      + CR_ST_WORD(m, i);
411f1ecb913SArd Biesheuvel 
412b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
413b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
414b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
415b449ca3cSArd Biesheuvel         CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
416f1ecb913SArd Biesheuvel     }
417f1ecb913SArd Biesheuvel 
418f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
419f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
420f1ecb913SArd Biesheuvel }
421f1ecb913SArd Biesheuvel 
422f1ecb913SArd Biesheuvel void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm)
423f1ecb913SArd Biesheuvel {
424f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
425f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
426f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
427f1ecb913SArd Biesheuvel     } };
428f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
429f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
430f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
431f1ecb913SArd Biesheuvel     } };
432f1ecb913SArd Biesheuvel 
433b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
434b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
435b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
436b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
437f1ecb913SArd Biesheuvel 
438f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
439f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
440f1ecb913SArd Biesheuvel }
441f1ecb913SArd Biesheuvel 
442f1ecb913SArd Biesheuvel void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn,
443f1ecb913SArd Biesheuvel                               uint32_t rm)
444f1ecb913SArd Biesheuvel {
445f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
446f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
447f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
448f1ecb913SArd Biesheuvel     } };
449f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
450f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
451f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
452f1ecb913SArd Biesheuvel     } };
453f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
454f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
455f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
456f1ecb913SArd Biesheuvel     } };
457f1ecb913SArd Biesheuvel 
458b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
459b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
460b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
461b449ca3cSArd Biesheuvel     CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
462f1ecb913SArd Biesheuvel 
463f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
464f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
465f1ecb913SArd Biesheuvel }
466