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