Deleted Added
sdiff udiff text old ( 13168:4965381c122d ) new ( 13169:eb3b2bea4231 )
full compact
1/*
2 * Copyright (c) 2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Matt Horsnell
38 * Prakash Ramrakhyani
39 */
40
41#include <cstdio>
42#include <iostream>
43#include <string>
44
45#include "crypto.hh"
46
47namespace ArmISA {
48
49void
50Crypto::sha256Op(
51 uint32_t *X,
52 uint32_t *Y,
53 uint32_t *Z)
54{
55 uint32_t T0, T1, T2, T3;
56 for (int i = 0; i < 4; ++i) {
57 T0 = choose(Y[0], Y[1], Y[2]);
58 T1 = majority(X[0], X[1], X[2]);
59 T2 = Y[3] + sigma1(Y[0]) + T0 + Z[i];
60 X[3] = T2 + X[3];
61 Y[3] = T2 + sigma0(X[0]) + T1;
62 // Rotate
63 T3 = Y[3];
64 Y[3] = Y[2]; Y[2] = Y[1]; Y[1] = Y[0]; Y[0] = X[3];
65 X[3] = X[2]; X[2] = X[1]; X[1] = X[0]; X[0] = T3;
66 }
67}
68
69void
70Crypto::_sha1Op(
71 uint32_t *X,
72 uint32_t *Y,
73 uint32_t *Z,
74 SHAOp op)
75{
76 uint32_t T1, T2;
77
78 for (int i = 0; i < 4; ++i) {
79 switch (op) {
80 case CHOOSE: T1 = choose(X[1], X[2], X[3]); break;
81 case PARITY: T1 = parity(X[1], X[2], X[3]); break;
82 case MAJORITY: T1 = majority(X[1], X[2], X[3]); break;
83 default: return;
84 }
85 Y[0] += ror(X[0], 27) + T1 + Z[i];
86 X[1] = ror(X[1], 2);
87 T2 = Y[0];
88 Y[0] = X[3];
89 X[3] = X[2]; X[2] = X[1]; X[1] = X[0]; X[0] = T2;
90 }
91}
92
93void
94Crypto::sha256H(
95 uint8_t *output,
96 uint8_t *input,
97 uint8_t *input2)
98{
99 uint32_t X[4], Y[4], Z[4];
100 load3Reg(&X[0], &Y[0], &Z[0], output, input, input2);
101 sha256Op(&X[0], &Y[0], &Z[0]);
102 store1Reg(output, &X[0]);
103}
104
105void
106Crypto::sha256H2(
107 uint8_t *output,
108 uint8_t *input,
109 uint8_t *input2)
110{
111 uint32_t X[4], Y[4], Z[4];
112 load3Reg(&X[0], &Y[0], &Z[0], output, input, input2);
113 sha256Op(&Y[0], &X[0], &Z[0]);
114 store1Reg(output, &X[0]);
115}
116
117void
118Crypto::sha256Su0(uint8_t *output, uint8_t *input)
119{
120 uint32_t X[4], Y[4];
121 uint32_t T[4];
122
123 load2Reg(&X[0], &Y[0], output, input);
124
125 T[3] = Y[0]; T[2] = X[3]; T[1] = X[2]; T[0] = X[1];
126
127 T[3] = ror(T[3], 7) ^ ror(T[3], 18) ^ (T[3] >> 3);
128 T[2] = ror(T[2], 7) ^ ror(T[2], 18) ^ (T[2] >> 3);
129 T[1] = ror(T[1], 7) ^ ror(T[1], 18) ^ (T[1] >> 3);
130 T[0] = ror(T[0], 7) ^ ror(T[0], 18) ^ (T[0] >> 3);
131
132 X[3] += T[3];
133 X[2] += T[2];
134 X[1] += T[1];
135 X[0] += T[0];
136
137 store1Reg(output, &X[0]);
138}
139
140void
141Crypto::sha256Su1(
142 uint8_t *output,
143 uint8_t *input,
144 uint8_t *input2)
145{
146 uint32_t X[4], Y[4], Z[4];
147 uint32_t T0[4], T1[4], T2[4], T3[4];
148
149 load3Reg(&X[0], &Y[0], &Z[0], output, input, input2);
150
151 T0[3] = Z[0]; T0[2] = Y[3]; T0[1] = Y[2]; T0[0] = Y[1];
152 T1[1] = Z[3]; T1[0] = Z[2];
153 T1[1] = ror(T1[1], 17) ^ ror(T1[1], 19) ^ (T1[1] >> 10);
154 T1[0] = ror(T1[0], 17) ^ ror(T1[0], 19) ^ (T1[0] >> 10);
155 T3[1] = X[1] + T0[1]; T3[0] = X[0] + T0[0];
156 T1[1] = T3[1] + T1[1]; T1[0] = T3[0] + T1[0];
157 T2[1] = ror(T1[1], 17) ^ ror(T1[1], 19) ^ (T1[1] >> 10);
158 T2[0] = ror(T1[0], 17) ^ ror(T1[0], 19) ^ (T1[0] >> 10);
159 T3[1] = X[3] + T0[3]; T3[0] = X[2] + T0[2];
160 X[3] = T3[1] + T2[1];
161 X[2] = T3[0] + T2[0];
162 X[1] = T1[1]; X[0] = T1[0];
163
164 store1Reg(output, &X[0]);
165}
166
167void
168Crypto::sha1Op(
169 uint8_t *output,
170 uint8_t *input,
171 uint8_t *input2,
172 SHAOp op)
173{
174 uint32_t X[4], Y[4], Z[4];
175 load3Reg(&X[0], &Y[0], &Z[0], output, input, input2);
176 _sha1Op(&X[0], &Y[0], &Z[0], op);
177 store1Reg(output, &X[0]);
178}
179
180void
181Crypto::sha1C(
182 uint8_t *output,
183 uint8_t *input,
184 uint8_t *input2)
185{
186 sha1Op(output, input, input2, CHOOSE);
187}
188
189void
190Crypto::sha1P(
191 uint8_t *output,
192 uint8_t *input,
193 uint8_t *input2)
194{
195 sha1Op(output, input, input2, PARITY);
196}
197
198void
199Crypto::sha1M(
200 uint8_t *output,
201 uint8_t *input,
202 uint8_t *input2)
203{
204 sha1Op(output, input, input2, MAJORITY);
205}
206
207void
208Crypto::sha1H(uint8_t *output, uint8_t *input)
209{
210 uint32_t X[4], Y[4];
211 load2Reg(&X[0], &Y[0], output, input);
212 X[0] = ror(Y[0], 2);
213 store1Reg(output, &X[0]);
214}
215
216void
217Crypto::sha1Su0(
218 uint8_t *output,
219 uint8_t *input,
220 uint8_t *input2)
221{
222 uint32_t X[4], Y[4], Z[4], T[4];
223 load3Reg(&X[0], &Y[0], &Z[0], output, input, input2);
224
225 T[3] = Y[1]; T[2] = Y[0]; T[1] = X[3]; T[0] = X[2];
226 X[3] = T[3] ^ X[3] ^ Z[3];
227 X[2] = T[2] ^ X[2] ^ Z[2];
228 X[1] = T[1] ^ X[1] ^ Z[1];
229 X[0] = T[0] ^ X[0] ^ Z[0];
230
231 store1Reg(output, &X[0]);
232}
233
234void
235Crypto::sha1Su1(uint8_t *output, uint8_t *input)
236{
237 uint32_t X[4], Y[4], T[4];
238 load2Reg(&X[0], &Y[0], output, input);
239
240 T[3] = X[3] ^ 0x0;
241 T[2] = X[2] ^ Y[3];
242 T[1] = X[1] ^ Y[2];
243 T[0] = X[0] ^ Y[1];
244 X[2] = ror(T[2], 31); X[1] = ror(T[1], 31); X[0] = ror(T[0], 31);
245 X[3] = ror(T[3], 31) ^ ror(T[0], 30);
246
247 store1Reg(output, &X[0]);
248}
249
250void
251Crypto::load2Reg(
252 uint32_t *X,
253 uint32_t *Y,
254 uint8_t *output,
255 uint8_t *input)
256{
257 for (int i = 0; i < 4; ++i) {
258 X[i] = *((uint32_t *)&output[i*4]);
259 Y[i] = *((uint32_t *)&input[i*4]);
260 }
261}
262
263void
264Crypto::load3Reg(
265 uint32_t *X,
266 uint32_t *Y,
267 uint32_t *Z,
268 uint8_t *output,
269 uint8_t *input,
270 uint8_t *input2)
271{
272 for (int i = 0; i < 4; ++i) {
273 X[i] = *((uint32_t *)&output[i*4]);
274 Y[i] = *((uint32_t *)&input[i*4]);
275 Z[i] = *((uint32_t *)&input2[i*4]);
276 }
277}
278
279void
280Crypto::store1Reg(uint8_t *output, uint32_t *X)
281{
282 for (int i = 0; i < 4; ++i) {
283 output[i*4] = (uint8_t)(X[i]);
284 output[i*4+1] = (uint8_t)(X[i] >> 8);
285 output[i*4+2] = (uint8_t)(X[i] >> 16);
286 output[i*4+3] = (uint8_t)(X[i] >> 24);
287 }
288}
289
290} // namespace ArmISA