1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2021 Marvell.
3 */
4
5 #include "roc_api.h"
6
7 #define lrot32(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits))))
8 #define rrot32(bits, word) lrot32(32 - (bits), word)
9 #define lrot64(bits, word) (((word) << (bits)) | ((word) >> (64 - (bits))))
10 #define rrot64(bits, word) lrot64(64 - (bits), word)
11
12 #define S11 7
13 #define S12 12
14 #define S13 17
15 #define S14 22
16 #define S21 5
17 #define S22 9
18 #define S23 14
19 #define S24 20
20 #define S31 4
21 #define S32 11
22 #define S33 16
23 #define S34 23
24 #define S41 6
25 #define S42 10
26 #define S43 15
27 #define S44 21
28
29 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
30 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31 #define H(x, y, z) ((x) ^ (y) ^ (z))
32 #define I(x, y, z) ((y) ^ ((x) | (~z)))
33
34 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
35
36 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
37 * Rotation is separate from addition to prevent recomputation.
38 */
39
40 #define FF(a, b, c, d, x, s, ac) \
41 { \
42 (a) += F((b), (c), (d)) + (x) + (uint32_t)(ac); \
43 (a) = ROTATE_LEFT((a), (s)); \
44 (a) += (b); \
45 }
46
47 #define GG(a, b, c, d, x, s, ac) \
48 { \
49 (a) += G((b), (c), (d)) + (x) + (uint32_t)(ac); \
50 (a) = ROTATE_LEFT((a), (s)); \
51 (a) += (b); \
52 }
53
54 #define HH(a, b, c, d, x, s, ac) \
55 { \
56 (a) += H((b), (c), (d)) + (x) + (uint32_t)(ac); \
57 (a) = ROTATE_LEFT((a), (s)); \
58 (a) += (b); \
59 }
60
61 #define II(a, b, c, d, x, s, ac) \
62 { \
63 (a) += I((b), (c), (d)) + (x) + (uint32_t)(ac); \
64 (a) = ROTATE_LEFT((a), (s)); \
65 (a) += (b); \
66 }
67
68 /*
69 * Compute a partial hash with the assumption that msg is the first block.
70 * Based on implementation from RFC 1321
71 */
72 void
roc_hash_md5_gen(uint8_t * msg,uint32_t * hash)73 roc_hash_md5_gen(uint8_t *msg, uint32_t *hash)
74 {
75 uint32_t state[4] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
76 uint32_t a = state[0];
77 uint32_t b = state[1];
78 uint32_t c = state[2];
79 uint32_t d = state[3];
80 uint32_t x[16];
81
82 memcpy(x, msg, 64);
83
84 /* Round 1 */
85 FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
86 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
87 FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
88 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
89 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
90 FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
91 FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
92 FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
93 FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
94 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
95 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
96 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
97 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
98 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
99 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
100 FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
101
102 /* Round 2 */
103 GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
104 GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
105 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
106 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
107 GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
108 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
109 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
110 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
111 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
112 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
113 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
114 GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
115 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
116 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
117 GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
118 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
119
120 /* Round 3 */
121 HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
122 HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
123 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
124 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
125 HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
126 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
127 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
128 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
129 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
130 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
131 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
132 HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
133 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
134 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
135 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
136 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
137
138 /* Round 4 */
139 II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
140 II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
141 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
142 II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
143 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
144 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
145 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
146 II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
147 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
148 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
149 II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
150 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
151 II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
152 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
153 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
154 II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
155
156 state[0] += a;
157 state[1] += b;
158 state[2] += c;
159 state[3] += d;
160
161 hash[0] = state[0];
162 hash[1] = state[1];
163 hash[2] = state[2];
164 hash[3] = state[3];
165 }
166
167 /*
168 * Compute a partial hash with the assumption that msg is the first block.
169 * Based on implementation from RFC 3174
170 */
171 void
roc_hash_sha1_gen(uint8_t * msg,uint32_t * hash)172 roc_hash_sha1_gen(uint8_t *msg, uint32_t *hash)
173 {
174 const uint32_t _K[] = {/* Round Constants defined in SHA-1 */
175 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
176
177 const uint32_t _H[] = {/* Initial Hash constants defined in SHA-1 */
178 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
179 0xC3D2E1F0};
180 int i;
181 uint32_t temp = 0; /* Temporary word value */
182 uint32_t W[80]; /* Word sequence */
183 uint32_t A, B, C, D, E; /* Word buffers */
184
185 /* Initialize the first 16 words in the array W */
186 memcpy(&W[0], msg, 16 * sizeof(W[0]));
187
188 for (i = 0; i < 16; i++)
189 W[i] = htobe32(W[i]);
190
191 for (i = 16; i < 80; i++)
192 W[i] = lrot32(1, W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]);
193
194 A = _H[0];
195 B = _H[1];
196 C = _H[2];
197 D = _H[3];
198 E = _H[4];
199
200 for (i = 0; i < 80; i++) {
201 if (i >= 0 && i <= 19)
202 temp = ((B & C) | ((~B) & D)) + _K[0];
203 else if (i >= 20 && i <= 39)
204 temp = (B ^ C ^ D) + _K[1];
205 else if (i >= 40 && i <= 59)
206 temp = ((B & C) | (B & D) | (C & D)) + _K[2];
207 else if (i >= 60 && i <= 79)
208 temp = (B ^ C ^ D) + _K[3];
209
210 temp = lrot32(5, A) + temp + E + W[i];
211 E = D;
212 D = C;
213 C = lrot32(30, B);
214 B = A;
215 A = temp;
216 }
217
218 A += _H[0];
219 B += _H[1];
220 C += _H[2];
221 D += _H[3];
222 E += _H[4];
223 hash[0] = htobe32(A);
224 hash[1] = htobe32(B);
225 hash[2] = htobe32(C);
226 hash[3] = htobe32(D);
227 hash[4] = htobe32(E);
228 }
229
230 /*
231 * Compute a partial hash with the assumption that msg is the first block.
232 * Based on implementation from RFC 3174
233 */
234 void
roc_hash_sha256_gen(uint8_t * msg,uint32_t * hash,int hash_size)235 roc_hash_sha256_gen(uint8_t *msg, uint32_t *hash, int hash_size)
236 {
237 const uint32_t _K[] = {
238 /* Round Constants defined in SHA-256 */
239 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
240 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
241 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
242 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
243 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
244 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
245 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
246 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
247 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
248 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
249 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
250 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
251 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
252
253 const uint32_t _H224[] = {/* Initial Hash constants defined in SHA-224 */
254 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
255 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
256 const uint32_t _H256[] = {/* Initial Hash constants defined in SHA-256 */
257 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
258 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
259 int i;
260 uint32_t temp[4], S0, S1; /* Temporary word value */
261 uint32_t W[64]; /* Word sequence */
262 uint32_t A, B, C, D, E, F, G, H; /* Word buffers */
263 const uint32_t *_H = (hash_size == 224) ? _H224 : _H256;
264
265 /* Initialize the first 16 words in the array W */
266 memcpy(&W[0], msg, 16 * sizeof(W[0]));
267
268 for (i = 0; i < 16; i++)
269 W[i] = htobe32(W[i]);
270
271 for (i = 16; i < 64; i++) {
272 S0 = rrot32(7, W[i - 15]) ^ rrot32(18, W[i - 15]) ^
273 (W[i - 15] >> 3);
274 S1 = rrot32(17, W[i - 2]) ^ rrot32(19, W[i - 2]) ^
275 (W[i - 2] >> 10);
276 W[i] = W[i - 16] + S0 + W[i - 7] + S1;
277 }
278
279 A = _H[0];
280 B = _H[1];
281 C = _H[2];
282 D = _H[3];
283 E = _H[4];
284 F = _H[5];
285 G = _H[6];
286 H = _H[7];
287
288 for (i = 0; i < 64; i++) {
289 S1 = rrot32(6, E) ^ rrot32(11, E) ^ rrot32(25, E);
290 temp[0] = (E & F) ^ ((~E) & G);
291 temp[1] = H + S1 + temp[0] + _K[i] + W[i];
292 S0 = rrot32(2, A) ^ rrot32(13, A) ^ rrot32(22, A);
293 temp[2] = (A & B) ^ (A & C) ^ (B & C);
294 temp[3] = S0 + temp[2];
295
296 H = G;
297 G = F;
298 F = E;
299 E = D + temp[1];
300 D = C;
301 C = B;
302 B = A;
303 A = temp[1] + temp[3];
304 }
305
306 A += _H[0];
307 B += _H[1];
308 C += _H[2];
309 D += _H[3];
310 E += _H[4];
311 F += _H[5];
312 G += _H[6];
313 H += _H[7];
314 hash[0] = htobe32(A);
315 hash[1] = htobe32(B);
316 hash[2] = htobe32(C);
317 hash[3] = htobe32(D);
318 hash[4] = htobe32(E);
319 hash[5] = htobe32(F);
320 hash[6] = htobe32(G);
321 hash[7] = htobe32(H);
322 }
323
324 /*
325 * Compute a partial hash with the assumption that msg is the first block.
326 * Based on implementation from RFC 3174
327 */
328 void
roc_hash_sha512_gen(uint8_t * msg,uint64_t * hash,int hash_size)329 roc_hash_sha512_gen(uint8_t *msg, uint64_t *hash, int hash_size)
330 {
331 const uint64_t _K[] = {
332 /* Round Constants defined in SHA-512 */
333 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
334 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
335 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
336 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
337 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
338 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
339 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
340 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
341 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
342 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
343 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
344 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
345 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
346 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
347 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
348 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
349 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
350 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
351 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
352 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
353 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
354 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
355 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
356 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
357 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
358 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
359 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
360
361 const uint64_t _H384[] = {/* Initial Hash constants defined in SHA384 */
362 0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
363 0x9159015a3070dd17, 0x152fecd8f70e5939,
364 0x67332667ffc00b31, 0x8eb44a8768581511,
365 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4};
366 const uint64_t _H512[] = {/* Initial Hash constants defined in SHA512 */
367 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
368 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
369 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
370 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179};
371 int i;
372 uint64_t temp[4], S0, S1; /* Temporary word value */
373 uint64_t W[80]; /* Word sequence */
374 uint64_t A, B, C, D, E, F, G, H; /* Word buffers */
375 const uint64_t *_H = (hash_size == 384) ? _H384 : _H512;
376
377 /* Initialize the first 16 words in the array W */
378 memcpy(&W[0], msg, 16 * sizeof(W[0]));
379
380 for (i = 0; i < 16; i++)
381 W[i] = htobe64(W[i]);
382
383 for (i = 16; i < 80; i++) {
384 S0 = rrot64(1, W[i - 15]) ^ rrot64(8, W[i - 15]) ^
385 (W[i - 15] >> 7);
386 S1 = rrot64(19, W[i - 2]) ^ rrot64(61, W[i - 2]) ^
387 (W[i - 2] >> 6);
388 W[i] = W[i - 16] + S0 + W[i - 7] + S1;
389 }
390
391 A = _H[0];
392 B = _H[1];
393 C = _H[2];
394 D = _H[3];
395 E = _H[4];
396 F = _H[5];
397 G = _H[6];
398 H = _H[7];
399
400 for (i = 0; i < 80; i++) {
401 S1 = rrot64(14, E) ^ rrot64(18, E) ^ rrot64(41, E);
402 temp[0] = (E & F) ^ ((~E) & G);
403 temp[1] = H + S1 + temp[0] + _K[i] + W[i];
404 S0 = rrot64(28, A) ^ rrot64(34, A) ^ rrot64(39, A);
405 temp[2] = (A & B) ^ (A & C) ^ (B & C);
406 temp[3] = S0 + temp[2];
407
408 H = G;
409 G = F;
410 F = E;
411 E = D + temp[1];
412 D = C;
413 C = B;
414 B = A;
415 A = temp[1] + temp[3];
416 }
417
418 A += _H[0];
419 B += _H[1];
420 C += _H[2];
421 D += _H[3];
422 E += _H[4];
423 F += _H[5];
424 G += _H[6];
425 H += _H[7];
426 hash[0] = htobe64(A);
427 hash[1] = htobe64(B);
428 hash[2] = htobe64(C);
429 hash[3] = htobe64(D);
430 hash[4] = htobe64(E);
431 hash[5] = htobe64(F);
432 hash[6] = htobe64(G);
433 hash[7] = htobe64(H);
434 }
435