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