xref: /dpdk/drivers/common/cnxk/roc_hash.c (revision 470071c85630c89bdc2e7661354298f485ae8be4)
1d85f9749STejasree Kondoj /* SPDX-License-Identifier: BSD-3-Clause
2d85f9749STejasree Kondoj  * Copyright (c) 2021 Marvell.
3d85f9749STejasree Kondoj  */
4d85f9749STejasree Kondoj 
5d85f9749STejasree Kondoj #include "roc_api.h"
6d85f9749STejasree Kondoj 
7d85f9749STejasree Kondoj #define lrot32(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits))))
8d85f9749STejasree Kondoj #define rrot32(bits, word) lrot32(32 - (bits), word)
9d85f9749STejasree Kondoj #define lrot64(bits, word) (((word) << (bits)) | ((word) >> (64 - (bits))))
10d85f9749STejasree Kondoj #define rrot64(bits, word) lrot64(64 - (bits), word)
11d85f9749STejasree Kondoj 
12729085b5SVidya Sagar Velumuri #define S11 7
13729085b5SVidya Sagar Velumuri #define S12 12
14729085b5SVidya Sagar Velumuri #define S13 17
15729085b5SVidya Sagar Velumuri #define S14 22
16729085b5SVidya Sagar Velumuri #define S21 5
17729085b5SVidya Sagar Velumuri #define S22 9
18729085b5SVidya Sagar Velumuri #define S23 14
19729085b5SVidya Sagar Velumuri #define S24 20
20729085b5SVidya Sagar Velumuri #define S31 4
21729085b5SVidya Sagar Velumuri #define S32 11
22729085b5SVidya Sagar Velumuri #define S33 16
23729085b5SVidya Sagar Velumuri #define S34 23
24729085b5SVidya Sagar Velumuri #define S41 6
25729085b5SVidya Sagar Velumuri #define S42 10
26729085b5SVidya Sagar Velumuri #define S43 15
27729085b5SVidya Sagar Velumuri #define S44 21
28729085b5SVidya Sagar Velumuri 
29729085b5SVidya Sagar Velumuri #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
30729085b5SVidya Sagar Velumuri #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31729085b5SVidya Sagar Velumuri #define H(x, y, z) ((x) ^ (y) ^ (z))
32729085b5SVidya Sagar Velumuri #define I(x, y, z) ((y) ^ ((x) | (~z)))
33729085b5SVidya Sagar Velumuri 
34729085b5SVidya Sagar Velumuri #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
35729085b5SVidya Sagar Velumuri 
36729085b5SVidya Sagar Velumuri /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
37729085b5SVidya Sagar Velumuri  * Rotation is separate from addition to prevent recomputation.
38729085b5SVidya Sagar Velumuri  */
39729085b5SVidya Sagar Velumuri 
40729085b5SVidya Sagar Velumuri #define FF(a, b, c, d, x, s, ac)                                                                   \
41729085b5SVidya Sagar Velumuri 	{                                                                                          \
42729085b5SVidya Sagar Velumuri 		(a) += F((b), (c), (d)) + (x) + (uint32_t)(ac);                                    \
43729085b5SVidya Sagar Velumuri 		(a) = ROTATE_LEFT((a), (s));                                                       \
44729085b5SVidya Sagar Velumuri 		(a) += (b);                                                                        \
45729085b5SVidya Sagar Velumuri 	}
46729085b5SVidya Sagar Velumuri 
47729085b5SVidya Sagar Velumuri #define GG(a, b, c, d, x, s, ac)                                                                   \
48729085b5SVidya Sagar Velumuri 	{                                                                                          \
49729085b5SVidya Sagar Velumuri 		(a) += G((b), (c), (d)) + (x) + (uint32_t)(ac);                                    \
50729085b5SVidya Sagar Velumuri 		(a) = ROTATE_LEFT((a), (s));                                                       \
51729085b5SVidya Sagar Velumuri 		(a) += (b);                                                                        \
52729085b5SVidya Sagar Velumuri 	}
53729085b5SVidya Sagar Velumuri 
54729085b5SVidya Sagar Velumuri #define HH(a, b, c, d, x, s, ac)                                                                   \
55729085b5SVidya Sagar Velumuri 	{                                                                                          \
56729085b5SVidya Sagar Velumuri 		(a) += H((b), (c), (d)) + (x) + (uint32_t)(ac);                                    \
57729085b5SVidya Sagar Velumuri 		(a) = ROTATE_LEFT((a), (s));                                                       \
58729085b5SVidya Sagar Velumuri 		(a) += (b);                                                                        \
59729085b5SVidya Sagar Velumuri 	}
60729085b5SVidya Sagar Velumuri 
61729085b5SVidya Sagar Velumuri #define II(a, b, c, d, x, s, ac)                                                                   \
62729085b5SVidya Sagar Velumuri 	{                                                                                          \
63729085b5SVidya Sagar Velumuri 		(a) += I((b), (c), (d)) + (x) + (uint32_t)(ac);                                    \
64729085b5SVidya Sagar Velumuri 		(a) = ROTATE_LEFT((a), (s));                                                       \
65729085b5SVidya Sagar Velumuri 		(a) += (b);                                                                        \
66729085b5SVidya Sagar Velumuri 	}
67729085b5SVidya Sagar Velumuri 
68729085b5SVidya Sagar Velumuri /*
69729085b5SVidya Sagar Velumuri  * Compute a partial hash with the assumption that msg is the first block.
70729085b5SVidya Sagar Velumuri  * Based on implementation from RFC 1321
71729085b5SVidya Sagar Velumuri  */
72729085b5SVidya Sagar Velumuri void
roc_hash_md5_gen(uint8_t * msg,uint32_t * hash)73729085b5SVidya Sagar Velumuri roc_hash_md5_gen(uint8_t *msg, uint32_t *hash)
74729085b5SVidya Sagar Velumuri {
75729085b5SVidya Sagar Velumuri 	uint32_t state[4] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
76729085b5SVidya Sagar Velumuri 	uint32_t a = state[0];
77729085b5SVidya Sagar Velumuri 	uint32_t b = state[1];
78729085b5SVidya Sagar Velumuri 	uint32_t c = state[2];
79729085b5SVidya Sagar Velumuri 	uint32_t d = state[3];
80729085b5SVidya Sagar Velumuri 	uint32_t x[16];
81729085b5SVidya Sagar Velumuri 
82729085b5SVidya Sagar Velumuri 	memcpy(x, msg, 64);
83729085b5SVidya Sagar Velumuri 
84729085b5SVidya Sagar Velumuri 	/* Round 1 */
85729085b5SVidya Sagar Velumuri 	FF(a, b, c, d, x[0], S11, 0xd76aa478);	/* 1 */
86729085b5SVidya Sagar Velumuri 	FF(d, a, b, c, x[1], S12, 0xe8c7b756);	/* 2 */
87729085b5SVidya Sagar Velumuri 	FF(c, d, a, b, x[2], S13, 0x242070db);	/* 3 */
88729085b5SVidya Sagar Velumuri 	FF(b, c, d, a, x[3], S14, 0xc1bdceee);	/* 4 */
89729085b5SVidya Sagar Velumuri 	FF(a, b, c, d, x[4], S11, 0xf57c0faf);	/* 5 */
90729085b5SVidya Sagar Velumuri 	FF(d, a, b, c, x[5], S12, 0x4787c62a);	/* 6 */
91729085b5SVidya Sagar Velumuri 	FF(c, d, a, b, x[6], S13, 0xa8304613);	/* 7 */
92729085b5SVidya Sagar Velumuri 	FF(b, c, d, a, x[7], S14, 0xfd469501);	/* 8 */
93729085b5SVidya Sagar Velumuri 	FF(a, b, c, d, x[8], S11, 0x698098d8);	/* 9 */
94729085b5SVidya Sagar Velumuri 	FF(d, a, b, c, x[9], S12, 0x8b44f7af);	/* 10 */
95729085b5SVidya Sagar Velumuri 	FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
96729085b5SVidya Sagar Velumuri 	FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
97729085b5SVidya Sagar Velumuri 	FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
98729085b5SVidya Sagar Velumuri 	FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
99729085b5SVidya Sagar Velumuri 	FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
100729085b5SVidya Sagar Velumuri 	FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
101729085b5SVidya Sagar Velumuri 
102729085b5SVidya Sagar Velumuri 	/* Round 2 */
103729085b5SVidya Sagar Velumuri 	GG(a, b, c, d, x[1], S21, 0xf61e2562);	/* 17 */
104729085b5SVidya Sagar Velumuri 	GG(d, a, b, c, x[6], S22, 0xc040b340);	/* 18 */
105729085b5SVidya Sagar Velumuri 	GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
106729085b5SVidya Sagar Velumuri 	GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);	/* 20 */
107729085b5SVidya Sagar Velumuri 	GG(a, b, c, d, x[5], S21, 0xd62f105d);	/* 21 */
108729085b5SVidya Sagar Velumuri 	GG(d, a, b, c, x[10], S22, 0x2441453);	/* 22 */
109729085b5SVidya Sagar Velumuri 	GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
110729085b5SVidya Sagar Velumuri 	GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);	/* 24 */
111729085b5SVidya Sagar Velumuri 	GG(a, b, c, d, x[9], S21, 0x21e1cde6);	/* 25 */
112729085b5SVidya Sagar Velumuri 	GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
113729085b5SVidya Sagar Velumuri 	GG(c, d, a, b, x[3], S23, 0xf4d50d87);	/* 27 */
114729085b5SVidya Sagar Velumuri 	GG(b, c, d, a, x[8], S24, 0x455a14ed);	/* 28 */
115729085b5SVidya Sagar Velumuri 	GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
116729085b5SVidya Sagar Velumuri 	GG(d, a, b, c, x[2], S22, 0xfcefa3f8);	/* 30 */
117729085b5SVidya Sagar Velumuri 	GG(c, d, a, b, x[7], S23, 0x676f02d9);	/* 31 */
118729085b5SVidya Sagar Velumuri 	GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
119729085b5SVidya Sagar Velumuri 
120729085b5SVidya Sagar Velumuri 	/* Round 3 */
121729085b5SVidya Sagar Velumuri 	HH(a, b, c, d, x[5], S31, 0xfffa3942);	/* 33 */
122729085b5SVidya Sagar Velumuri 	HH(d, a, b, c, x[8], S32, 0x8771f681);	/* 34 */
123729085b5SVidya Sagar Velumuri 	HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
124729085b5SVidya Sagar Velumuri 	HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
125729085b5SVidya Sagar Velumuri 	HH(a, b, c, d, x[1], S31, 0xa4beea44);	/* 37 */
126729085b5SVidya Sagar Velumuri 	HH(d, a, b, c, x[4], S32, 0x4bdecfa9);	/* 38 */
127729085b5SVidya Sagar Velumuri 	HH(c, d, a, b, x[7], S33, 0xf6bb4b60);	/* 39 */
128729085b5SVidya Sagar Velumuri 	HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
129729085b5SVidya Sagar Velumuri 	HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
130729085b5SVidya Sagar Velumuri 	HH(d, a, b, c, x[0], S32, 0xeaa127fa);	/* 42 */
131729085b5SVidya Sagar Velumuri 	HH(c, d, a, b, x[3], S33, 0xd4ef3085);	/* 43 */
132729085b5SVidya Sagar Velumuri 	HH(b, c, d, a, x[6], S34, 0x4881d05);	/* 44 */
133729085b5SVidya Sagar Velumuri 	HH(a, b, c, d, x[9], S31, 0xd9d4d039);	/* 45 */
134729085b5SVidya Sagar Velumuri 	HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
135729085b5SVidya Sagar Velumuri 	HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
136729085b5SVidya Sagar Velumuri 	HH(b, c, d, a, x[2], S34, 0xc4ac5665);	/* 48 */
137729085b5SVidya Sagar Velumuri 
138729085b5SVidya Sagar Velumuri 	/* Round 4 */
139729085b5SVidya Sagar Velumuri 	II(a, b, c, d, x[0], S41, 0xf4292244);	/* 49 */
140729085b5SVidya Sagar Velumuri 	II(d, a, b, c, x[7], S42, 0x432aff97);	/* 50 */
141729085b5SVidya Sagar Velumuri 	II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
142729085b5SVidya Sagar Velumuri 	II(b, c, d, a, x[5], S44, 0xfc93a039);	/* 52 */
143729085b5SVidya Sagar Velumuri 	II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
144729085b5SVidya Sagar Velumuri 	II(d, a, b, c, x[3], S42, 0x8f0ccc92);	/* 54 */
145729085b5SVidya Sagar Velumuri 	II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
146729085b5SVidya Sagar Velumuri 	II(b, c, d, a, x[1], S44, 0x85845dd1);	/* 56 */
147729085b5SVidya Sagar Velumuri 	II(a, b, c, d, x[8], S41, 0x6fa87e4f);	/* 57 */
148729085b5SVidya Sagar Velumuri 	II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
149729085b5SVidya Sagar Velumuri 	II(c, d, a, b, x[6], S43, 0xa3014314);	/* 59 */
150729085b5SVidya Sagar Velumuri 	II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
151729085b5SVidya Sagar Velumuri 	II(a, b, c, d, x[4], S41, 0xf7537e82);	/* 61 */
152729085b5SVidya Sagar Velumuri 	II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
153729085b5SVidya Sagar Velumuri 	II(c, d, a, b, x[2], S43, 0x2ad7d2bb);	/* 63 */
154729085b5SVidya Sagar Velumuri 	II(b, c, d, a, x[9], S44, 0xeb86d391);	/* 64 */
155729085b5SVidya Sagar Velumuri 
156729085b5SVidya Sagar Velumuri 	state[0] += a;
157729085b5SVidya Sagar Velumuri 	state[1] += b;
158729085b5SVidya Sagar Velumuri 	state[2] += c;
159729085b5SVidya Sagar Velumuri 	state[3] += d;
160729085b5SVidya Sagar Velumuri 
161729085b5SVidya Sagar Velumuri 	hash[0] = state[0];
162729085b5SVidya Sagar Velumuri 	hash[1] = state[1];
163729085b5SVidya Sagar Velumuri 	hash[2] = state[2];
164729085b5SVidya Sagar Velumuri 	hash[3] = state[3];
165729085b5SVidya Sagar Velumuri }
166729085b5SVidya Sagar Velumuri 
167d85f9749STejasree Kondoj /*
168d85f9749STejasree Kondoj  * Compute a partial hash with the assumption that msg is the first block.
169d85f9749STejasree Kondoj  * Based on implementation from RFC 3174
170d85f9749STejasree Kondoj  */
171d85f9749STejasree Kondoj void
roc_hash_sha1_gen(uint8_t * msg,uint32_t * hash)172d85f9749STejasree Kondoj roc_hash_sha1_gen(uint8_t *msg, uint32_t *hash)
173d85f9749STejasree Kondoj {
174d85f9749STejasree Kondoj 	const uint32_t _K[] = {/* Round Constants defined in SHA-1   */
175d85f9749STejasree Kondoj 			       0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
176d85f9749STejasree Kondoj 
177d85f9749STejasree Kondoj 	const uint32_t _H[] = {/* Initial Hash constants defined in SHA-1 */
178d85f9749STejasree Kondoj 			       0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
179d85f9749STejasree Kondoj 			       0xC3D2E1F0};
180d85f9749STejasree Kondoj 	int i;
181af5c9909STejasree Kondoj 	uint32_t temp = 0;	/* Temporary word value */
182d85f9749STejasree Kondoj 	uint32_t W[80];		/* Word sequence */
183d85f9749STejasree Kondoj 	uint32_t A, B, C, D, E; /* Word buffers */
184d85f9749STejasree Kondoj 
185d85f9749STejasree Kondoj 	/* Initialize the first 16 words in the array W */
186d85f9749STejasree Kondoj 	memcpy(&W[0], msg, 16 * sizeof(W[0]));
187d85f9749STejasree Kondoj 
188d85f9749STejasree Kondoj 	for (i = 0; i < 16; i++)
189d85f9749STejasree Kondoj 		W[i] = htobe32(W[i]);
190d85f9749STejasree Kondoj 
191d85f9749STejasree Kondoj 	for (i = 16; i < 80; i++)
192d85f9749STejasree Kondoj 		W[i] = lrot32(1, W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]);
193d85f9749STejasree Kondoj 
194d85f9749STejasree Kondoj 	A = _H[0];
195d85f9749STejasree Kondoj 	B = _H[1];
196d85f9749STejasree Kondoj 	C = _H[2];
197d85f9749STejasree Kondoj 	D = _H[3];
198d85f9749STejasree Kondoj 	E = _H[4];
199d85f9749STejasree Kondoj 
200d85f9749STejasree Kondoj 	for (i = 0; i < 80; i++) {
201d85f9749STejasree Kondoj 		if (i >= 0 && i <= 19)
202d85f9749STejasree Kondoj 			temp = ((B & C) | ((~B) & D)) + _K[0];
203d85f9749STejasree Kondoj 		else if (i >= 20 && i <= 39)
204d85f9749STejasree Kondoj 			temp = (B ^ C ^ D) + _K[1];
205d85f9749STejasree Kondoj 		else if (i >= 40 && i <= 59)
206d85f9749STejasree Kondoj 			temp = ((B & C) | (B & D) | (C & D)) + _K[2];
207d85f9749STejasree Kondoj 		else if (i >= 60 && i <= 79)
208d85f9749STejasree Kondoj 			temp = (B ^ C ^ D) + _K[3];
209d85f9749STejasree Kondoj 
210d85f9749STejasree Kondoj 		temp = lrot32(5, A) + temp + E + W[i];
211d85f9749STejasree Kondoj 		E = D;
212d85f9749STejasree Kondoj 		D = C;
213d85f9749STejasree Kondoj 		C = lrot32(30, B);
214d85f9749STejasree Kondoj 		B = A;
215d85f9749STejasree Kondoj 		A = temp;
216d85f9749STejasree Kondoj 	}
217d85f9749STejasree Kondoj 
218d85f9749STejasree Kondoj 	A += _H[0];
219d85f9749STejasree Kondoj 	B += _H[1];
220d85f9749STejasree Kondoj 	C += _H[2];
221d85f9749STejasree Kondoj 	D += _H[3];
222d85f9749STejasree Kondoj 	E += _H[4];
223d85f9749STejasree Kondoj 	hash[0] = htobe32(A);
224d85f9749STejasree Kondoj 	hash[1] = htobe32(B);
225d85f9749STejasree Kondoj 	hash[2] = htobe32(C);
226d85f9749STejasree Kondoj 	hash[3] = htobe32(D);
227d85f9749STejasree Kondoj 	hash[4] = htobe32(E);
228d85f9749STejasree Kondoj }
229d85f9749STejasree Kondoj 
230d85f9749STejasree Kondoj /*
231d85f9749STejasree Kondoj  * Compute a partial hash with the assumption that msg is the first block.
232d85f9749STejasree Kondoj  * Based on implementation from RFC 3174
233d85f9749STejasree Kondoj  */
234d85f9749STejasree Kondoj void
roc_hash_sha256_gen(uint8_t * msg,uint32_t * hash,int hash_size)235*470071c8SAakash Sasidharan roc_hash_sha256_gen(uint8_t *msg, uint32_t *hash, int hash_size)
236d85f9749STejasree Kondoj {
237d85f9749STejasree Kondoj 	const uint32_t _K[] = {
238d85f9749STejasree Kondoj 		/* Round Constants defined in SHA-256   */
239d85f9749STejasree Kondoj 		0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
240d85f9749STejasree Kondoj 		0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
241d85f9749STejasree Kondoj 		0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
242d85f9749STejasree Kondoj 		0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
243d85f9749STejasree Kondoj 		0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
244d85f9749STejasree Kondoj 		0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
245d85f9749STejasree Kondoj 		0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
246d85f9749STejasree Kondoj 		0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
247d85f9749STejasree Kondoj 		0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
248d85f9749STejasree Kondoj 		0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
249d85f9749STejasree Kondoj 		0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
250d85f9749STejasree Kondoj 		0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
251d85f9749STejasree Kondoj 		0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
252d85f9749STejasree Kondoj 
253*470071c8SAakash Sasidharan 	const uint32_t _H224[] = {/* Initial Hash constants defined in SHA-224 */
254*470071c8SAakash Sasidharan 				  0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
255*470071c8SAakash Sasidharan 				  0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
256*470071c8SAakash Sasidharan 	const uint32_t _H256[] = {/* Initial Hash constants defined in SHA-256 */
257d85f9749STejasree Kondoj 				  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
258d85f9749STejasree Kondoj 				  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
259d85f9749STejasree Kondoj 	int i;
260d85f9749STejasree Kondoj 	uint32_t temp[4], S0, S1;	 /* Temporary word value */
261d85f9749STejasree Kondoj 	uint32_t W[64];			 /* Word sequence */
262d85f9749STejasree Kondoj 	uint32_t A, B, C, D, E, F, G, H; /* Word buffers */
263*470071c8SAakash Sasidharan 	const uint32_t *_H = (hash_size == 224) ? _H224 : _H256;
264d85f9749STejasree Kondoj 
265d85f9749STejasree Kondoj 	/* Initialize the first 16 words in the array W */
266d85f9749STejasree Kondoj 	memcpy(&W[0], msg, 16 * sizeof(W[0]));
267d85f9749STejasree Kondoj 
268d85f9749STejasree Kondoj 	for (i = 0; i < 16; i++)
269d85f9749STejasree Kondoj 		W[i] = htobe32(W[i]);
270d85f9749STejasree Kondoj 
271d85f9749STejasree Kondoj 	for (i = 16; i < 64; i++) {
272d85f9749STejasree Kondoj 		S0 = rrot32(7, W[i - 15]) ^ rrot32(18, W[i - 15]) ^
273d85f9749STejasree Kondoj 		     (W[i - 15] >> 3);
274d85f9749STejasree Kondoj 		S1 = rrot32(17, W[i - 2]) ^ rrot32(19, W[i - 2]) ^
275d85f9749STejasree Kondoj 		     (W[i - 2] >> 10);
276d85f9749STejasree Kondoj 		W[i] = W[i - 16] + S0 + W[i - 7] + S1;
277d85f9749STejasree Kondoj 	}
278d85f9749STejasree Kondoj 
279d85f9749STejasree Kondoj 	A = _H[0];
280d85f9749STejasree Kondoj 	B = _H[1];
281d85f9749STejasree Kondoj 	C = _H[2];
282d85f9749STejasree Kondoj 	D = _H[3];
283d85f9749STejasree Kondoj 	E = _H[4];
284d85f9749STejasree Kondoj 	F = _H[5];
285d85f9749STejasree Kondoj 	G = _H[6];
286d85f9749STejasree Kondoj 	H = _H[7];
287d85f9749STejasree Kondoj 
288d85f9749STejasree Kondoj 	for (i = 0; i < 64; i++) {
289d85f9749STejasree Kondoj 		S1 = rrot32(6, E) ^ rrot32(11, E) ^ rrot32(25, E);
290d85f9749STejasree Kondoj 		temp[0] = (E & F) ^ ((~E) & G);
291d85f9749STejasree Kondoj 		temp[1] = H + S1 + temp[0] + _K[i] + W[i];
292d85f9749STejasree Kondoj 		S0 = rrot32(2, A) ^ rrot32(13, A) ^ rrot32(22, A);
293d85f9749STejasree Kondoj 		temp[2] = (A & B) ^ (A & C) ^ (B & C);
294d85f9749STejasree Kondoj 		temp[3] = S0 + temp[2];
295d85f9749STejasree Kondoj 
296d85f9749STejasree Kondoj 		H = G;
297d85f9749STejasree Kondoj 		G = F;
298d85f9749STejasree Kondoj 		F = E;
299d85f9749STejasree Kondoj 		E = D + temp[1];
300d85f9749STejasree Kondoj 		D = C;
301d85f9749STejasree Kondoj 		C = B;
302d85f9749STejasree Kondoj 		B = A;
303d85f9749STejasree Kondoj 		A = temp[1] + temp[3];
304d85f9749STejasree Kondoj 	}
305d85f9749STejasree Kondoj 
306d85f9749STejasree Kondoj 	A += _H[0];
307d85f9749STejasree Kondoj 	B += _H[1];
308d85f9749STejasree Kondoj 	C += _H[2];
309d85f9749STejasree Kondoj 	D += _H[3];
310d85f9749STejasree Kondoj 	E += _H[4];
311d85f9749STejasree Kondoj 	F += _H[5];
312d85f9749STejasree Kondoj 	G += _H[6];
313d85f9749STejasree Kondoj 	H += _H[7];
314d85f9749STejasree Kondoj 	hash[0] = htobe32(A);
315d85f9749STejasree Kondoj 	hash[1] = htobe32(B);
316d85f9749STejasree Kondoj 	hash[2] = htobe32(C);
317d85f9749STejasree Kondoj 	hash[3] = htobe32(D);
318d85f9749STejasree Kondoj 	hash[4] = htobe32(E);
319d85f9749STejasree Kondoj 	hash[5] = htobe32(F);
320d85f9749STejasree Kondoj 	hash[6] = htobe32(G);
321d85f9749STejasree Kondoj 	hash[7] = htobe32(H);
322d85f9749STejasree Kondoj }
323d85f9749STejasree Kondoj 
324d85f9749STejasree Kondoj /*
325d85f9749STejasree Kondoj  * Compute a partial hash with the assumption that msg is the first block.
326d85f9749STejasree Kondoj  * Based on implementation from RFC 3174
327d85f9749STejasree Kondoj  */
328d85f9749STejasree Kondoj void
roc_hash_sha512_gen(uint8_t * msg,uint64_t * hash,int hash_size)329d85f9749STejasree Kondoj roc_hash_sha512_gen(uint8_t *msg, uint64_t *hash, int hash_size)
330d85f9749STejasree Kondoj {
331d85f9749STejasree Kondoj 	const uint64_t _K[] = {
332d85f9749STejasree Kondoj 		/* Round Constants defined in SHA-512   */
333d85f9749STejasree Kondoj 		0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
334d85f9749STejasree Kondoj 		0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
335d85f9749STejasree Kondoj 		0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
336d85f9749STejasree Kondoj 		0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
337d85f9749STejasree Kondoj 		0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
338d85f9749STejasree Kondoj 		0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
339d85f9749STejasree Kondoj 		0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
340d85f9749STejasree Kondoj 		0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
341d85f9749STejasree Kondoj 		0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
342d85f9749STejasree Kondoj 		0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
343d85f9749STejasree Kondoj 		0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
344d85f9749STejasree Kondoj 		0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
345d85f9749STejasree Kondoj 		0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
346d85f9749STejasree Kondoj 		0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
347d85f9749STejasree Kondoj 		0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
348d85f9749STejasree Kondoj 		0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
349d85f9749STejasree Kondoj 		0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
350d85f9749STejasree Kondoj 		0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
351d85f9749STejasree Kondoj 		0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
352d85f9749STejasree Kondoj 		0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
353d85f9749STejasree Kondoj 		0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
354d85f9749STejasree Kondoj 		0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
355d85f9749STejasree Kondoj 		0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
356d85f9749STejasree Kondoj 		0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
357d85f9749STejasree Kondoj 		0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
358d85f9749STejasree Kondoj 		0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
359d85f9749STejasree Kondoj 		0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
360d85f9749STejasree Kondoj 
361d85f9749STejasree Kondoj 	const uint64_t _H384[] = {/* Initial Hash constants defined in SHA384 */
362d85f9749STejasree Kondoj 				  0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
363d85f9749STejasree Kondoj 				  0x9159015a3070dd17, 0x152fecd8f70e5939,
364d85f9749STejasree Kondoj 				  0x67332667ffc00b31, 0x8eb44a8768581511,
365d85f9749STejasree Kondoj 				  0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4};
366d85f9749STejasree Kondoj 	const uint64_t _H512[] = {/* Initial Hash constants defined in SHA512 */
367d85f9749STejasree Kondoj 				  0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
368d85f9749STejasree Kondoj 				  0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
369d85f9749STejasree Kondoj 				  0x510e527fade682d1, 0x9b05688c2b3e6c1f,
370d85f9749STejasree Kondoj 				  0x1f83d9abfb41bd6b, 0x5be0cd19137e2179};
371d85f9749STejasree Kondoj 	int i;
372d85f9749STejasree Kondoj 	uint64_t temp[4], S0, S1;	 /* Temporary word value */
373d85f9749STejasree Kondoj 	uint64_t W[80];			 /* Word sequence */
374d85f9749STejasree Kondoj 	uint64_t A, B, C, D, E, F, G, H; /* Word buffers */
375d85f9749STejasree Kondoj 	const uint64_t *_H = (hash_size == 384) ? _H384 : _H512;
376d85f9749STejasree Kondoj 
377d85f9749STejasree Kondoj 	/* Initialize the first 16 words in the array W */
378d85f9749STejasree Kondoj 	memcpy(&W[0], msg, 16 * sizeof(W[0]));
379d85f9749STejasree Kondoj 
380d85f9749STejasree Kondoj 	for (i = 0; i < 16; i++)
381d85f9749STejasree Kondoj 		W[i] = htobe64(W[i]);
382d85f9749STejasree Kondoj 
383d85f9749STejasree Kondoj 	for (i = 16; i < 80; i++) {
384d85f9749STejasree Kondoj 		S0 = rrot64(1, W[i - 15]) ^ rrot64(8, W[i - 15]) ^
385d85f9749STejasree Kondoj 		     (W[i - 15] >> 7);
386d85f9749STejasree Kondoj 		S1 = rrot64(19, W[i - 2]) ^ rrot64(61, W[i - 2]) ^
387d85f9749STejasree Kondoj 		     (W[i - 2] >> 6);
388d85f9749STejasree Kondoj 		W[i] = W[i - 16] + S0 + W[i - 7] + S1;
389d85f9749STejasree Kondoj 	}
390d85f9749STejasree Kondoj 
391d85f9749STejasree Kondoj 	A = _H[0];
392d85f9749STejasree Kondoj 	B = _H[1];
393d85f9749STejasree Kondoj 	C = _H[2];
394d85f9749STejasree Kondoj 	D = _H[3];
395d85f9749STejasree Kondoj 	E = _H[4];
396d85f9749STejasree Kondoj 	F = _H[5];
397d85f9749STejasree Kondoj 	G = _H[6];
398d85f9749STejasree Kondoj 	H = _H[7];
399d85f9749STejasree Kondoj 
400d85f9749STejasree Kondoj 	for (i = 0; i < 80; i++) {
401d85f9749STejasree Kondoj 		S1 = rrot64(14, E) ^ rrot64(18, E) ^ rrot64(41, E);
402d85f9749STejasree Kondoj 		temp[0] = (E & F) ^ ((~E) & G);
403d85f9749STejasree Kondoj 		temp[1] = H + S1 + temp[0] + _K[i] + W[i];
404d85f9749STejasree Kondoj 		S0 = rrot64(28, A) ^ rrot64(34, A) ^ rrot64(39, A);
405d85f9749STejasree Kondoj 		temp[2] = (A & B) ^ (A & C) ^ (B & C);
406d85f9749STejasree Kondoj 		temp[3] = S0 + temp[2];
407d85f9749STejasree Kondoj 
408d85f9749STejasree Kondoj 		H = G;
409d85f9749STejasree Kondoj 		G = F;
410d85f9749STejasree Kondoj 		F = E;
411d85f9749STejasree Kondoj 		E = D + temp[1];
412d85f9749STejasree Kondoj 		D = C;
413d85f9749STejasree Kondoj 		C = B;
414d85f9749STejasree Kondoj 		B = A;
415d85f9749STejasree Kondoj 		A = temp[1] + temp[3];
416d85f9749STejasree Kondoj 	}
417d85f9749STejasree Kondoj 
418d85f9749STejasree Kondoj 	A += _H[0];
419d85f9749STejasree Kondoj 	B += _H[1];
420d85f9749STejasree Kondoj 	C += _H[2];
421d85f9749STejasree Kondoj 	D += _H[3];
422d85f9749STejasree Kondoj 	E += _H[4];
423d85f9749STejasree Kondoj 	F += _H[5];
424d85f9749STejasree Kondoj 	G += _H[6];
425d85f9749STejasree Kondoj 	H += _H[7];
426d85f9749STejasree Kondoj 	hash[0] = htobe64(A);
427d85f9749STejasree Kondoj 	hash[1] = htobe64(B);
428d85f9749STejasree Kondoj 	hash[2] = htobe64(C);
429d85f9749STejasree Kondoj 	hash[3] = htobe64(D);
430d85f9749STejasree Kondoj 	hash[4] = htobe64(E);
431d85f9749STejasree Kondoj 	hash[5] = htobe64(F);
432d85f9749STejasree Kondoj 	hash[6] = htobe64(G);
433d85f9749STejasree Kondoj 	hash[7] = htobe64(H);
434d85f9749STejasree Kondoj }
435