xref: /openbmc/u-boot/lib/libavb/avb_sha512.c (revision 897a1d947e7e50cf03113dcbe505ffb63dce45a9)
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