1*897a1d94STom Rini // SPDX-License-Identifier: BSD-3-Clause
2d8f9d2afSIgor Opaniuk /*
3d8f9d2afSIgor Opaniuk * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
4d8f9d2afSIgor Opaniuk * All rights reserved.
5d8f9d2afSIgor Opaniuk *
6d8f9d2afSIgor Opaniuk * FIPS 180-2 SHA-224/256/384/512 implementation
7d8f9d2afSIgor Opaniuk * Last update: 02/02/2007
8d8f9d2afSIgor Opaniuk * Issue date: 04/30/2005
9d8f9d2afSIgor Opaniuk */
10d8f9d2afSIgor Opaniuk
11d8f9d2afSIgor Opaniuk #include "avb_sha.h"
12d8f9d2afSIgor Opaniuk
13d8f9d2afSIgor Opaniuk #define SHFR(x, n) (x >> n)
14d8f9d2afSIgor Opaniuk #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
15d8f9d2afSIgor Opaniuk #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
16d8f9d2afSIgor Opaniuk #define CH(x, y, z) ((x & y) ^ (~x & z))
17d8f9d2afSIgor Opaniuk #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
18d8f9d2afSIgor Opaniuk
19d8f9d2afSIgor Opaniuk #define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
20d8f9d2afSIgor Opaniuk #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
21d8f9d2afSIgor Opaniuk #define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7))
22d8f9d2afSIgor Opaniuk #define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6))
23d8f9d2afSIgor Opaniuk
24d8f9d2afSIgor Opaniuk #define UNPACK32(x, str) \
25d8f9d2afSIgor Opaniuk { \
26d8f9d2afSIgor Opaniuk *((str) + 3) = (uint8_t)((x)); \
27d8f9d2afSIgor Opaniuk *((str) + 2) = (uint8_t)((x) >> 8); \
28d8f9d2afSIgor Opaniuk *((str) + 1) = (uint8_t)((x) >> 16); \
29d8f9d2afSIgor Opaniuk *((str) + 0) = (uint8_t)((x) >> 24); \
30d8f9d2afSIgor Opaniuk }
31d8f9d2afSIgor Opaniuk
32d8f9d2afSIgor Opaniuk #define UNPACK64(x, str) \
33d8f9d2afSIgor Opaniuk { \
34d8f9d2afSIgor Opaniuk *((str) + 7) = (uint8_t)x; \
35d8f9d2afSIgor Opaniuk *((str) + 6) = (uint8_t)((uint64_t)x >> 8); \
36d8f9d2afSIgor Opaniuk *((str) + 5) = (uint8_t)((uint64_t)x >> 16); \
37d8f9d2afSIgor Opaniuk *((str) + 4) = (uint8_t)((uint64_t)x >> 24); \
38d8f9d2afSIgor Opaniuk *((str) + 3) = (uint8_t)((uint64_t)x >> 32); \
39d8f9d2afSIgor Opaniuk *((str) + 2) = (uint8_t)((uint64_t)x >> 40); \
40d8f9d2afSIgor Opaniuk *((str) + 1) = (uint8_t)((uint64_t)x >> 48); \
41d8f9d2afSIgor Opaniuk *((str) + 0) = (uint8_t)((uint64_t)x >> 56); \
42d8f9d2afSIgor Opaniuk }
43d8f9d2afSIgor Opaniuk
44d8f9d2afSIgor Opaniuk #define PACK64(str, x) \
45d8f9d2afSIgor Opaniuk { \
46d8f9d2afSIgor Opaniuk *(x) = \
47d8f9d2afSIgor Opaniuk ((uint64_t) * ((str) + 7)) | ((uint64_t) * ((str) + 6) << 8) | \
48d8f9d2afSIgor Opaniuk ((uint64_t) * ((str) + 5) << 16) | ((uint64_t) * ((str) + 4) << 24) | \
49d8f9d2afSIgor Opaniuk ((uint64_t) * ((str) + 3) << 32) | ((uint64_t) * ((str) + 2) << 40) | \
50d8f9d2afSIgor Opaniuk ((uint64_t) * ((str) + 1) << 48) | ((uint64_t) * ((str) + 0) << 56); \
51d8f9d2afSIgor Opaniuk }
52d8f9d2afSIgor Opaniuk
53d8f9d2afSIgor Opaniuk /* Macros used for loops unrolling */
54d8f9d2afSIgor Opaniuk
55d8f9d2afSIgor Opaniuk #define SHA512_SCR(i) \
56d8f9d2afSIgor Opaniuk { w[i] = SHA512_F4(w[i - 2]) + w[i - 7] + SHA512_F3(w[i - 15]) + w[i - 16]; }
57d8f9d2afSIgor Opaniuk
58d8f9d2afSIgor Opaniuk #define SHA512_EXP(a, b, c, d, e, f, g, h, j) \
59d8f9d2afSIgor Opaniuk { \
60d8f9d2afSIgor Opaniuk t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + sha512_k[j] + \
61d8f9d2afSIgor Opaniuk w[j]; \
62d8f9d2afSIgor Opaniuk t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
63d8f9d2afSIgor Opaniuk wv[d] += t1; \
64d8f9d2afSIgor Opaniuk wv[h] = t1 + t2; \
65d8f9d2afSIgor Opaniuk }
66d8f9d2afSIgor Opaniuk
67d8f9d2afSIgor Opaniuk static const uint64_t sha512_h0[8] = {0x6a09e667f3bcc908ULL,
68d8f9d2afSIgor Opaniuk 0xbb67ae8584caa73bULL,
69d8f9d2afSIgor Opaniuk 0x3c6ef372fe94f82bULL,
70d8f9d2afSIgor Opaniuk 0xa54ff53a5f1d36f1ULL,
71d8f9d2afSIgor Opaniuk 0x510e527fade682d1ULL,
72d8f9d2afSIgor Opaniuk 0x9b05688c2b3e6c1fULL,
73d8f9d2afSIgor Opaniuk 0x1f83d9abfb41bd6bULL,
74d8f9d2afSIgor Opaniuk 0x5be0cd19137e2179ULL};
75d8f9d2afSIgor Opaniuk
76d8f9d2afSIgor Opaniuk static const uint64_t sha512_k[80] = {
77d8f9d2afSIgor Opaniuk 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
78d8f9d2afSIgor Opaniuk 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
79d8f9d2afSIgor Opaniuk 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
80d8f9d2afSIgor Opaniuk 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
81d8f9d2afSIgor Opaniuk 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
82d8f9d2afSIgor Opaniuk 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
83d8f9d2afSIgor Opaniuk 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
84d8f9d2afSIgor Opaniuk 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
85d8f9d2afSIgor Opaniuk 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
86d8f9d2afSIgor Opaniuk 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
87d8f9d2afSIgor Opaniuk 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
88d8f9d2afSIgor Opaniuk 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
89d8f9d2afSIgor Opaniuk 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
90d8f9d2afSIgor Opaniuk 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
91d8f9d2afSIgor Opaniuk 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
92d8f9d2afSIgor Opaniuk 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
93d8f9d2afSIgor Opaniuk 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
94d8f9d2afSIgor Opaniuk 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
95d8f9d2afSIgor Opaniuk 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
96d8f9d2afSIgor Opaniuk 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
97d8f9d2afSIgor Opaniuk 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
98d8f9d2afSIgor Opaniuk 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
99d8f9d2afSIgor Opaniuk 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
100d8f9d2afSIgor Opaniuk 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
101d8f9d2afSIgor Opaniuk 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
102d8f9d2afSIgor Opaniuk 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
103d8f9d2afSIgor Opaniuk 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
104d8f9d2afSIgor Opaniuk
105d8f9d2afSIgor Opaniuk /* SHA-512 implementation */
106d8f9d2afSIgor Opaniuk
avb_sha512_init(AvbSHA512Ctx * ctx)107d8f9d2afSIgor Opaniuk void avb_sha512_init(AvbSHA512Ctx* ctx) {
108d8f9d2afSIgor Opaniuk #ifdef UNROLL_LOOPS_SHA512
109d8f9d2afSIgor Opaniuk ctx->h[0] = sha512_h0[0];
110d8f9d2afSIgor Opaniuk ctx->h[1] = sha512_h0[1];
111d8f9d2afSIgor Opaniuk ctx->h[2] = sha512_h0[2];
112d8f9d2afSIgor Opaniuk ctx->h[3] = sha512_h0[3];
113d8f9d2afSIgor Opaniuk ctx->h[4] = sha512_h0[4];
114d8f9d2afSIgor Opaniuk ctx->h[5] = sha512_h0[5];
115d8f9d2afSIgor Opaniuk ctx->h[6] = sha512_h0[6];
116d8f9d2afSIgor Opaniuk ctx->h[7] = sha512_h0[7];
117d8f9d2afSIgor Opaniuk #else
118d8f9d2afSIgor Opaniuk int i;
119d8f9d2afSIgor Opaniuk
120d8f9d2afSIgor Opaniuk for (i = 0; i < 8; i++)
121d8f9d2afSIgor Opaniuk ctx->h[i] = sha512_h0[i];
122d8f9d2afSIgor Opaniuk #endif /* UNROLL_LOOPS_SHA512 */
123d8f9d2afSIgor Opaniuk
124d8f9d2afSIgor Opaniuk ctx->len = 0;
125d8f9d2afSIgor Opaniuk ctx->tot_len = 0;
126d8f9d2afSIgor Opaniuk }
127d8f9d2afSIgor Opaniuk
SHA512_transform(AvbSHA512Ctx * ctx,const uint8_t * message,unsigned int block_nb)128d8f9d2afSIgor Opaniuk static void SHA512_transform(AvbSHA512Ctx* ctx,
129d8f9d2afSIgor Opaniuk const uint8_t* message,
130d8f9d2afSIgor Opaniuk unsigned int block_nb) {
131d8f9d2afSIgor Opaniuk uint64_t w[80];
132d8f9d2afSIgor Opaniuk uint64_t wv[8];
133d8f9d2afSIgor Opaniuk uint64_t t1, t2;
134d8f9d2afSIgor Opaniuk const uint8_t* sub_block;
135d8f9d2afSIgor Opaniuk int i, j;
136d8f9d2afSIgor Opaniuk
137d8f9d2afSIgor Opaniuk for (i = 0; i < (int)block_nb; i++) {
138d8f9d2afSIgor Opaniuk sub_block = message + (i << 7);
139d8f9d2afSIgor Opaniuk
140d8f9d2afSIgor Opaniuk #ifdef UNROLL_LOOPS_SHA512
141d8f9d2afSIgor Opaniuk PACK64(&sub_block[0], &w[0]);
142d8f9d2afSIgor Opaniuk PACK64(&sub_block[8], &w[1]);
143d8f9d2afSIgor Opaniuk PACK64(&sub_block[16], &w[2]);
144d8f9d2afSIgor Opaniuk PACK64(&sub_block[24], &w[3]);
145d8f9d2afSIgor Opaniuk PACK64(&sub_block[32], &w[4]);
146d8f9d2afSIgor Opaniuk PACK64(&sub_block[40], &w[5]);
147d8f9d2afSIgor Opaniuk PACK64(&sub_block[48], &w[6]);
148d8f9d2afSIgor Opaniuk PACK64(&sub_block[56], &w[7]);
149d8f9d2afSIgor Opaniuk PACK64(&sub_block[64], &w[8]);
150d8f9d2afSIgor Opaniuk PACK64(&sub_block[72], &w[9]);
151d8f9d2afSIgor Opaniuk PACK64(&sub_block[80], &w[10]);
152d8f9d2afSIgor Opaniuk PACK64(&sub_block[88], &w[11]);
153d8f9d2afSIgor Opaniuk PACK64(&sub_block[96], &w[12]);
154d8f9d2afSIgor Opaniuk PACK64(&sub_block[104], &w[13]);
155d8f9d2afSIgor Opaniuk PACK64(&sub_block[112], &w[14]);
156d8f9d2afSIgor Opaniuk PACK64(&sub_block[120], &w[15]);
157d8f9d2afSIgor Opaniuk
158d8f9d2afSIgor Opaniuk SHA512_SCR(16);
159d8f9d2afSIgor Opaniuk SHA512_SCR(17);
160d8f9d2afSIgor Opaniuk SHA512_SCR(18);
161d8f9d2afSIgor Opaniuk SHA512_SCR(19);
162d8f9d2afSIgor Opaniuk SHA512_SCR(20);
163d8f9d2afSIgor Opaniuk SHA512_SCR(21);
164d8f9d2afSIgor Opaniuk SHA512_SCR(22);
165d8f9d2afSIgor Opaniuk SHA512_SCR(23);
166d8f9d2afSIgor Opaniuk SHA512_SCR(24);
167d8f9d2afSIgor Opaniuk SHA512_SCR(25);
168d8f9d2afSIgor Opaniuk SHA512_SCR(26);
169d8f9d2afSIgor Opaniuk SHA512_SCR(27);
170d8f9d2afSIgor Opaniuk SHA512_SCR(28);
171d8f9d2afSIgor Opaniuk SHA512_SCR(29);
172d8f9d2afSIgor Opaniuk SHA512_SCR(30);
173d8f9d2afSIgor Opaniuk SHA512_SCR(31);
174d8f9d2afSIgor Opaniuk SHA512_SCR(32);
175d8f9d2afSIgor Opaniuk SHA512_SCR(33);
176d8f9d2afSIgor Opaniuk SHA512_SCR(34);
177d8f9d2afSIgor Opaniuk SHA512_SCR(35);
178d8f9d2afSIgor Opaniuk SHA512_SCR(36);
179d8f9d2afSIgor Opaniuk SHA512_SCR(37);
180d8f9d2afSIgor Opaniuk SHA512_SCR(38);
181d8f9d2afSIgor Opaniuk SHA512_SCR(39);
182d8f9d2afSIgor Opaniuk SHA512_SCR(40);
183d8f9d2afSIgor Opaniuk SHA512_SCR(41);
184d8f9d2afSIgor Opaniuk SHA512_SCR(42);
185d8f9d2afSIgor Opaniuk SHA512_SCR(43);
186d8f9d2afSIgor Opaniuk SHA512_SCR(44);
187d8f9d2afSIgor Opaniuk SHA512_SCR(45);
188d8f9d2afSIgor Opaniuk SHA512_SCR(46);
189d8f9d2afSIgor Opaniuk SHA512_SCR(47);
190d8f9d2afSIgor Opaniuk SHA512_SCR(48);
191d8f9d2afSIgor Opaniuk SHA512_SCR(49);
192d8f9d2afSIgor Opaniuk SHA512_SCR(50);
193d8f9d2afSIgor Opaniuk SHA512_SCR(51);
194d8f9d2afSIgor Opaniuk SHA512_SCR(52);
195d8f9d2afSIgor Opaniuk SHA512_SCR(53);
196d8f9d2afSIgor Opaniuk SHA512_SCR(54);
197d8f9d2afSIgor Opaniuk SHA512_SCR(55);
198d8f9d2afSIgor Opaniuk SHA512_SCR(56);
199d8f9d2afSIgor Opaniuk SHA512_SCR(57);
200d8f9d2afSIgor Opaniuk SHA512_SCR(58);
201d8f9d2afSIgor Opaniuk SHA512_SCR(59);
202d8f9d2afSIgor Opaniuk SHA512_SCR(60);
203d8f9d2afSIgor Opaniuk SHA512_SCR(61);
204d8f9d2afSIgor Opaniuk SHA512_SCR(62);
205d8f9d2afSIgor Opaniuk SHA512_SCR(63);
206d8f9d2afSIgor Opaniuk SHA512_SCR(64);
207d8f9d2afSIgor Opaniuk SHA512_SCR(65);
208d8f9d2afSIgor Opaniuk SHA512_SCR(66);
209d8f9d2afSIgor Opaniuk SHA512_SCR(67);
210d8f9d2afSIgor Opaniuk SHA512_SCR(68);
211d8f9d2afSIgor Opaniuk SHA512_SCR(69);
212d8f9d2afSIgor Opaniuk SHA512_SCR(70);
213d8f9d2afSIgor Opaniuk SHA512_SCR(71);
214d8f9d2afSIgor Opaniuk SHA512_SCR(72);
215d8f9d2afSIgor Opaniuk SHA512_SCR(73);
216d8f9d2afSIgor Opaniuk SHA512_SCR(74);
217d8f9d2afSIgor Opaniuk SHA512_SCR(75);
218d8f9d2afSIgor Opaniuk SHA512_SCR(76);
219d8f9d2afSIgor Opaniuk SHA512_SCR(77);
220d8f9d2afSIgor Opaniuk SHA512_SCR(78);
221d8f9d2afSIgor Opaniuk SHA512_SCR(79);
222d8f9d2afSIgor Opaniuk
223d8f9d2afSIgor Opaniuk wv[0] = ctx->h[0];
224d8f9d2afSIgor Opaniuk wv[1] = ctx->h[1];
225d8f9d2afSIgor Opaniuk wv[2] = ctx->h[2];
226d8f9d2afSIgor Opaniuk wv[3] = ctx->h[3];
227d8f9d2afSIgor Opaniuk wv[4] = ctx->h[4];
228d8f9d2afSIgor Opaniuk wv[5] = ctx->h[5];
229d8f9d2afSIgor Opaniuk wv[6] = ctx->h[6];
230d8f9d2afSIgor Opaniuk wv[7] = ctx->h[7];
231d8f9d2afSIgor Opaniuk
232d8f9d2afSIgor Opaniuk j = 0;
233d8f9d2afSIgor Opaniuk
234d8f9d2afSIgor Opaniuk do {
235d8f9d2afSIgor Opaniuk SHA512_EXP(0, 1, 2, 3, 4, 5, 6, 7, j);
236d8f9d2afSIgor Opaniuk j++;
237d8f9d2afSIgor Opaniuk SHA512_EXP(7, 0, 1, 2, 3, 4, 5, 6, j);
238d8f9d2afSIgor Opaniuk j++;
239d8f9d2afSIgor Opaniuk SHA512_EXP(6, 7, 0, 1, 2, 3, 4, 5, j);
240d8f9d2afSIgor Opaniuk j++;
241d8f9d2afSIgor Opaniuk SHA512_EXP(5, 6, 7, 0, 1, 2, 3, 4, j);
242d8f9d2afSIgor Opaniuk j++;
243d8f9d2afSIgor Opaniuk SHA512_EXP(4, 5, 6, 7, 0, 1, 2, 3, j);
244d8f9d2afSIgor Opaniuk j++;
245d8f9d2afSIgor Opaniuk SHA512_EXP(3, 4, 5, 6, 7, 0, 1, 2, j);
246d8f9d2afSIgor Opaniuk j++;
247d8f9d2afSIgor Opaniuk SHA512_EXP(2, 3, 4, 5, 6, 7, 0, 1, j);
248d8f9d2afSIgor Opaniuk j++;
249d8f9d2afSIgor Opaniuk SHA512_EXP(1, 2, 3, 4, 5, 6, 7, 0, j);
250d8f9d2afSIgor Opaniuk j++;
251d8f9d2afSIgor Opaniuk } while (j < 80);
252d8f9d2afSIgor Opaniuk
253d8f9d2afSIgor Opaniuk ctx->h[0] += wv[0];
254d8f9d2afSIgor Opaniuk ctx->h[1] += wv[1];
255d8f9d2afSIgor Opaniuk ctx->h[2] += wv[2];
256d8f9d2afSIgor Opaniuk ctx->h[3] += wv[3];
257d8f9d2afSIgor Opaniuk ctx->h[4] += wv[4];
258d8f9d2afSIgor Opaniuk ctx->h[5] += wv[5];
259d8f9d2afSIgor Opaniuk ctx->h[6] += wv[6];
260d8f9d2afSIgor Opaniuk ctx->h[7] += wv[7];
261d8f9d2afSIgor Opaniuk #else
262d8f9d2afSIgor Opaniuk for (j = 0; j < 16; j++) {
263d8f9d2afSIgor Opaniuk PACK64(&sub_block[j << 3], &w[j]);
264d8f9d2afSIgor Opaniuk }
265d8f9d2afSIgor Opaniuk
266d8f9d2afSIgor Opaniuk for (j = 16; j < 80; j++) {
267d8f9d2afSIgor Opaniuk SHA512_SCR(j);
268d8f9d2afSIgor Opaniuk }
269d8f9d2afSIgor Opaniuk
270d8f9d2afSIgor Opaniuk for (j = 0; j < 8; j++) {
271d8f9d2afSIgor Opaniuk wv[j] = ctx->h[j];
272d8f9d2afSIgor Opaniuk }
273d8f9d2afSIgor Opaniuk
274d8f9d2afSIgor Opaniuk for (j = 0; j < 80; j++) {
275d8f9d2afSIgor Opaniuk t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha512_k[j] +
276d8f9d2afSIgor Opaniuk w[j];
277d8f9d2afSIgor Opaniuk t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
278d8f9d2afSIgor Opaniuk wv[7] = wv[6];
279d8f9d2afSIgor Opaniuk wv[6] = wv[5];
280d8f9d2afSIgor Opaniuk wv[5] = wv[4];
281d8f9d2afSIgor Opaniuk wv[4] = wv[3] + t1;
282d8f9d2afSIgor Opaniuk wv[3] = wv[2];
283d8f9d2afSIgor Opaniuk wv[2] = wv[1];
284d8f9d2afSIgor Opaniuk wv[1] = wv[0];
285d8f9d2afSIgor Opaniuk wv[0] = t1 + t2;
286d8f9d2afSIgor Opaniuk }
287d8f9d2afSIgor Opaniuk
288d8f9d2afSIgor Opaniuk for (j = 0; j < 8; j++)
289d8f9d2afSIgor Opaniuk ctx->h[j] += wv[j];
290d8f9d2afSIgor Opaniuk #endif /* UNROLL_LOOPS_SHA512 */
291d8f9d2afSIgor Opaniuk }
292d8f9d2afSIgor Opaniuk }
293d8f9d2afSIgor Opaniuk
avb_sha512_update(AvbSHA512Ctx * ctx,const uint8_t * data,uint32_t len)294d8f9d2afSIgor Opaniuk void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len) {
295d8f9d2afSIgor Opaniuk unsigned int block_nb;
296d8f9d2afSIgor Opaniuk unsigned int new_len, rem_len, tmp_len;
297d8f9d2afSIgor Opaniuk const uint8_t* shifted_data;
298d8f9d2afSIgor Opaniuk
299d8f9d2afSIgor Opaniuk tmp_len = AVB_SHA512_BLOCK_SIZE - ctx->len;
300d8f9d2afSIgor Opaniuk rem_len = len < tmp_len ? len : tmp_len;
301d8f9d2afSIgor Opaniuk
302d8f9d2afSIgor Opaniuk avb_memcpy(&ctx->block[ctx->len], data, rem_len);
303d8f9d2afSIgor Opaniuk
304d8f9d2afSIgor Opaniuk if (ctx->len + len < AVB_SHA512_BLOCK_SIZE) {
305d8f9d2afSIgor Opaniuk ctx->len += len;
306d8f9d2afSIgor Opaniuk return;
307d8f9d2afSIgor Opaniuk }
308d8f9d2afSIgor Opaniuk
309d8f9d2afSIgor Opaniuk new_len = len - rem_len;
310d8f9d2afSIgor Opaniuk block_nb = new_len / AVB_SHA512_BLOCK_SIZE;
311d8f9d2afSIgor Opaniuk
312d8f9d2afSIgor Opaniuk shifted_data = data + rem_len;
313d8f9d2afSIgor Opaniuk
314d8f9d2afSIgor Opaniuk SHA512_transform(ctx, ctx->block, 1);
315d8f9d2afSIgor Opaniuk SHA512_transform(ctx, shifted_data, block_nb);
316d8f9d2afSIgor Opaniuk
317d8f9d2afSIgor Opaniuk rem_len = new_len % AVB_SHA512_BLOCK_SIZE;
318d8f9d2afSIgor Opaniuk
319d8f9d2afSIgor Opaniuk avb_memcpy(ctx->block, &shifted_data[block_nb << 7], rem_len);
320d8f9d2afSIgor Opaniuk
321d8f9d2afSIgor Opaniuk ctx->len = rem_len;
322d8f9d2afSIgor Opaniuk ctx->tot_len += (block_nb + 1) << 7;
323d8f9d2afSIgor Opaniuk }
324d8f9d2afSIgor Opaniuk
avb_sha512_final(AvbSHA512Ctx * ctx)325d8f9d2afSIgor Opaniuk uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
326d8f9d2afSIgor Opaniuk unsigned int block_nb;
327d8f9d2afSIgor Opaniuk unsigned int pm_len;
328d8f9d2afSIgor Opaniuk unsigned int len_b;
329d8f9d2afSIgor Opaniuk
330d8f9d2afSIgor Opaniuk #ifndef UNROLL_LOOPS_SHA512
331d8f9d2afSIgor Opaniuk int i;
332d8f9d2afSIgor Opaniuk #endif
333d8f9d2afSIgor Opaniuk
334d8f9d2afSIgor Opaniuk block_nb =
335d8f9d2afSIgor Opaniuk 1 + ((AVB_SHA512_BLOCK_SIZE - 17) < (ctx->len % AVB_SHA512_BLOCK_SIZE));
336d8f9d2afSIgor Opaniuk
337d8f9d2afSIgor Opaniuk len_b = (ctx->tot_len + ctx->len) << 3;
338d8f9d2afSIgor Opaniuk pm_len = block_nb << 7;
339d8f9d2afSIgor Opaniuk
340d8f9d2afSIgor Opaniuk avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
341d8f9d2afSIgor Opaniuk ctx->block[ctx->len] = 0x80;
342d8f9d2afSIgor Opaniuk UNPACK32(len_b, ctx->block + pm_len - 4);
343d8f9d2afSIgor Opaniuk
344d8f9d2afSIgor Opaniuk SHA512_transform(ctx, ctx->block, block_nb);
345d8f9d2afSIgor Opaniuk
346d8f9d2afSIgor Opaniuk #ifdef UNROLL_LOOPS_SHA512
347d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[0], &ctx->buf[0]);
348d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[1], &ctx->buf[8]);
349d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[2], &ctx->buf[16]);
350d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[3], &ctx->buf[24]);
351d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[4], &ctx->buf[32]);
352d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[5], &ctx->buf[40]);
353d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[6], &ctx->buf[48]);
354d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[7], &ctx->buf[56]);
355d8f9d2afSIgor Opaniuk #else
356d8f9d2afSIgor Opaniuk for (i = 0; i < 8; i++)
357d8f9d2afSIgor Opaniuk UNPACK64(ctx->h[i], &ctx->buf[i << 3]);
358d8f9d2afSIgor Opaniuk #endif /* UNROLL_LOOPS_SHA512 */
359d8f9d2afSIgor Opaniuk
360d8f9d2afSIgor Opaniuk return ctx->buf;
361d8f9d2afSIgor Opaniuk }
362