3 // Copyright (c) 2020 Metempsy Technology Consulting
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.
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.
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.
38 #include "arch/arm/qarma.hh"
40 #include "base/bitfield.hh"
42 using namespace QARMA
;
47 QARMA::rotCell(uint8_t incell
, int amount
)
49 uint8_t res
= ((incell
<< amount
) | (incell
>> (4-amount
)))& 0xF;
54 QARMA::tweakCellInvRot(uint8_t incell
)
56 uint8_t outcell
= 0x0;
57 outcell
= incell
<< 1;
58 uint8_t t
= 0x1 & (incell
^ (incell
>>3));
64 QARMA::tweakCellRot(uint8_t incell
)
66 uint8_t outcell
= 0x0;
67 outcell
= incell
>> 1;
68 uint8_t t
= 0x1 & (incell
^ (incell
>>1));
74 QARMA::tweakInvShuffle(BIT64 indata
)
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
);
97 QARMA::tweakShuffle(BIT64 indata
)
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
);
121 QARMA::PACCellInvShuffle(BIT64 indata
)
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
;
144 QARMA::PACCellShuffle(BIT64 indata
)
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
;
168 QARMA::PACInvSub(uint64_t tInput
)
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;
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;
297 QARMA::PACMult(uint64_t tInput
)
299 uint64_t t_output
= 0;
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;
307 uint64_t t0
= rotCell(b8
, 1) ^ rotCell(b4
, 2);
308 t0
= t0
^ rotCell(b0
, 1);
310 uint64_t t1
= rotCell(b12
, 1) ^ rotCell(b4
, 1);
311 t1
= t1
^ rotCell(b0
, 2);
313 uint64_t t2
= rotCell(b12
, 2) ^ rotCell(b8
, 1);
314 t2
= t2
^ rotCell(b0
, 1);
316 uint64_t t3
= rotCell(b12
, 1) ^ rotCell(b8
, 2);
317 t3
= t3
^ rotCell(b4
, 1);
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)));
328 QARMA::computePAC(BIT64 data
, BIT64 modifier
, BIT64 key0
, BIT64 key1
)
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;
341 const BIT64 alpha
= 0xC0AC29B7C97C50DD;
342 //modk0 = key0<0>:key0<63:2>:
344 modk0
= (key0
& 0x1) << 63;
345 modk0
= modk0
| ((key0
& ~0x3) >> 1);
346 modk0
= modk0
| ((key0
.b15
>>3) ^ ((key0
.b0
& 0x2)>>1));
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
];
356 workingval
= PACCellShuffle(workingval
);
357 workingval
= PACMult(workingval
);
359 workingval
= PACSub(workingval
);
360 runningmod
= tweakShuffle(runningmod
);
362 roundkey
= modk0
^ runningmod
;
363 workingval
= workingval
^ roundkey
;
365 workingval
= PACCellShuffle(workingval
);
366 workingval
= PACMult(workingval
);
367 workingval
= PACSub(workingval
);
368 workingval
= PACCellShuffle(workingval
);
369 workingval
= PACMult(workingval
);
370 workingval
= key1
^ workingval
;
372 workingval
= PACCellInvShuffle(workingval
);
373 workingval
= PACInvSub(workingval
);
374 workingval
= PACMult(workingval
);
375 workingval
= PACCellInvShuffle(workingval
);
376 workingval
= workingval
^ key0
;
377 workingval
= workingval
^ runningmod
;
379 for (int i
=0; i
<=4; i
++) {
380 workingval
= PACInvSub(workingval
);
382 workingval
= PACMult(workingval
);
383 workingval
= PACCellInvShuffle(workingval
);
385 runningmod
= tweakInvShuffle(runningmod
);
386 roundkey
= key1
^ runningmod
;
387 workingval
= workingval
^ RC
[4-i
];
388 workingval
= workingval
^ roundkey
;
389 workingval
= workingval
^ alpha
;
391 workingval
= workingval
^ modk0
;