qemu/target/arm/crypto_helper.c
<<
>>
Prefs
   1/*
   2 * crypto_helper.c - emulate v8 Crypto Extensions instructions
   3 *
   4 * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include "qemu/osdep.h"
  13
  14#include "cpu.h"
  15#include "exec/helper-proto.h"
  16#include "crypto/aes.h"
  17
  18union CRYPTO_STATE {
  19    uint8_t    bytes[16];
  20    uint32_t   words[4];
  21    uint64_t   l[2];
  22};
  23
  24#ifdef HOST_WORDS_BIGENDIAN
  25#define CR_ST_BYTE(state, i)   (state.bytes[(15 - (i)) ^ 8])
  26#define CR_ST_WORD(state, i)   (state.words[(3 - (i)) ^ 2])
  27#else
  28#define CR_ST_BYTE(state, i)   (state.bytes[i])
  29#define CR_ST_WORD(state, i)   (state.words[i])
  30#endif
  31
  32void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
  33{
  34    static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
  35    static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
  36    uint64_t *rd = vd;
  37    uint64_t *rm = vm;
  38    union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
  39    union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
  40    int i;
  41
  42    assert(decrypt < 2);
  43
  44    /* xor state vector with round key */
  45    rk.l[0] ^= st.l[0];
  46    rk.l[1] ^= st.l[1];
  47
  48    /* combine ShiftRows operation and sbox substitution */
  49    for (i = 0; i < 16; i++) {
  50        CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
  51    }
  52
  53    rd[0] = st.l[0];
  54    rd[1] = st.l[1];
  55}
  56
  57void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
  58{
  59    static uint32_t const mc[][256] = { {
  60        /* MixColumns lookup table */
  61        0x00000000, 0x03010102, 0x06020204, 0x05030306,
  62        0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
  63        0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
  64        0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
  65        0x30101020, 0x33111122, 0x36121224, 0x35131326,
  66        0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
  67        0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
  68        0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
  69        0x60202040, 0x63212142, 0x66222244, 0x65232346,
  70        0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
  71        0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
  72        0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
  73        0x50303060, 0x53313162, 0x56323264, 0x55333366,
  74        0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
  75        0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
  76        0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
  77        0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
  78        0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
  79        0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
  80        0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
  81        0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
  82        0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
  83        0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
  84        0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
  85        0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
  86        0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
  87        0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
  88        0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
  89        0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
  90        0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
  91        0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
  92        0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
  93        0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
  94        0x97848413, 0x94858511, 0x91868617, 0x92878715,
  95        0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
  96        0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
  97        0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
  98        0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
  99        0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
 100        0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
 101        0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
 102        0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
 103        0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
 104        0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
 105        0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
 106        0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
 107        0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
 108        0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
 109        0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
 110        0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
 111        0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
 112        0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
 113        0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
 114        0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
 115        0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
 116        0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
 117        0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
 118        0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
 119        0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
 120        0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
 121        0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
 122        0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
 123        0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
 124        0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
 125    }, {
 126        /* Inverse MixColumns lookup table */
 127        0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
 128        0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
 129        0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
 130        0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
 131        0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
 132        0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
 133        0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
 134        0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
 135        0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
 136        0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
 137        0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
 138        0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
 139        0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
 140        0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
 141        0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
 142        0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
 143        0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
 144        0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
 145        0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
 146        0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
 147        0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
 148        0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
 149        0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
 150        0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
 151        0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
 152        0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
 153        0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
 154        0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
 155        0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
 156        0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
 157        0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
 158        0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
 159        0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
 160        0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
 161        0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
 162        0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
 163        0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
 164        0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
 165        0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
 166        0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
 167        0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
 168        0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
 169        0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
 170        0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
 171        0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
 172        0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
 173        0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
 174        0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
 175        0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
 176        0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
 177        0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
 178        0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
 179        0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
 180        0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
 181        0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
 182        0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
 183        0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
 184        0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
 185        0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
 186        0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
 187        0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
 188        0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
 189        0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
 190        0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
 191    } };
 192
 193    uint64_t *rd = vd;
 194    uint64_t *rm = vm;
 195    union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
 196    int i;
 197
 198    assert(decrypt < 2);
 199
 200    for (i = 0; i < 16; i += 4) {
 201        CR_ST_WORD(st, i >> 2) =
 202            mc[decrypt][CR_ST_BYTE(st, i)] ^
 203            rol32(mc[decrypt][CR_ST_BYTE(st, i + 1)], 8) ^
 204            rol32(mc[decrypt][CR_ST_BYTE(st, i + 2)], 16) ^
 205            rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
 206    }
 207
 208    rd[0] = st.l[0];
 209    rd[1] = st.l[1];
 210}
 211
 212/*
 213 * SHA-1 logical functions
 214 */
 215
 216static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
 217{
 218    return (x & (y ^ z)) ^ z;
 219}
 220
 221static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
 222{
 223    return x ^ y ^ z;
 224}
 225
 226static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
 227{
 228    return (x & y) | ((x | y) & z);
 229}
 230
 231void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
 232{
 233    uint64_t *rd = vd;
 234    uint64_t *rn = vn;
 235    uint64_t *rm = vm;
 236    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 237    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 238    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 239
 240    if (op == 3) { /* sha1su0 */
 241        d.l[0] ^= d.l[1] ^ m.l[0];
 242        d.l[1] ^= n.l[0] ^ m.l[1];
 243    } else {
 244        int i;
 245
 246        for (i = 0; i < 4; i++) {
 247            uint32_t t;
 248
 249            switch (op) {
 250            case 0: /* sha1c */
 251                t = cho(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
 252                break;
 253            case 1: /* sha1p */
 254                t = par(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
 255                break;
 256            case 2: /* sha1m */
 257                t = maj(CR_ST_WORD(d, 1), CR_ST_WORD(d, 2), CR_ST_WORD(d, 3));
 258                break;
 259            default:
 260                g_assert_not_reached();
 261            }
 262            t += rol32(CR_ST_WORD(d, 0), 5) + CR_ST_WORD(n, 0)
 263                 + CR_ST_WORD(m, i);
 264
 265            CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3);
 266            CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
 267            CR_ST_WORD(d, 2) = ror32(CR_ST_WORD(d, 1), 2);
 268            CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
 269            CR_ST_WORD(d, 0) = t;
 270        }
 271    }
 272    rd[0] = d.l[0];
 273    rd[1] = d.l[1];
 274}
 275
 276void HELPER(crypto_sha1h)(void *vd, void *vm)
 277{
 278    uint64_t *rd = vd;
 279    uint64_t *rm = vm;
 280    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 281
 282    CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
 283    CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
 284
 285    rd[0] = m.l[0];
 286    rd[1] = m.l[1];
 287}
 288
 289void HELPER(crypto_sha1su1)(void *vd, void *vm)
 290{
 291    uint64_t *rd = vd;
 292    uint64_t *rm = vm;
 293    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 294    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 295
 296    CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
 297    CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
 298    CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
 299    CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
 300
 301    rd[0] = d.l[0];
 302    rd[1] = d.l[1];
 303}
 304
 305/*
 306 * The SHA-256 logical functions, according to
 307 * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
 308 */
 309
 310static uint32_t S0(uint32_t x)
 311{
 312    return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
 313}
 314
 315static uint32_t S1(uint32_t x)
 316{
 317    return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
 318}
 319
 320static uint32_t s0(uint32_t x)
 321{
 322    return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
 323}
 324
 325static uint32_t s1(uint32_t x)
 326{
 327    return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
 328}
 329
 330void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
 331{
 332    uint64_t *rd = vd;
 333    uint64_t *rn = vn;
 334    uint64_t *rm = vm;
 335    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 336    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 337    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 338    int i;
 339
 340    for (i = 0; i < 4; i++) {
 341        uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2))
 342                     + CR_ST_WORD(n, 3) + S1(CR_ST_WORD(n, 0))
 343                     + CR_ST_WORD(m, i);
 344
 345        CR_ST_WORD(n, 3) = CR_ST_WORD(n, 2);
 346        CR_ST_WORD(n, 2) = CR_ST_WORD(n, 1);
 347        CR_ST_WORD(n, 1) = CR_ST_WORD(n, 0);
 348        CR_ST_WORD(n, 0) = CR_ST_WORD(d, 3) + t;
 349
 350        t += maj(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
 351             + S0(CR_ST_WORD(d, 0));
 352
 353        CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
 354        CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
 355        CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
 356        CR_ST_WORD(d, 0) = t;
 357    }
 358
 359    rd[0] = d.l[0];
 360    rd[1] = d.l[1];
 361}
 362
 363void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
 364{
 365    uint64_t *rd = vd;
 366    uint64_t *rn = vn;
 367    uint64_t *rm = vm;
 368    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 369    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 370    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 371    int i;
 372
 373    for (i = 0; i < 4; i++) {
 374        uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2))
 375                     + CR_ST_WORD(d, 3) + S1(CR_ST_WORD(d, 0))
 376                     + CR_ST_WORD(m, i);
 377
 378        CR_ST_WORD(d, 3) = CR_ST_WORD(d, 2);
 379        CR_ST_WORD(d, 2) = CR_ST_WORD(d, 1);
 380        CR_ST_WORD(d, 1) = CR_ST_WORD(d, 0);
 381        CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
 382    }
 383
 384    rd[0] = d.l[0];
 385    rd[1] = d.l[1];
 386}
 387
 388void HELPER(crypto_sha256su0)(void *vd, void *vm)
 389{
 390    uint64_t *rd = vd;
 391    uint64_t *rm = vm;
 392    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 393    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 394
 395    CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
 396    CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
 397    CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
 398    CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
 399
 400    rd[0] = d.l[0];
 401    rd[1] = d.l[1];
 402}
 403
 404void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
 405{
 406    uint64_t *rd = vd;
 407    uint64_t *rn = vn;
 408    uint64_t *rm = vm;
 409    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 410    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 411    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 412
 413    CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
 414    CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
 415    CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
 416    CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
 417
 418    rd[0] = d.l[0];
 419    rd[1] = d.l[1];
 420}
 421
 422/*
 423 * The SHA-512 logical functions (same as above but using 64-bit operands)
 424 */
 425
 426static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
 427{
 428    return (x & (y ^ z)) ^ z;
 429}
 430
 431static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
 432{
 433    return (x & y) | ((x | y) & z);
 434}
 435
 436static uint64_t S0_512(uint64_t x)
 437{
 438    return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
 439}
 440
 441static uint64_t S1_512(uint64_t x)
 442{
 443    return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
 444}
 445
 446static uint64_t s0_512(uint64_t x)
 447{
 448    return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
 449}
 450
 451static uint64_t s1_512(uint64_t x)
 452{
 453    return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
 454}
 455
 456void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
 457{
 458    uint64_t *rd = vd;
 459    uint64_t *rn = vn;
 460    uint64_t *rm = vm;
 461    uint64_t d0 = rd[0];
 462    uint64_t d1 = rd[1];
 463
 464    d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
 465    d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
 466
 467    rd[0] = d0;
 468    rd[1] = d1;
 469}
 470
 471void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
 472{
 473    uint64_t *rd = vd;
 474    uint64_t *rn = vn;
 475    uint64_t *rm = vm;
 476    uint64_t d0 = rd[0];
 477    uint64_t d1 = rd[1];
 478
 479    d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
 480    d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
 481
 482    rd[0] = d0;
 483    rd[1] = d1;
 484}
 485
 486void HELPER(crypto_sha512su0)(void *vd, void *vn)
 487{
 488    uint64_t *rd = vd;
 489    uint64_t *rn = vn;
 490    uint64_t d0 = rd[0];
 491    uint64_t d1 = rd[1];
 492
 493    d0 += s0_512(rd[1]);
 494    d1 += s0_512(rn[0]);
 495
 496    rd[0] = d0;
 497    rd[1] = d1;
 498}
 499
 500void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
 501{
 502    uint64_t *rd = vd;
 503    uint64_t *rn = vn;
 504    uint64_t *rm = vm;
 505
 506    rd[0] += s1_512(rn[0]) + rm[0];
 507    rd[1] += s1_512(rn[1]) + rm[1];
 508}
 509
 510void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
 511{
 512    uint64_t *rd = vd;
 513    uint64_t *rn = vn;
 514    uint64_t *rm = vm;
 515    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 516    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 517    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 518    uint32_t t;
 519
 520    t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
 521    CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
 522
 523    t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
 524    CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
 525
 526    t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
 527    CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
 528
 529    t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
 530    CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
 531
 532    rd[0] = d.l[0];
 533    rd[1] = d.l[1];
 534}
 535
 536void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
 537{
 538    uint64_t *rd = vd;
 539    uint64_t *rn = vn;
 540    uint64_t *rm = vm;
 541    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 542    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 543    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 544    uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
 545
 546    CR_ST_WORD(d, 0) ^= t;
 547    CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
 548    CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
 549    CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
 550                        ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
 551
 552    rd[0] = d.l[0];
 553    rd[1] = d.l[1];
 554}
 555
 556void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
 557                          uint32_t opcode)
 558{
 559    uint64_t *rd = vd;
 560    uint64_t *rn = vn;
 561    uint64_t *rm = vm;
 562    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 563    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 564    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 565    uint32_t t;
 566
 567    assert(imm2 < 4);
 568
 569    if (opcode == 0 || opcode == 2) {
 570        /* SM3TT1A, SM3TT2A */
 571        t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
 572    } else if (opcode == 1) {
 573        /* SM3TT1B */
 574        t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
 575    } else if (opcode == 3) {
 576        /* SM3TT2B */
 577        t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
 578    } else {
 579        g_assert_not_reached();
 580    }
 581
 582    t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
 583
 584    CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
 585
 586    if (opcode < 2) {
 587        /* SM3TT1A, SM3TT1B */
 588        t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
 589
 590        CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
 591    } else {
 592        /* SM3TT2A, SM3TT2B */
 593        t += CR_ST_WORD(n, 3);
 594        t ^= rol32(t, 9) ^ rol32(t, 17);
 595
 596        CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
 597    }
 598
 599    CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
 600    CR_ST_WORD(d, 3) = t;
 601
 602    rd[0] = d.l[0];
 603    rd[1] = d.l[1];
 604}
 605
 606static uint8_t const sm4_sbox[] = {
 607    0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
 608    0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
 609    0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
 610    0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
 611    0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
 612    0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
 613    0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
 614    0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
 615    0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
 616    0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
 617    0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
 618    0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
 619    0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
 620    0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
 621    0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
 622    0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
 623    0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
 624    0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
 625    0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
 626    0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
 627    0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
 628    0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
 629    0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
 630    0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
 631    0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
 632    0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
 633    0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
 634    0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
 635    0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
 636    0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
 637    0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
 638    0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
 639};
 640
 641void HELPER(crypto_sm4e)(void *vd, void *vn)
 642{
 643    uint64_t *rd = vd;
 644    uint64_t *rn = vn;
 645    union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
 646    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 647    uint32_t t, i;
 648
 649    for (i = 0; i < 4; i++) {
 650        t = CR_ST_WORD(d, (i + 1) % 4) ^
 651            CR_ST_WORD(d, (i + 2) % 4) ^
 652            CR_ST_WORD(d, (i + 3) % 4) ^
 653            CR_ST_WORD(n, i);
 654
 655        t = sm4_sbox[t & 0xff] |
 656            sm4_sbox[(t >> 8) & 0xff] << 8 |
 657            sm4_sbox[(t >> 16) & 0xff] << 16 |
 658            sm4_sbox[(t >> 24) & 0xff] << 24;
 659
 660        CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
 661                            rol32(t, 24);
 662    }
 663
 664    rd[0] = d.l[0];
 665    rd[1] = d.l[1];
 666}
 667
 668void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
 669{
 670    uint64_t *rd = vd;
 671    uint64_t *rn = vn;
 672    uint64_t *rm = vm;
 673    union CRYPTO_STATE d;
 674    union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
 675    union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
 676    uint32_t t, i;
 677
 678    d = n;
 679    for (i = 0; i < 4; i++) {
 680        t = CR_ST_WORD(d, (i + 1) % 4) ^
 681            CR_ST_WORD(d, (i + 2) % 4) ^
 682            CR_ST_WORD(d, (i + 3) % 4) ^
 683            CR_ST_WORD(m, i);
 684
 685        t = sm4_sbox[t & 0xff] |
 686            sm4_sbox[(t >> 8) & 0xff] << 8 |
 687            sm4_sbox[(t >> 16) & 0xff] << 16 |
 688            sm4_sbox[(t >> 24) & 0xff] << 24;
 689
 690        CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
 691    }
 692
 693    rd[0] = d.l[0];
 694    rd[1] = d.l[1];
 695}
 696