xref: /qemu/target/arm/tcg/crypto_helper.c (revision f1ecb913d81199758383b8cbc15f4eb435b91753)
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"
179d935509SArd Biesheuvel 
18f1ecb913SArd Biesheuvel union CRYPTO_STATE {
199d935509SArd Biesheuvel     uint8_t    bytes[16];
20f1ecb913SArd Biesheuvel     uint32_t   words[4];
219d935509SArd Biesheuvel     uint64_t   l[2];
229d935509SArd Biesheuvel };
239d935509SArd Biesheuvel 
249d935509SArd Biesheuvel void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
259d935509SArd Biesheuvel                          uint32_t decrypt)
269d935509SArd Biesheuvel {
279d935509SArd Biesheuvel     static uint8_t const sbox[][256] = { {
289d935509SArd Biesheuvel         /* S-box for encryption */
299d935509SArd Biesheuvel         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
309d935509SArd Biesheuvel         0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
319d935509SArd Biesheuvel         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
329d935509SArd Biesheuvel         0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
339d935509SArd Biesheuvel         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
349d935509SArd Biesheuvel         0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
359d935509SArd Biesheuvel         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
369d935509SArd Biesheuvel         0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
379d935509SArd Biesheuvel         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
389d935509SArd Biesheuvel         0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
399d935509SArd Biesheuvel         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
409d935509SArd Biesheuvel         0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
419d935509SArd Biesheuvel         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
429d935509SArd Biesheuvel         0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
439d935509SArd Biesheuvel         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
449d935509SArd Biesheuvel         0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
459d935509SArd Biesheuvel         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
469d935509SArd Biesheuvel         0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
479d935509SArd Biesheuvel         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
489d935509SArd Biesheuvel         0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
499d935509SArd Biesheuvel         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
509d935509SArd Biesheuvel         0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
519d935509SArd Biesheuvel         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
529d935509SArd Biesheuvel         0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
539d935509SArd Biesheuvel         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
549d935509SArd Biesheuvel         0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
559d935509SArd Biesheuvel         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
569d935509SArd Biesheuvel         0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
579d935509SArd Biesheuvel         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
589d935509SArd Biesheuvel         0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
599d935509SArd Biesheuvel         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
609d935509SArd Biesheuvel         0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
619d935509SArd Biesheuvel     }, {
629d935509SArd Biesheuvel         /* S-box for decryption */
639d935509SArd Biesheuvel         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
649d935509SArd Biesheuvel         0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
659d935509SArd Biesheuvel         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
669d935509SArd Biesheuvel         0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
679d935509SArd Biesheuvel         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
689d935509SArd Biesheuvel         0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
699d935509SArd Biesheuvel         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
709d935509SArd Biesheuvel         0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
719d935509SArd Biesheuvel         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
729d935509SArd Biesheuvel         0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
739d935509SArd Biesheuvel         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
749d935509SArd Biesheuvel         0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
759d935509SArd Biesheuvel         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
769d935509SArd Biesheuvel         0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
779d935509SArd Biesheuvel         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
789d935509SArd Biesheuvel         0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
799d935509SArd Biesheuvel         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
809d935509SArd Biesheuvel         0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
819d935509SArd Biesheuvel         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
829d935509SArd Biesheuvel         0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
839d935509SArd Biesheuvel         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
849d935509SArd Biesheuvel         0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
859d935509SArd Biesheuvel         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
869d935509SArd Biesheuvel         0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
879d935509SArd Biesheuvel         0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
889d935509SArd Biesheuvel         0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
899d935509SArd Biesheuvel         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
909d935509SArd Biesheuvel         0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
919d935509SArd Biesheuvel         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
929d935509SArd Biesheuvel         0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
939d935509SArd Biesheuvel         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
949d935509SArd Biesheuvel         0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
959d935509SArd Biesheuvel     } };
969d935509SArd Biesheuvel     static uint8_t const shift[][16] = {
979d935509SArd Biesheuvel         /* ShiftRows permutation vector for encryption */
989d935509SArd Biesheuvel         { 0,  5, 10, 15, 4, 9, 14,  3, 8, 13, 2,  7, 12, 1, 6, 11 },
999d935509SArd Biesheuvel         /* ShiftRows permutation vector for decryption */
1009d935509SArd Biesheuvel         { 0, 13, 10,  7, 4, 1, 14, 11, 8,  5, 2, 15, 12, 9, 6,  3 },
1019d935509SArd Biesheuvel     };
102f1ecb913SArd Biesheuvel     union CRYPTO_STATE rk = { .l = {
1039d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
1049d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
1059d935509SArd Biesheuvel     } };
106f1ecb913SArd Biesheuvel     union CRYPTO_STATE st = { .l = {
1079d935509SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
1089d935509SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
1099d935509SArd Biesheuvel     } };
1109d935509SArd Biesheuvel     int i;
1119d935509SArd Biesheuvel 
1129d935509SArd Biesheuvel     assert(decrypt < 2);
1139d935509SArd Biesheuvel 
1149d935509SArd Biesheuvel     /* xor state vector with round key */
1159d935509SArd Biesheuvel     rk.l[0] ^= st.l[0];
1169d935509SArd Biesheuvel     rk.l[1] ^= st.l[1];
1179d935509SArd Biesheuvel 
1189d935509SArd Biesheuvel     /* combine ShiftRows operation and sbox substitution */
1199d935509SArd Biesheuvel     for (i = 0; i < 16; i++) {
1209d935509SArd Biesheuvel         st.bytes[i] = sbox[decrypt][rk.bytes[shift[decrypt][i]]];
1219d935509SArd Biesheuvel     }
1229d935509SArd Biesheuvel 
1239d935509SArd Biesheuvel     env->vfp.regs[rd] = make_float64(st.l[0]);
1249d935509SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(st.l[1]);
1259d935509SArd Biesheuvel }
1269d935509SArd Biesheuvel 
1279d935509SArd Biesheuvel void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
1289d935509SArd Biesheuvel                           uint32_t decrypt)
1299d935509SArd Biesheuvel {
1309d935509SArd Biesheuvel     static uint32_t const mc[][256] = { {
1319d935509SArd Biesheuvel         /* MixColumns lookup table */
1329d935509SArd Biesheuvel         0x00000000, 0x03010102, 0x06020204, 0x05030306,
1339d935509SArd Biesheuvel         0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
1349d935509SArd Biesheuvel         0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
1359d935509SArd Biesheuvel         0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
1369d935509SArd Biesheuvel         0x30101020, 0x33111122, 0x36121224, 0x35131326,
1379d935509SArd Biesheuvel         0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
1389d935509SArd Biesheuvel         0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
1399d935509SArd Biesheuvel         0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
1409d935509SArd Biesheuvel         0x60202040, 0x63212142, 0x66222244, 0x65232346,
1419d935509SArd Biesheuvel         0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
1429d935509SArd Biesheuvel         0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
1439d935509SArd Biesheuvel         0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
1449d935509SArd Biesheuvel         0x50303060, 0x53313162, 0x56323264, 0x55333366,
1459d935509SArd Biesheuvel         0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
1469d935509SArd Biesheuvel         0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
1479d935509SArd Biesheuvel         0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
1489d935509SArd Biesheuvel         0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
1499d935509SArd Biesheuvel         0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
1509d935509SArd Biesheuvel         0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
1519d935509SArd Biesheuvel         0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
1529d935509SArd Biesheuvel         0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
1539d935509SArd Biesheuvel         0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
1549d935509SArd Biesheuvel         0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
1559d935509SArd Biesheuvel         0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
1569d935509SArd Biesheuvel         0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
1579d935509SArd Biesheuvel         0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
1589d935509SArd Biesheuvel         0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
1599d935509SArd Biesheuvel         0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
1609d935509SArd Biesheuvel         0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
1619d935509SArd Biesheuvel         0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
1629d935509SArd Biesheuvel         0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
1639d935509SArd Biesheuvel         0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
1649d935509SArd Biesheuvel         0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
1659d935509SArd Biesheuvel         0x97848413, 0x94858511, 0x91868617, 0x92878715,
1669d935509SArd Biesheuvel         0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
1679d935509SArd Biesheuvel         0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
1689d935509SArd Biesheuvel         0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
1699d935509SArd Biesheuvel         0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
1709d935509SArd Biesheuvel         0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
1719d935509SArd Biesheuvel         0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
1729d935509SArd Biesheuvel         0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
1739d935509SArd Biesheuvel         0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
1749d935509SArd Biesheuvel         0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
1759d935509SArd Biesheuvel         0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
1769d935509SArd Biesheuvel         0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
1779d935509SArd Biesheuvel         0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
1789d935509SArd Biesheuvel         0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
1799d935509SArd Biesheuvel         0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
1809d935509SArd Biesheuvel         0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
1819d935509SArd Biesheuvel         0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
1829d935509SArd Biesheuvel         0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
1839d935509SArd Biesheuvel         0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
1849d935509SArd Biesheuvel         0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
1859d935509SArd Biesheuvel         0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
1869d935509SArd Biesheuvel         0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
1879d935509SArd Biesheuvel         0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
1889d935509SArd Biesheuvel         0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
1899d935509SArd Biesheuvel         0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
1909d935509SArd Biesheuvel         0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
1919d935509SArd Biesheuvel         0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
1929d935509SArd Biesheuvel         0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
1939d935509SArd Biesheuvel         0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
1949d935509SArd Biesheuvel         0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
1959d935509SArd Biesheuvel         0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
1969d935509SArd Biesheuvel     }, {
1979d935509SArd Biesheuvel         /* Inverse MixColumns lookup table */
1989d935509SArd Biesheuvel         0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
1999d935509SArd Biesheuvel         0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
2009d935509SArd Biesheuvel         0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
2019d935509SArd Biesheuvel         0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
2029d935509SArd Biesheuvel         0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
2039d935509SArd Biesheuvel         0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
2049d935509SArd Biesheuvel         0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
2059d935509SArd Biesheuvel         0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
2069d935509SArd Biesheuvel         0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
2079d935509SArd Biesheuvel         0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
2089d935509SArd Biesheuvel         0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
2099d935509SArd Biesheuvel         0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
2109d935509SArd Biesheuvel         0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
2119d935509SArd Biesheuvel         0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
2129d935509SArd Biesheuvel         0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
2139d935509SArd Biesheuvel         0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
2149d935509SArd Biesheuvel         0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
2159d935509SArd Biesheuvel         0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
2169d935509SArd Biesheuvel         0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
2179d935509SArd Biesheuvel         0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
2189d935509SArd Biesheuvel         0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
2199d935509SArd Biesheuvel         0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
2209d935509SArd Biesheuvel         0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
2219d935509SArd Biesheuvel         0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
2229d935509SArd Biesheuvel         0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
2239d935509SArd Biesheuvel         0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
2249d935509SArd Biesheuvel         0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
2259d935509SArd Biesheuvel         0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
2269d935509SArd Biesheuvel         0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
2279d935509SArd Biesheuvel         0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
2289d935509SArd Biesheuvel         0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
2299d935509SArd Biesheuvel         0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
2309d935509SArd Biesheuvel         0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
2319d935509SArd Biesheuvel         0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
2329d935509SArd Biesheuvel         0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
2339d935509SArd Biesheuvel         0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
2349d935509SArd Biesheuvel         0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
2359d935509SArd Biesheuvel         0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
2369d935509SArd Biesheuvel         0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
2379d935509SArd Biesheuvel         0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
2389d935509SArd Biesheuvel         0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
2399d935509SArd Biesheuvel         0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
2409d935509SArd Biesheuvel         0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
2419d935509SArd Biesheuvel         0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
2429d935509SArd Biesheuvel         0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
2439d935509SArd Biesheuvel         0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
2449d935509SArd Biesheuvel         0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
2459d935509SArd Biesheuvel         0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
2469d935509SArd Biesheuvel         0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
2479d935509SArd Biesheuvel         0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
2489d935509SArd Biesheuvel         0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
2499d935509SArd Biesheuvel         0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
2509d935509SArd Biesheuvel         0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
2519d935509SArd Biesheuvel         0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
2529d935509SArd Biesheuvel         0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
2539d935509SArd Biesheuvel         0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
2549d935509SArd Biesheuvel         0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
2559d935509SArd Biesheuvel         0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
2569d935509SArd Biesheuvel         0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
2579d935509SArd Biesheuvel         0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
2589d935509SArd Biesheuvel         0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
2599d935509SArd Biesheuvel         0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
2609d935509SArd Biesheuvel         0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
2619d935509SArd Biesheuvel         0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
2629d935509SArd Biesheuvel     } };
263f1ecb913SArd Biesheuvel     union CRYPTO_STATE st = { .l = {
2649d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
2659d935509SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
2669d935509SArd Biesheuvel     } };
2679d935509SArd Biesheuvel     int i;
2689d935509SArd Biesheuvel 
2699d935509SArd Biesheuvel     assert(decrypt < 2);
2709d935509SArd Biesheuvel 
2719d935509SArd Biesheuvel     for (i = 0; i < 16; i += 4) {
272f1ecb913SArd Biesheuvel         st.words[i >> 2] = cpu_to_le32(
2739d935509SArd Biesheuvel             mc[decrypt][st.bytes[i]] ^
2749d935509SArd Biesheuvel             rol32(mc[decrypt][st.bytes[i + 1]], 8) ^
2759d935509SArd Biesheuvel             rol32(mc[decrypt][st.bytes[i + 2]], 16) ^
2769d935509SArd Biesheuvel             rol32(mc[decrypt][st.bytes[i + 3]], 24));
2779d935509SArd Biesheuvel     }
2789d935509SArd Biesheuvel 
2799d935509SArd Biesheuvel     env->vfp.regs[rd] = make_float64(st.l[0]);
2809d935509SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(st.l[1]);
2819d935509SArd Biesheuvel }
282f1ecb913SArd Biesheuvel 
283f1ecb913SArd Biesheuvel /*
284f1ecb913SArd Biesheuvel  * SHA-1 logical functions
285f1ecb913SArd Biesheuvel  */
286f1ecb913SArd Biesheuvel 
287f1ecb913SArd Biesheuvel static uint32_t cho(uint32_t x, uint32_t y, uint32_t z)
288f1ecb913SArd Biesheuvel {
289f1ecb913SArd Biesheuvel     return (x & (y ^ z)) ^ z;
290f1ecb913SArd Biesheuvel }
291f1ecb913SArd Biesheuvel 
292f1ecb913SArd Biesheuvel static uint32_t par(uint32_t x, uint32_t y, uint32_t z)
293f1ecb913SArd Biesheuvel {
294f1ecb913SArd Biesheuvel     return x ^ y ^ z;
295f1ecb913SArd Biesheuvel }
296f1ecb913SArd Biesheuvel 
297f1ecb913SArd Biesheuvel static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
298f1ecb913SArd Biesheuvel {
299f1ecb913SArd Biesheuvel     return (x & y) | ((x | y) & z);
300f1ecb913SArd Biesheuvel }
301f1ecb913SArd Biesheuvel 
302f1ecb913SArd Biesheuvel void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
303f1ecb913SArd Biesheuvel                               uint32_t rm, uint32_t op)
304f1ecb913SArd Biesheuvel {
305f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
306f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
307f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
308f1ecb913SArd Biesheuvel     } };
309f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
310f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
311f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
312f1ecb913SArd Biesheuvel     } };
313f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
314f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
315f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
316f1ecb913SArd Biesheuvel     } };
317f1ecb913SArd Biesheuvel 
318f1ecb913SArd Biesheuvel     if (op == 3) { /* sha1su0 */
319f1ecb913SArd Biesheuvel         d.l[0] ^= d.l[1] ^ m.l[0];
320f1ecb913SArd Biesheuvel         d.l[1] ^= n.l[0] ^ m.l[1];
321f1ecb913SArd Biesheuvel     } else {
322f1ecb913SArd Biesheuvel         int i;
323f1ecb913SArd Biesheuvel 
324f1ecb913SArd Biesheuvel         for (i = 0; i < 4; i++) {
325f1ecb913SArd Biesheuvel             uint32_t t;
326f1ecb913SArd Biesheuvel 
327f1ecb913SArd Biesheuvel             switch (op) {
328f1ecb913SArd Biesheuvel             case 0: /* sha1c */
329f1ecb913SArd Biesheuvel                 t = cho(d.words[1], d.words[2], d.words[3]);
330f1ecb913SArd Biesheuvel                 break;
331f1ecb913SArd Biesheuvel             case 1: /* sha1p */
332f1ecb913SArd Biesheuvel                 t = par(d.words[1], d.words[2], d.words[3]);
333f1ecb913SArd Biesheuvel                 break;
334f1ecb913SArd Biesheuvel             case 2: /* sha1m */
335f1ecb913SArd Biesheuvel                 t = maj(d.words[1], d.words[2], d.words[3]);
336f1ecb913SArd Biesheuvel                 break;
337f1ecb913SArd Biesheuvel             default:
338f1ecb913SArd Biesheuvel                 g_assert_not_reached();
339f1ecb913SArd Biesheuvel             }
340f1ecb913SArd Biesheuvel             t += rol32(d.words[0], 5) + n.words[0] + m.words[i];
341f1ecb913SArd Biesheuvel 
342f1ecb913SArd Biesheuvel             n.words[0] = d.words[3];
343f1ecb913SArd Biesheuvel             d.words[3] = d.words[2];
344f1ecb913SArd Biesheuvel             d.words[2] = ror32(d.words[1], 2);
345f1ecb913SArd Biesheuvel             d.words[1] = d.words[0];
346f1ecb913SArd Biesheuvel             d.words[0] = t;
347f1ecb913SArd Biesheuvel         }
348f1ecb913SArd Biesheuvel     }
349f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
350f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
351f1ecb913SArd Biesheuvel }
352f1ecb913SArd Biesheuvel 
353f1ecb913SArd Biesheuvel void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm)
354f1ecb913SArd Biesheuvel {
355f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
356f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
357f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
358f1ecb913SArd Biesheuvel     } };
359f1ecb913SArd Biesheuvel 
360f1ecb913SArd Biesheuvel     m.words[0] = ror32(m.words[0], 2);
361f1ecb913SArd Biesheuvel     m.words[1] = m.words[2] = m.words[3] = 0;
362f1ecb913SArd Biesheuvel 
363f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(m.l[0]);
364f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(m.l[1]);
365f1ecb913SArd Biesheuvel }
366f1ecb913SArd Biesheuvel 
367f1ecb913SArd Biesheuvel void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm)
368f1ecb913SArd Biesheuvel {
369f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
370f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
371f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
372f1ecb913SArd Biesheuvel     } };
373f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
374f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
375f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
376f1ecb913SArd Biesheuvel     } };
377f1ecb913SArd Biesheuvel 
378f1ecb913SArd Biesheuvel     d.words[0] = rol32(d.words[0] ^ m.words[1], 1);
379f1ecb913SArd Biesheuvel     d.words[1] = rol32(d.words[1] ^ m.words[2], 1);
380f1ecb913SArd Biesheuvel     d.words[2] = rol32(d.words[2] ^ m.words[3], 1);
381f1ecb913SArd Biesheuvel     d.words[3] = rol32(d.words[3] ^ d.words[0], 1);
382f1ecb913SArd Biesheuvel 
383f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
384f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
385f1ecb913SArd Biesheuvel }
386f1ecb913SArd Biesheuvel 
387f1ecb913SArd Biesheuvel /*
388f1ecb913SArd Biesheuvel  * The SHA-256 logical functions, according to
389f1ecb913SArd Biesheuvel  * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
390f1ecb913SArd Biesheuvel  */
391f1ecb913SArd Biesheuvel 
392f1ecb913SArd Biesheuvel static uint32_t S0(uint32_t x)
393f1ecb913SArd Biesheuvel {
394f1ecb913SArd Biesheuvel     return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
395f1ecb913SArd Biesheuvel }
396f1ecb913SArd Biesheuvel 
397f1ecb913SArd Biesheuvel static uint32_t S1(uint32_t x)
398f1ecb913SArd Biesheuvel {
399f1ecb913SArd Biesheuvel     return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
400f1ecb913SArd Biesheuvel }
401f1ecb913SArd Biesheuvel 
402f1ecb913SArd Biesheuvel static uint32_t s0(uint32_t x)
403f1ecb913SArd Biesheuvel {
404f1ecb913SArd Biesheuvel     return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
405f1ecb913SArd Biesheuvel }
406f1ecb913SArd Biesheuvel 
407f1ecb913SArd Biesheuvel static uint32_t s1(uint32_t x)
408f1ecb913SArd Biesheuvel {
409f1ecb913SArd Biesheuvel     return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
410f1ecb913SArd Biesheuvel }
411f1ecb913SArd Biesheuvel 
412f1ecb913SArd Biesheuvel void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
413f1ecb913SArd Biesheuvel                             uint32_t rm)
414f1ecb913SArd Biesheuvel {
415f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
416f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
417f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
418f1ecb913SArd Biesheuvel     } };
419f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
420f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
421f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
422f1ecb913SArd Biesheuvel     } };
423f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
424f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
425f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
426f1ecb913SArd Biesheuvel     } };
427f1ecb913SArd Biesheuvel     int i;
428f1ecb913SArd Biesheuvel 
429f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
430f1ecb913SArd Biesheuvel         uint32_t t = cho(n.words[0], n.words[1], n.words[2]) + n.words[3]
431f1ecb913SArd Biesheuvel                      + S1(n.words[0]) + m.words[i];
432f1ecb913SArd Biesheuvel 
433f1ecb913SArd Biesheuvel         n.words[3] = n.words[2];
434f1ecb913SArd Biesheuvel         n.words[2] = n.words[1];
435f1ecb913SArd Biesheuvel         n.words[1] = n.words[0];
436f1ecb913SArd Biesheuvel         n.words[0] = d.words[3] + t;
437f1ecb913SArd Biesheuvel 
438f1ecb913SArd Biesheuvel         t += maj(d.words[0], d.words[1], d.words[2]) + S0(d.words[0]);
439f1ecb913SArd Biesheuvel 
440f1ecb913SArd Biesheuvel         d.words[3] = d.words[2];
441f1ecb913SArd Biesheuvel         d.words[2] = d.words[1];
442f1ecb913SArd Biesheuvel         d.words[1] = d.words[0];
443f1ecb913SArd Biesheuvel         d.words[0] = t;
444f1ecb913SArd Biesheuvel     }
445f1ecb913SArd Biesheuvel 
446f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
447f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
448f1ecb913SArd Biesheuvel }
449f1ecb913SArd Biesheuvel 
450f1ecb913SArd Biesheuvel void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
451f1ecb913SArd Biesheuvel                              uint32_t rm)
452f1ecb913SArd Biesheuvel {
453f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
454f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
455f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
456f1ecb913SArd Biesheuvel     } };
457f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
458f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
459f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
460f1ecb913SArd Biesheuvel     } };
461f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
462f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
463f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
464f1ecb913SArd Biesheuvel     } };
465f1ecb913SArd Biesheuvel     int i;
466f1ecb913SArd Biesheuvel 
467f1ecb913SArd Biesheuvel     for (i = 0; i < 4; i++) {
468f1ecb913SArd Biesheuvel         uint32_t t = cho(d.words[0], d.words[1], d.words[2]) + d.words[3]
469f1ecb913SArd Biesheuvel                      + S1(d.words[0]) + m.words[i];
470f1ecb913SArd Biesheuvel 
471f1ecb913SArd Biesheuvel         d.words[3] = d.words[2];
472f1ecb913SArd Biesheuvel         d.words[2] = d.words[1];
473f1ecb913SArd Biesheuvel         d.words[1] = d.words[0];
474f1ecb913SArd Biesheuvel         d.words[0] = n.words[3 - i] + t;
475f1ecb913SArd Biesheuvel     }
476f1ecb913SArd Biesheuvel 
477f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
478f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
479f1ecb913SArd Biesheuvel }
480f1ecb913SArd Biesheuvel 
481f1ecb913SArd Biesheuvel void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm)
482f1ecb913SArd Biesheuvel {
483f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
484f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
485f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
486f1ecb913SArd Biesheuvel     } };
487f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
488f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
489f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
490f1ecb913SArd Biesheuvel     } };
491f1ecb913SArd Biesheuvel 
492f1ecb913SArd Biesheuvel     d.words[0] += s0(d.words[1]);
493f1ecb913SArd Biesheuvel     d.words[1] += s0(d.words[2]);
494f1ecb913SArd Biesheuvel     d.words[2] += s0(d.words[3]);
495f1ecb913SArd Biesheuvel     d.words[3] += s0(m.words[0]);
496f1ecb913SArd Biesheuvel 
497f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
498f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
499f1ecb913SArd Biesheuvel }
500f1ecb913SArd Biesheuvel 
501f1ecb913SArd Biesheuvel void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn,
502f1ecb913SArd Biesheuvel                               uint32_t rm)
503f1ecb913SArd Biesheuvel {
504f1ecb913SArd Biesheuvel     union CRYPTO_STATE d = { .l = {
505f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd]),
506f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rd + 1])
507f1ecb913SArd Biesheuvel     } };
508f1ecb913SArd Biesheuvel     union CRYPTO_STATE n = { .l = {
509f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn]),
510f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rn + 1])
511f1ecb913SArd Biesheuvel     } };
512f1ecb913SArd Biesheuvel     union CRYPTO_STATE m = { .l = {
513f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm]),
514f1ecb913SArd Biesheuvel         float64_val(env->vfp.regs[rm + 1])
515f1ecb913SArd Biesheuvel     } };
516f1ecb913SArd Biesheuvel 
517f1ecb913SArd Biesheuvel     d.words[0] += s1(m.words[2]) + n.words[1];
518f1ecb913SArd Biesheuvel     d.words[1] += s1(m.words[3]) + n.words[2];
519f1ecb913SArd Biesheuvel     d.words[2] += s1(d.words[0]) + n.words[3];
520f1ecb913SArd Biesheuvel     d.words[3] += s1(d.words[1]) + m.words[0];
521f1ecb913SArd Biesheuvel 
522f1ecb913SArd Biesheuvel     env->vfp.regs[rd] = make_float64(d.l[0]);
523f1ecb913SArd Biesheuvel     env->vfp.regs[rd + 1] = make_float64(d.l[1]);
524f1ecb913SArd Biesheuvel }
525