MAINTAINERS: mark megasas as maintained
[qemu/ar7.git] / target-arm / crypto_helper.c
blobf94be69ac596ed19c36b5e314d5d040f9eb2a7fa
1 /*
2 * crypto_helper.c - emulate v8 Crypto Extensions instructions
4 * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
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.
12 #include <stdlib.h>
14 #include "cpu.h"
15 #include "exec/exec-all.h"
16 #include "helper.h"
18 union AES_STATE {
19 uint8_t bytes[16];
20 uint32_t cols[4];
21 uint64_t l[2];
24 void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
25 uint32_t decrypt)
27 static uint8_t const sbox[][256] = { {
28 /* S-box for encryption */
29 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
30 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
31 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
32 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
33 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
34 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
35 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
36 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
37 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
38 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
39 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
40 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
41 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
42 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
43 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
44 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
45 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
46 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
47 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
48 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
49 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
50 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
51 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
52 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
53 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
54 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
55 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
56 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
57 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
58 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
59 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
60 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
61 }, {
62 /* S-box for decryption */
63 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
64 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
65 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
66 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
67 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
68 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
69 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
70 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
71 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
72 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
73 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
74 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
75 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
76 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
77 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
78 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
79 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
80 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
81 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
82 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
83 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
84 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
85 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
86 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
87 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
88 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
89 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
90 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
91 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
92 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
93 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
94 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
95 } };
96 static uint8_t const shift[][16] = {
97 /* ShiftRows permutation vector for encryption */
98 { 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 },
99 /* ShiftRows permutation vector for decryption */
100 { 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 },
102 union AES_STATE rk = { .l = {
103 float64_val(env->vfp.regs[rm]),
104 float64_val(env->vfp.regs[rm + 1])
105 } };
106 union AES_STATE st = { .l = {
107 float64_val(env->vfp.regs[rd]),
108 float64_val(env->vfp.regs[rd + 1])
109 } };
110 int i;
112 assert(decrypt < 2);
114 /* xor state vector with round key */
115 rk.l[0] ^= st.l[0];
116 rk.l[1] ^= st.l[1];
118 /* combine ShiftRows operation and sbox substitution */
119 for (i = 0; i < 16; i++) {
120 st.bytes[i] = sbox[decrypt][rk.bytes[shift[decrypt][i]]];
123 env->vfp.regs[rd] = make_float64(st.l[0]);
124 env->vfp.regs[rd + 1] = make_float64(st.l[1]);
127 void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
128 uint32_t decrypt)
130 static uint32_t const mc[][256] = { {
131 /* MixColumns lookup table */
132 0x00000000, 0x03010102, 0x06020204, 0x05030306,
133 0x0c040408, 0x0f05050a, 0x0a06060c, 0x0907070e,
134 0x18080810, 0x1b090912, 0x1e0a0a14, 0x1d0b0b16,
135 0x140c0c18, 0x170d0d1a, 0x120e0e1c, 0x110f0f1e,
136 0x30101020, 0x33111122, 0x36121224, 0x35131326,
137 0x3c141428, 0x3f15152a, 0x3a16162c, 0x3917172e,
138 0x28181830, 0x2b191932, 0x2e1a1a34, 0x2d1b1b36,
139 0x241c1c38, 0x271d1d3a, 0x221e1e3c, 0x211f1f3e,
140 0x60202040, 0x63212142, 0x66222244, 0x65232346,
141 0x6c242448, 0x6f25254a, 0x6a26264c, 0x6927274e,
142 0x78282850, 0x7b292952, 0x7e2a2a54, 0x7d2b2b56,
143 0x742c2c58, 0x772d2d5a, 0x722e2e5c, 0x712f2f5e,
144 0x50303060, 0x53313162, 0x56323264, 0x55333366,
145 0x5c343468, 0x5f35356a, 0x5a36366c, 0x5937376e,
146 0x48383870, 0x4b393972, 0x4e3a3a74, 0x4d3b3b76,
147 0x443c3c78, 0x473d3d7a, 0x423e3e7c, 0x413f3f7e,
148 0xc0404080, 0xc3414182, 0xc6424284, 0xc5434386,
149 0xcc444488, 0xcf45458a, 0xca46468c, 0xc947478e,
150 0xd8484890, 0xdb494992, 0xde4a4a94, 0xdd4b4b96,
151 0xd44c4c98, 0xd74d4d9a, 0xd24e4e9c, 0xd14f4f9e,
152 0xf05050a0, 0xf35151a2, 0xf65252a4, 0xf55353a6,
153 0xfc5454a8, 0xff5555aa, 0xfa5656ac, 0xf95757ae,
154 0xe85858b0, 0xeb5959b2, 0xee5a5ab4, 0xed5b5bb6,
155 0xe45c5cb8, 0xe75d5dba, 0xe25e5ebc, 0xe15f5fbe,
156 0xa06060c0, 0xa36161c2, 0xa66262c4, 0xa56363c6,
157 0xac6464c8, 0xaf6565ca, 0xaa6666cc, 0xa96767ce,
158 0xb86868d0, 0xbb6969d2, 0xbe6a6ad4, 0xbd6b6bd6,
159 0xb46c6cd8, 0xb76d6dda, 0xb26e6edc, 0xb16f6fde,
160 0x907070e0, 0x937171e2, 0x967272e4, 0x957373e6,
161 0x9c7474e8, 0x9f7575ea, 0x9a7676ec, 0x997777ee,
162 0x887878f0, 0x8b7979f2, 0x8e7a7af4, 0x8d7b7bf6,
163 0x847c7cf8, 0x877d7dfa, 0x827e7efc, 0x817f7ffe,
164 0x9b80801b, 0x98818119, 0x9d82821f, 0x9e83831d,
165 0x97848413, 0x94858511, 0x91868617, 0x92878715,
166 0x8388880b, 0x80898909, 0x858a8a0f, 0x868b8b0d,
167 0x8f8c8c03, 0x8c8d8d01, 0x898e8e07, 0x8a8f8f05,
168 0xab90903b, 0xa8919139, 0xad92923f, 0xae93933d,
169 0xa7949433, 0xa4959531, 0xa1969637, 0xa2979735,
170 0xb398982b, 0xb0999929, 0xb59a9a2f, 0xb69b9b2d,
171 0xbf9c9c23, 0xbc9d9d21, 0xb99e9e27, 0xba9f9f25,
172 0xfba0a05b, 0xf8a1a159, 0xfda2a25f, 0xfea3a35d,
173 0xf7a4a453, 0xf4a5a551, 0xf1a6a657, 0xf2a7a755,
174 0xe3a8a84b, 0xe0a9a949, 0xe5aaaa4f, 0xe6abab4d,
175 0xefacac43, 0xecadad41, 0xe9aeae47, 0xeaafaf45,
176 0xcbb0b07b, 0xc8b1b179, 0xcdb2b27f, 0xceb3b37d,
177 0xc7b4b473, 0xc4b5b571, 0xc1b6b677, 0xc2b7b775,
178 0xd3b8b86b, 0xd0b9b969, 0xd5baba6f, 0xd6bbbb6d,
179 0xdfbcbc63, 0xdcbdbd61, 0xd9bebe67, 0xdabfbf65,
180 0x5bc0c09b, 0x58c1c199, 0x5dc2c29f, 0x5ec3c39d,
181 0x57c4c493, 0x54c5c591, 0x51c6c697, 0x52c7c795,
182 0x43c8c88b, 0x40c9c989, 0x45caca8f, 0x46cbcb8d,
183 0x4fcccc83, 0x4ccdcd81, 0x49cece87, 0x4acfcf85,
184 0x6bd0d0bb, 0x68d1d1b9, 0x6dd2d2bf, 0x6ed3d3bd,
185 0x67d4d4b3, 0x64d5d5b1, 0x61d6d6b7, 0x62d7d7b5,
186 0x73d8d8ab, 0x70d9d9a9, 0x75dadaaf, 0x76dbdbad,
187 0x7fdcdca3, 0x7cdddda1, 0x79dedea7, 0x7adfdfa5,
188 0x3be0e0db, 0x38e1e1d9, 0x3de2e2df, 0x3ee3e3dd,
189 0x37e4e4d3, 0x34e5e5d1, 0x31e6e6d7, 0x32e7e7d5,
190 0x23e8e8cb, 0x20e9e9c9, 0x25eaeacf, 0x26ebebcd,
191 0x2fececc3, 0x2cededc1, 0x29eeeec7, 0x2aefefc5,
192 0x0bf0f0fb, 0x08f1f1f9, 0x0df2f2ff, 0x0ef3f3fd,
193 0x07f4f4f3, 0x04f5f5f1, 0x01f6f6f7, 0x02f7f7f5,
194 0x13f8f8eb, 0x10f9f9e9, 0x15fafaef, 0x16fbfbed,
195 0x1ffcfce3, 0x1cfdfde1, 0x19fefee7, 0x1affffe5,
196 }, {
197 /* Inverse MixColumns lookup table */
198 0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12,
199 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
200 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
201 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
202 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2,
203 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
204 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382,
205 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
206 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
207 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
208 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9,
209 0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
210 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029,
211 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
212 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
213 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
214 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf,
215 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
216 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf,
217 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
218 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
219 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
220 0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f,
221 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
222 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664,
223 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
224 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
225 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
226 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684,
227 0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
228 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4,
229 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
230 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
231 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
232 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23,
233 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
234 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3,
235 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
236 0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
237 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
238 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88,
239 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
240 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8,
241 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
242 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
243 0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
244 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418,
245 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
246 0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe,
247 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
248 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
249 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
250 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e,
251 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
252 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e,
253 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
254 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
255 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
256 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255,
257 0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
258 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5,
259 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
260 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
261 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
262 } };
263 union AES_STATE st = { .l = {
264 float64_val(env->vfp.regs[rm]),
265 float64_val(env->vfp.regs[rm + 1])
266 } };
267 int i;
269 assert(decrypt < 2);
271 for (i = 0; i < 16; i += 4) {
272 st.cols[i >> 2] = cpu_to_le32(
273 mc[decrypt][st.bytes[i]] ^
274 rol32(mc[decrypt][st.bytes[i + 1]], 8) ^
275 rol32(mc[decrypt][st.bytes[i + 2]], 16) ^
276 rol32(mc[decrypt][st.bytes[i + 3]], 24));
279 env->vfp.regs[rd] = make_float64(st.l[0]);
280 env->vfp.regs[rd + 1] = make_float64(st.l[1]);