misc: Merged release-staging-v19.0.0.0 into develop
[gem5.git] / src / arch / arm / qarma.cc
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2020 Metempsy Technology Consulting
4 // All rights reserved
5 //
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
14 //
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38 #include "arch/arm/qarma.hh"
39
40 #include "base/bitfield.hh"
41
42 using namespace QARMA;
43 using namespace std;
44
45
46 uint8_t
47 QARMA::rotCell(uint8_t incell, int amount)
48 {
49 uint8_t res = ((incell << amount) | (incell >> (4-amount)))& 0xF;
50 return res;
51 }
52
53 uint8_t
54 QARMA::tweakCellInvRot(uint8_t incell)
55 {
56 uint8_t outcell = 0x0;
57 outcell = incell << 1;
58 uint8_t t = 0x1 & (incell ^ (incell>>3));
59 outcell |= t;
60 return outcell & 0xF;
61 }
62
63 uint8_t
64 QARMA::tweakCellRot(uint8_t incell)
65 {
66 uint8_t outcell = 0x0;
67 outcell = incell >> 1;
68 uint8_t t = 0x1 & (incell ^ (incell>>1));
69 outcell |= t<<3;
70 return outcell & 0xF;
71 }
72
73 BIT64
74 QARMA::tweakInvShuffle(BIT64 indata)
75 {
76 BIT64 outdata = 0x0;
77 outdata.b0 = tweakCellInvRot(indata.b12);
78 outdata.b1 = indata.b13;
79 outdata.b2 = indata.b5;
80 outdata.b3 = indata.b6;
81 outdata.b4 = indata.b0;
82 outdata.b5 = indata.b1;
83 outdata.b6 = tweakCellInvRot(indata.b2);
84 outdata.b7 = indata.b3;
85 outdata.b8 = tweakCellInvRot(indata.b7);
86 outdata.b9 = tweakCellInvRot(indata.b15);
87 outdata.b10 = tweakCellInvRot(indata.b14);
88 outdata.b11 = tweakCellInvRot(indata.b4);
89 outdata.b12 = indata.b8;
90 outdata.b13 = indata.b9;
91 outdata.b14 = indata.b10;
92 outdata.b15 = tweakCellInvRot(indata.b11);
93 return outdata;
94 }
95
96 BIT64
97 QARMA::tweakShuffle(BIT64 indata)
98 {
99 BIT64 outdata = 0x0;
100 outdata.b0 = indata.b4;
101 outdata.b1 = indata.b5;
102 outdata.b2 = tweakCellRot(indata.b6);
103 outdata.b3 = indata.b7;
104 outdata.b4 = tweakCellRot(indata.b11);
105 outdata.b5 = indata.b2;
106 outdata.b6 = indata.b3;
107 outdata.b7 = tweakCellRot(indata.b8);
108 outdata.b8 = indata.b12;
109 outdata.b9 = indata.b13;
110 outdata.b10 = indata.b14;
111 outdata.b11 = tweakCellRot(indata.b15);
112 outdata.b12 = tweakCellRot(indata.b0);
113 outdata.b13 = indata.b1;
114 outdata.b14 = tweakCellRot(indata.b10);
115 outdata.b15 = tweakCellRot(indata.b9);
116 return outdata;
117 }
118
119
120 BIT64
121 QARMA::PACCellInvShuffle(BIT64 indata)
122 {
123 BIT64 outdata = 0x0;
124 outdata.b0 = indata.b3;
125 outdata.b1 = indata.b6;
126 outdata.b2 = indata.b12;
127 outdata.b3 = indata.b9;
128 outdata.b4 = indata.b14;
129 outdata.b5 = indata.b11;
130 outdata.b6 = indata.b1;
131 outdata.b7 = indata.b4;
132 outdata.b8 = indata.b8;
133 outdata.b9 = indata.b13;
134 outdata.b10 = indata.b7;
135 outdata.b11 = indata.b2;
136 outdata.b12 = indata.b5;
137 outdata.b13 = indata.b0;
138 outdata.b14 = indata.b10;
139 outdata.b15 = indata.b15;
140 return outdata;
141 }
142
143 BIT64
144 QARMA::PACCellShuffle(BIT64 indata)
145 {
146 BIT64 outdata = 0x0;
147 outdata.b0 = indata.b13;
148 outdata.b1 = indata.b6;
149 outdata.b2 = indata.b11;
150 outdata.b3 = indata.b0;
151 outdata.b4 = indata.b7;
152 outdata.b5 = indata.b12;
153 outdata.b6 = indata.b1;
154 outdata.b7 = indata.b10;
155 outdata.b8 = indata.b8;
156 outdata.b9 = indata.b3;
157 outdata.b10 = indata.b14;
158 outdata.b11 = indata.b5;
159 outdata.b12 = indata.b2;
160 outdata.b13 = indata.b9;
161 outdata.b14 = indata.b4;
162 outdata.b15 = indata.b15;
163 return outdata;
164 }
165
166
167 uint64_t
168 QARMA::PACInvSub(uint64_t tInput)
169 {
170 // This is a 4-bit substitution from the PRINCE-family cipher
171 uint64_t t_output = 0x0;
172 for (int i=15; i>=0; i--) {
173 t_output = t_output << 4;
174 uint8_t b = (tInput >> i*4 ) & 0xF;
175 switch ( b ) {
176 case 0x0:
177 t_output |= 0x5;
178 break;
179 case 0x1:
180 t_output |= 0xe;
181 break;
182 case 0x2:
183 t_output |= 0xd;
184 break;
185 case 0x3:
186 t_output |= 0x8;
187 break;
188 case 0x4:
189 t_output |= 0xa;
190 break;
191 case 0x5:
192 t_output |= 0xb;
193 break;
194 case 0x6:
195 t_output |= 0x1;
196 break;
197 case 0x7:
198 t_output |= 0x9;
199 break;
200 case 0x8:
201 t_output |= 0x2;
202 break;
203 case 0x9:
204 t_output |= 0x6;
205 break;
206 case 0xa:
207 t_output |= 0xf;
208 break;
209 case 0xb:
210 t_output |= 0x0;
211 break;
212 case 0xc:
213 t_output |= 0x4;
214 break;
215 case 0xd:
216 t_output |= 0xc;
217 break;
218 case 0xe:
219 t_output |= 0x7;
220 break;
221 case 0xf:
222 t_output |= 0x3;
223 break;
224 default:
225 //unreachable
226 break;
227 }
228 }
229 return t_output;
230 }
231
232 uint64_t
233 QARMA::PACSub(uint64_t tInput){
234 // This is a 4-bit substitution from the PRINCE-family cipher
235 uint64_t t_output = 0x0;
236 for (int i=15; i>=0; i--) {
237 t_output = t_output << 4;
238 uint8_t b = (tInput >> i*4 ) & 0xF;
239 switch ( b ) {
240 case 0x0:
241 t_output |= 0xb;
242 break;
243 case 0x1:
244 t_output |= 0x6;
245 break;
246 case 0x2:
247 t_output |= 0x8;
248 break;
249 case 0x3:
250 t_output |= 0xf;
251 break;
252 case 0x4:
253 t_output |= 0xc;
254 break;
255 case 0x5:
256 t_output |= 0x0;
257 break;
258 case 0x6:
259 t_output |= 0x9;
260 break;
261 case 0x7:
262 t_output |= 0xe;
263 break;
264 case 0x8:
265 t_output |= 0x3;
266 break;
267 case 0x9:
268 t_output |= 0x7;
269 break;
270 case 0xa:
271 t_output |= 0x4;
272 break;
273 case 0xb:
274 t_output |= 0x5;
275 break;
276 case 0xc:
277 t_output |= 0xd;
278 break;
279 case 0xd:
280 t_output |= 0x2;
281 break;
282 case 0xe:
283 t_output |= 0x1;
284 break;
285 case 0xf:
286 t_output |= 0xa;
287 break;
288 default:
289 //unreachable
290 break;
291 }
292 }
293 return t_output;
294 }
295
296 uint64_t
297 QARMA::PACMult(uint64_t tInput)
298 {
299 uint64_t t_output = 0;
300
301 for (int i=0;i<=3; i++) {
302 uint8_t b8 = (tInput >> (4*(i+8))) & 0xF;
303 uint8_t b4 = (tInput >> (4*(i+4))) & 0xF;
304 uint8_t b12 = (tInput >> (4*(i+12))) & 0xF;
305 uint8_t b0 = (tInput >> (4*(i))) & 0xF;
306
307 uint64_t t0 = rotCell(b8, 1) ^ rotCell(b4, 2);
308 t0 = t0 ^ rotCell(b0, 1);
309
310 uint64_t t1 = rotCell(b12, 1) ^ rotCell(b4, 1);
311 t1 = t1 ^ rotCell(b0, 2);
312
313 uint64_t t2 = rotCell(b12, 2) ^ rotCell(b8, 1);
314 t2 = t2 ^ rotCell(b0, 1);
315
316 uint64_t t3 = rotCell(b12, 1) ^ rotCell(b8, 2);
317 t3 = t3 ^ rotCell(b4, 1);
318
319 t_output |= (t3 << (4*i));
320 t_output |= (t2 << (4*(i+4)));
321 t_output |= (t1 << (4*(i+8)));
322 t_output |= (t0 << (4*(i+12)));
323 }
324 return t_output;
325 }
326
327 BIT64
328 QARMA::computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
329 {
330 BIT64 workingval;
331 BIT64 runningmod;
332 BIT64 roundkey;
333 BIT64 modk0;
334 std::array<BIT64, 5> RC;
335 RC[0] = (BIT64) 0x0000000000000000;
336 RC[1] = (BIT64) 0x13198A2E03707344;
337 RC[2] = (BIT64) 0xA4093822299F31D0;
338 RC[3] = (BIT64) 0x082EFA98EC4E6C89;
339 RC[4] = (BIT64) 0x452821E638D01377;
340
341 const BIT64 alpha = 0xC0AC29B7C97C50DD;
342 //modk0 = key0<0>:key0<63:2>:
343
344 modk0 = (key0 & 0x1) << 63;
345 modk0 = modk0 | ((key0 & ~0x3) >> 1);
346 modk0 = modk0 | ((key0.b15>>3) ^ ((key0.b0 & 0x2)>>1));
347
348 runningmod = modifier;
349 workingval = data^key0;
350 for (int i=0; i<=4; i++) {
351 roundkey = key1 ^ runningmod;
352 workingval = workingval ^ roundkey;
353 workingval = workingval ^ RC[i];
354
355 if (i > 0) {
356 workingval = PACCellShuffle(workingval);
357 workingval = PACMult(workingval);
358 }
359 workingval = PACSub(workingval);
360 runningmod = tweakShuffle(runningmod);
361 }
362 roundkey = modk0 ^ runningmod;
363 workingval = workingval ^ roundkey;
364
365 workingval = PACCellShuffle(workingval);
366 workingval = PACMult(workingval);
367 workingval = PACSub(workingval);
368 workingval = PACCellShuffle(workingval);
369 workingval = PACMult(workingval);
370 workingval = key1 ^ workingval;
371
372 workingval = PACCellInvShuffle(workingval);
373 workingval = PACInvSub(workingval);
374 workingval = PACMult(workingval);
375 workingval = PACCellInvShuffle(workingval);
376 workingval = workingval ^ key0;
377 workingval = workingval ^ runningmod;
378
379 for (int i=0; i<=4; i++) {
380 workingval = PACInvSub(workingval);
381 if (i < 4) {
382 workingval = PACMult(workingval);
383 workingval = PACCellInvShuffle(workingval);
384 }
385 runningmod = tweakInvShuffle(runningmod);
386 roundkey = key1 ^ runningmod;
387 workingval = workingval ^ RC[4-i];
388 workingval = workingval ^ roundkey;
389 workingval = workingval ^ alpha;
390 }
391 workingval = workingval ^ modk0;
392 return workingval;
393 }
394