xref: /dpdk/drivers/common/cnxk/roc_hash.c (revision 470071c85630c89bdc2e7661354298f485ae8be4)
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