xref: /rk3399_rockchip-uboot/lib/avb/libavb/avb_sha512.c (revision 5b0bc491775b5fbdb7c2928102abff2e61be3376)
137a7bc39SJason Zhu /* SHA-256 and SHA-512 implementation based on code by Oliver Gay
237a7bc39SJason Zhu  * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below.
337a7bc39SJason Zhu  */
437a7bc39SJason Zhu 
537a7bc39SJason Zhu /*
637a7bc39SJason Zhu  * FIPS 180-2 SHA-224/256/384/512 implementation
737a7bc39SJason Zhu  * Last update: 02/02/2007
837a7bc39SJason Zhu  * Issue date:  04/30/2005
937a7bc39SJason Zhu  *
1037a7bc39SJason Zhu  * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
1137a7bc39SJason Zhu  * All rights reserved.
1237a7bc39SJason Zhu  *
1337a7bc39SJason Zhu  * Redistribution and use in source and binary forms, with or without
1437a7bc39SJason Zhu  * modification, are permitted provided that the following conditions
1537a7bc39SJason Zhu  * are met:
1637a7bc39SJason Zhu  * 1. Redistributions of source code must retain the above copyright
1737a7bc39SJason Zhu  *    notice, this list of conditions and the following disclaimer.
1837a7bc39SJason Zhu  * 2. Redistributions in binary form must reproduce the above copyright
1937a7bc39SJason Zhu  *    notice, this list of conditions and the following disclaimer in the
2037a7bc39SJason Zhu  *    documentation and/or other materials provided with the distribution.
2137a7bc39SJason Zhu  * 3. Neither the name of the project nor the names of its contributors
2237a7bc39SJason Zhu  *    may be used to endorse or promote products derived from this software
2337a7bc39SJason Zhu  *    without specific prior written permission.
2437a7bc39SJason Zhu  *
2537a7bc39SJason Zhu  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2637a7bc39SJason Zhu  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2737a7bc39SJason Zhu  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2837a7bc39SJason Zhu  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2937a7bc39SJason Zhu  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3037a7bc39SJason Zhu  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3137a7bc39SJason Zhu  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3237a7bc39SJason Zhu  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3337a7bc39SJason Zhu  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3437a7bc39SJason Zhu  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3537a7bc39SJason Zhu  * SUCH DAMAGE.
3637a7bc39SJason Zhu  */
3737a7bc39SJason Zhu 
3837a7bc39SJason Zhu #include <android_avb/avb_sha.h>
39*5b0bc491SJoseph Chen #include <android_avb/avb_util.h>
4037a7bc39SJason Zhu 
41*5b0bc491SJoseph Chen /* Crypto-v1 is not support sha512 */
42*5b0bc491SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRYPTO_V2
43*5b0bc491SJoseph Chen void avb_sha512_init(AvbSHA512Ctx* ctx) {
44*5b0bc491SJoseph Chen   ctx->crypto_ctx.algo = CRYPTO_SHA512;
45*5b0bc491SJoseph Chen   ctx->crypto_ctx.length = ctx->tot_len;
46*5b0bc491SJoseph Chen   memset(ctx->buf, 0, sizeof(ctx->buf));
47*5b0bc491SJoseph Chen 
48*5b0bc491SJoseph Chen   ctx->crypto_dev = crypto_get_device(ctx->crypto_ctx.algo);
49*5b0bc491SJoseph Chen   if (!ctx->crypto_dev)
50*5b0bc491SJoseph Chen     avb_error("Can't get sha512 crypto device\n");
51*5b0bc491SJoseph Chen   else
52*5b0bc491SJoseph Chen     crypto_sha_init(ctx->crypto_dev, &ctx->crypto_ctx);
53*5b0bc491SJoseph Chen }
54*5b0bc491SJoseph Chen 
55*5b0bc491SJoseph Chen void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) {
56*5b0bc491SJoseph Chen   if (ctx->crypto_dev)
57*5b0bc491SJoseph Chen     crypto_sha_update(ctx->crypto_dev, (u32 *)data, len);
58*5b0bc491SJoseph Chen }
59*5b0bc491SJoseph Chen 
60*5b0bc491SJoseph Chen uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
61*5b0bc491SJoseph Chen   if (ctx->crypto_dev)
62*5b0bc491SJoseph Chen     crypto_sha_final(ctx->crypto_dev, &ctx->crypto_ctx, ctx->buf);
63*5b0bc491SJoseph Chen 
64*5b0bc491SJoseph Chen   return ctx->buf;
65*5b0bc491SJoseph Chen }
66*5b0bc491SJoseph Chen 
67*5b0bc491SJoseph Chen #else
6837a7bc39SJason Zhu #define SHFR(x, n) (x >> n)
6937a7bc39SJason Zhu #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
7037a7bc39SJason Zhu #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
7137a7bc39SJason Zhu #define CH(x, y, z) ((x & y) ^ (~x & z))
7237a7bc39SJason Zhu #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
7337a7bc39SJason Zhu 
7437a7bc39SJason Zhu #define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
7537a7bc39SJason Zhu #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
7637a7bc39SJason Zhu #define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7))
7737a7bc39SJason Zhu #define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6))
7837a7bc39SJason Zhu 
7937a7bc39SJason Zhu #define UNPACK32(x, str)                 \
8037a7bc39SJason Zhu   {                                      \
8137a7bc39SJason Zhu     *((str) + 3) = (uint8_t)((x));       \
8237a7bc39SJason Zhu     *((str) + 2) = (uint8_t)((x) >> 8);  \
8337a7bc39SJason Zhu     *((str) + 1) = (uint8_t)((x) >> 16); \
8437a7bc39SJason Zhu     *((str) + 0) = (uint8_t)((x) >> 24); \
8537a7bc39SJason Zhu   }
8637a7bc39SJason Zhu 
8737a7bc39SJason Zhu #define UNPACK64(x, str)                         \
8837a7bc39SJason Zhu   {                                              \
8937a7bc39SJason Zhu     *((str) + 7) = (uint8_t)x;                   \
9037a7bc39SJason Zhu     *((str) + 6) = (uint8_t)((uint64_t)x >> 8);  \
9137a7bc39SJason Zhu     *((str) + 5) = (uint8_t)((uint64_t)x >> 16); \
9237a7bc39SJason Zhu     *((str) + 4) = (uint8_t)((uint64_t)x >> 24); \
9337a7bc39SJason Zhu     *((str) + 3) = (uint8_t)((uint64_t)x >> 32); \
9437a7bc39SJason Zhu     *((str) + 2) = (uint8_t)((uint64_t)x >> 40); \
9537a7bc39SJason Zhu     *((str) + 1) = (uint8_t)((uint64_t)x >> 48); \
9637a7bc39SJason Zhu     *((str) + 0) = (uint8_t)((uint64_t)x >> 56); \
9737a7bc39SJason Zhu   }
9837a7bc39SJason Zhu 
9937a7bc39SJason Zhu #define PACK64(str, x)                                                        \
10037a7bc39SJason Zhu   {                                                                           \
10137a7bc39SJason Zhu     *(x) =                                                                    \
10237a7bc39SJason Zhu         ((uint64_t) * ((str) + 7)) | ((uint64_t) * ((str) + 6) << 8) |        \
10337a7bc39SJason Zhu         ((uint64_t) * ((str) + 5) << 16) | ((uint64_t) * ((str) + 4) << 24) | \
10437a7bc39SJason Zhu         ((uint64_t) * ((str) + 3) << 32) | ((uint64_t) * ((str) + 2) << 40) | \
10537a7bc39SJason Zhu         ((uint64_t) * ((str) + 1) << 48) | ((uint64_t) * ((str) + 0) << 56);  \
10637a7bc39SJason Zhu   }
10737a7bc39SJason Zhu 
10837a7bc39SJason Zhu /* Macros used for loops unrolling */
10937a7bc39SJason Zhu 
11037a7bc39SJason Zhu #define SHA512_SCR(i) \
11137a7bc39SJason Zhu   { w[i] = SHA512_F4(w[i - 2]) + w[i - 7] + SHA512_F3(w[i - 15]) + w[i - 16]; }
11237a7bc39SJason Zhu 
11337a7bc39SJason Zhu #define SHA512_EXP(a, b, c, d, e, f, g, h, j)                               \
11437a7bc39SJason Zhu   {                                                                         \
11537a7bc39SJason Zhu     t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) + sha512_k[j] + \
11637a7bc39SJason Zhu          w[j];                                                              \
11737a7bc39SJason Zhu     t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);                       \
11837a7bc39SJason Zhu     wv[d] += t1;                                                            \
11937a7bc39SJason Zhu     wv[h] = t1 + t2;                                                        \
12037a7bc39SJason Zhu   }
12137a7bc39SJason Zhu 
12237a7bc39SJason Zhu static const uint64_t sha512_h0[8] = {0x6a09e667f3bcc908ULL,
12337a7bc39SJason Zhu                                       0xbb67ae8584caa73bULL,
12437a7bc39SJason Zhu                                       0x3c6ef372fe94f82bULL,
12537a7bc39SJason Zhu                                       0xa54ff53a5f1d36f1ULL,
12637a7bc39SJason Zhu                                       0x510e527fade682d1ULL,
12737a7bc39SJason Zhu                                       0x9b05688c2b3e6c1fULL,
12837a7bc39SJason Zhu                                       0x1f83d9abfb41bd6bULL,
12937a7bc39SJason Zhu                                       0x5be0cd19137e2179ULL};
13037a7bc39SJason Zhu 
13137a7bc39SJason Zhu static const uint64_t sha512_k[80] = {
13237a7bc39SJason Zhu     0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
13337a7bc39SJason Zhu     0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
13437a7bc39SJason Zhu     0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
13537a7bc39SJason Zhu     0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
13637a7bc39SJason Zhu     0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
13737a7bc39SJason Zhu     0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
13837a7bc39SJason Zhu     0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
13937a7bc39SJason Zhu     0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
14037a7bc39SJason Zhu     0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
14137a7bc39SJason Zhu     0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
14237a7bc39SJason Zhu     0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
14337a7bc39SJason Zhu     0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
14437a7bc39SJason Zhu     0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
14537a7bc39SJason Zhu     0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
14637a7bc39SJason Zhu     0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
14737a7bc39SJason Zhu     0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
14837a7bc39SJason Zhu     0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
14937a7bc39SJason Zhu     0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
15037a7bc39SJason Zhu     0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
15137a7bc39SJason Zhu     0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
15237a7bc39SJason Zhu     0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
15337a7bc39SJason Zhu     0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
15437a7bc39SJason Zhu     0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
15537a7bc39SJason Zhu     0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
15637a7bc39SJason Zhu     0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
15737a7bc39SJason Zhu     0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
15837a7bc39SJason Zhu     0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
15937a7bc39SJason Zhu 
16037a7bc39SJason Zhu /* SHA-512 implementation */
16137a7bc39SJason Zhu 
16237a7bc39SJason Zhu void avb_sha512_init(AvbSHA512Ctx* ctx) {
16337a7bc39SJason Zhu #ifdef UNROLL_LOOPS_SHA512
16437a7bc39SJason Zhu   ctx->h[0] = sha512_h0[0];
16537a7bc39SJason Zhu   ctx->h[1] = sha512_h0[1];
16637a7bc39SJason Zhu   ctx->h[2] = sha512_h0[2];
16737a7bc39SJason Zhu   ctx->h[3] = sha512_h0[3];
16837a7bc39SJason Zhu   ctx->h[4] = sha512_h0[4];
16937a7bc39SJason Zhu   ctx->h[5] = sha512_h0[5];
17037a7bc39SJason Zhu   ctx->h[6] = sha512_h0[6];
17137a7bc39SJason Zhu   ctx->h[7] = sha512_h0[7];
17237a7bc39SJason Zhu #else
17337a7bc39SJason Zhu   int i;
17437a7bc39SJason Zhu 
17537a7bc39SJason Zhu   for (i = 0; i < 8; i++)
17637a7bc39SJason Zhu     ctx->h[i] = sha512_h0[i];
17737a7bc39SJason Zhu #endif /* UNROLL_LOOPS_SHA512 */
17837a7bc39SJason Zhu 
17937a7bc39SJason Zhu   ctx->len = 0;
18037a7bc39SJason Zhu   ctx->tot_len = 0;
18137a7bc39SJason Zhu }
18237a7bc39SJason Zhu 
18337a7bc39SJason Zhu static void SHA512_transform(AvbSHA512Ctx* ctx,
18437a7bc39SJason Zhu                              const uint8_t* message,
18569fdc596SJason Zhu                              size_t block_nb) {
18637a7bc39SJason Zhu   uint64_t w[80];
18737a7bc39SJason Zhu   uint64_t wv[8];
18837a7bc39SJason Zhu   uint64_t t1, t2;
18937a7bc39SJason Zhu   const uint8_t* sub_block;
19069fdc596SJason Zhu   size_t i, j;
19137a7bc39SJason Zhu 
19269fdc596SJason Zhu   for (i = 0; i < block_nb; i++) {
19337a7bc39SJason Zhu     sub_block = message + (i << 7);
19437a7bc39SJason Zhu 
19537a7bc39SJason Zhu #ifdef UNROLL_LOOPS_SHA512
19637a7bc39SJason Zhu     PACK64(&sub_block[0], &w[0]);
19737a7bc39SJason Zhu     PACK64(&sub_block[8], &w[1]);
19837a7bc39SJason Zhu     PACK64(&sub_block[16], &w[2]);
19937a7bc39SJason Zhu     PACK64(&sub_block[24], &w[3]);
20037a7bc39SJason Zhu     PACK64(&sub_block[32], &w[4]);
20137a7bc39SJason Zhu     PACK64(&sub_block[40], &w[5]);
20237a7bc39SJason Zhu     PACK64(&sub_block[48], &w[6]);
20337a7bc39SJason Zhu     PACK64(&sub_block[56], &w[7]);
20437a7bc39SJason Zhu     PACK64(&sub_block[64], &w[8]);
20537a7bc39SJason Zhu     PACK64(&sub_block[72], &w[9]);
20637a7bc39SJason Zhu     PACK64(&sub_block[80], &w[10]);
20737a7bc39SJason Zhu     PACK64(&sub_block[88], &w[11]);
20837a7bc39SJason Zhu     PACK64(&sub_block[96], &w[12]);
20937a7bc39SJason Zhu     PACK64(&sub_block[104], &w[13]);
21037a7bc39SJason Zhu     PACK64(&sub_block[112], &w[14]);
21137a7bc39SJason Zhu     PACK64(&sub_block[120], &w[15]);
21237a7bc39SJason Zhu 
21337a7bc39SJason Zhu     SHA512_SCR(16);
21437a7bc39SJason Zhu     SHA512_SCR(17);
21537a7bc39SJason Zhu     SHA512_SCR(18);
21637a7bc39SJason Zhu     SHA512_SCR(19);
21737a7bc39SJason Zhu     SHA512_SCR(20);
21837a7bc39SJason Zhu     SHA512_SCR(21);
21937a7bc39SJason Zhu     SHA512_SCR(22);
22037a7bc39SJason Zhu     SHA512_SCR(23);
22137a7bc39SJason Zhu     SHA512_SCR(24);
22237a7bc39SJason Zhu     SHA512_SCR(25);
22337a7bc39SJason Zhu     SHA512_SCR(26);
22437a7bc39SJason Zhu     SHA512_SCR(27);
22537a7bc39SJason Zhu     SHA512_SCR(28);
22637a7bc39SJason Zhu     SHA512_SCR(29);
22737a7bc39SJason Zhu     SHA512_SCR(30);
22837a7bc39SJason Zhu     SHA512_SCR(31);
22937a7bc39SJason Zhu     SHA512_SCR(32);
23037a7bc39SJason Zhu     SHA512_SCR(33);
23137a7bc39SJason Zhu     SHA512_SCR(34);
23237a7bc39SJason Zhu     SHA512_SCR(35);
23337a7bc39SJason Zhu     SHA512_SCR(36);
23437a7bc39SJason Zhu     SHA512_SCR(37);
23537a7bc39SJason Zhu     SHA512_SCR(38);
23637a7bc39SJason Zhu     SHA512_SCR(39);
23737a7bc39SJason Zhu     SHA512_SCR(40);
23837a7bc39SJason Zhu     SHA512_SCR(41);
23937a7bc39SJason Zhu     SHA512_SCR(42);
24037a7bc39SJason Zhu     SHA512_SCR(43);
24137a7bc39SJason Zhu     SHA512_SCR(44);
24237a7bc39SJason Zhu     SHA512_SCR(45);
24337a7bc39SJason Zhu     SHA512_SCR(46);
24437a7bc39SJason Zhu     SHA512_SCR(47);
24537a7bc39SJason Zhu     SHA512_SCR(48);
24637a7bc39SJason Zhu     SHA512_SCR(49);
24737a7bc39SJason Zhu     SHA512_SCR(50);
24837a7bc39SJason Zhu     SHA512_SCR(51);
24937a7bc39SJason Zhu     SHA512_SCR(52);
25037a7bc39SJason Zhu     SHA512_SCR(53);
25137a7bc39SJason Zhu     SHA512_SCR(54);
25237a7bc39SJason Zhu     SHA512_SCR(55);
25337a7bc39SJason Zhu     SHA512_SCR(56);
25437a7bc39SJason Zhu     SHA512_SCR(57);
25537a7bc39SJason Zhu     SHA512_SCR(58);
25637a7bc39SJason Zhu     SHA512_SCR(59);
25737a7bc39SJason Zhu     SHA512_SCR(60);
25837a7bc39SJason Zhu     SHA512_SCR(61);
25937a7bc39SJason Zhu     SHA512_SCR(62);
26037a7bc39SJason Zhu     SHA512_SCR(63);
26137a7bc39SJason Zhu     SHA512_SCR(64);
26237a7bc39SJason Zhu     SHA512_SCR(65);
26337a7bc39SJason Zhu     SHA512_SCR(66);
26437a7bc39SJason Zhu     SHA512_SCR(67);
26537a7bc39SJason Zhu     SHA512_SCR(68);
26637a7bc39SJason Zhu     SHA512_SCR(69);
26737a7bc39SJason Zhu     SHA512_SCR(70);
26837a7bc39SJason Zhu     SHA512_SCR(71);
26937a7bc39SJason Zhu     SHA512_SCR(72);
27037a7bc39SJason Zhu     SHA512_SCR(73);
27137a7bc39SJason Zhu     SHA512_SCR(74);
27237a7bc39SJason Zhu     SHA512_SCR(75);
27337a7bc39SJason Zhu     SHA512_SCR(76);
27437a7bc39SJason Zhu     SHA512_SCR(77);
27537a7bc39SJason Zhu     SHA512_SCR(78);
27637a7bc39SJason Zhu     SHA512_SCR(79);
27737a7bc39SJason Zhu 
27837a7bc39SJason Zhu     wv[0] = ctx->h[0];
27937a7bc39SJason Zhu     wv[1] = ctx->h[1];
28037a7bc39SJason Zhu     wv[2] = ctx->h[2];
28137a7bc39SJason Zhu     wv[3] = ctx->h[3];
28237a7bc39SJason Zhu     wv[4] = ctx->h[4];
28337a7bc39SJason Zhu     wv[5] = ctx->h[5];
28437a7bc39SJason Zhu     wv[6] = ctx->h[6];
28537a7bc39SJason Zhu     wv[7] = ctx->h[7];
28637a7bc39SJason Zhu 
28737a7bc39SJason Zhu     j = 0;
28837a7bc39SJason Zhu 
28937a7bc39SJason Zhu     do {
29037a7bc39SJason Zhu       SHA512_EXP(0, 1, 2, 3, 4, 5, 6, 7, j);
29137a7bc39SJason Zhu       j++;
29237a7bc39SJason Zhu       SHA512_EXP(7, 0, 1, 2, 3, 4, 5, 6, j);
29337a7bc39SJason Zhu       j++;
29437a7bc39SJason Zhu       SHA512_EXP(6, 7, 0, 1, 2, 3, 4, 5, j);
29537a7bc39SJason Zhu       j++;
29637a7bc39SJason Zhu       SHA512_EXP(5, 6, 7, 0, 1, 2, 3, 4, j);
29737a7bc39SJason Zhu       j++;
29837a7bc39SJason Zhu       SHA512_EXP(4, 5, 6, 7, 0, 1, 2, 3, j);
29937a7bc39SJason Zhu       j++;
30037a7bc39SJason Zhu       SHA512_EXP(3, 4, 5, 6, 7, 0, 1, 2, j);
30137a7bc39SJason Zhu       j++;
30237a7bc39SJason Zhu       SHA512_EXP(2, 3, 4, 5, 6, 7, 0, 1, j);
30337a7bc39SJason Zhu       j++;
30437a7bc39SJason Zhu       SHA512_EXP(1, 2, 3, 4, 5, 6, 7, 0, j);
30537a7bc39SJason Zhu       j++;
30637a7bc39SJason Zhu     } while (j < 80);
30737a7bc39SJason Zhu 
30837a7bc39SJason Zhu     ctx->h[0] += wv[0];
30937a7bc39SJason Zhu     ctx->h[1] += wv[1];
31037a7bc39SJason Zhu     ctx->h[2] += wv[2];
31137a7bc39SJason Zhu     ctx->h[3] += wv[3];
31237a7bc39SJason Zhu     ctx->h[4] += wv[4];
31337a7bc39SJason Zhu     ctx->h[5] += wv[5];
31437a7bc39SJason Zhu     ctx->h[6] += wv[6];
31537a7bc39SJason Zhu     ctx->h[7] += wv[7];
31637a7bc39SJason Zhu #else
31737a7bc39SJason Zhu     for (j = 0; j < 16; j++) {
31837a7bc39SJason Zhu       PACK64(&sub_block[j << 3], &w[j]);
31937a7bc39SJason Zhu     }
32037a7bc39SJason Zhu 
32137a7bc39SJason Zhu     for (j = 16; j < 80; j++) {
32237a7bc39SJason Zhu       SHA512_SCR(j);
32337a7bc39SJason Zhu     }
32437a7bc39SJason Zhu 
32537a7bc39SJason Zhu     for (j = 0; j < 8; j++) {
32637a7bc39SJason Zhu       wv[j] = ctx->h[j];
32737a7bc39SJason Zhu     }
32837a7bc39SJason Zhu 
32937a7bc39SJason Zhu     for (j = 0; j < 80; j++) {
33037a7bc39SJason Zhu       t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha512_k[j] +
33137a7bc39SJason Zhu            w[j];
33237a7bc39SJason Zhu       t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
33337a7bc39SJason Zhu       wv[7] = wv[6];
33437a7bc39SJason Zhu       wv[6] = wv[5];
33537a7bc39SJason Zhu       wv[5] = wv[4];
33637a7bc39SJason Zhu       wv[4] = wv[3] + t1;
33737a7bc39SJason Zhu       wv[3] = wv[2];
33837a7bc39SJason Zhu       wv[2] = wv[1];
33937a7bc39SJason Zhu       wv[1] = wv[0];
34037a7bc39SJason Zhu       wv[0] = t1 + t2;
34137a7bc39SJason Zhu     }
34237a7bc39SJason Zhu 
34337a7bc39SJason Zhu     for (j = 0; j < 8; j++)
34437a7bc39SJason Zhu       ctx->h[j] += wv[j];
34537a7bc39SJason Zhu #endif /* UNROLL_LOOPS_SHA512 */
34637a7bc39SJason Zhu   }
34737a7bc39SJason Zhu }
34837a7bc39SJason Zhu 
34969fdc596SJason Zhu void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) {
35069fdc596SJason Zhu   size_t block_nb;
35169fdc596SJason Zhu   size_t new_len, rem_len, tmp_len;
35237a7bc39SJason Zhu   const uint8_t* shifted_data;
35337a7bc39SJason Zhu 
35437a7bc39SJason Zhu   tmp_len = AVB_SHA512_BLOCK_SIZE - ctx->len;
35537a7bc39SJason Zhu   rem_len = len < tmp_len ? len : tmp_len;
35637a7bc39SJason Zhu 
35737a7bc39SJason Zhu   avb_memcpy(&ctx->block[ctx->len], data, rem_len);
35837a7bc39SJason Zhu 
35937a7bc39SJason Zhu   if (ctx->len + len < AVB_SHA512_BLOCK_SIZE) {
36037a7bc39SJason Zhu     ctx->len += len;
36137a7bc39SJason Zhu     return;
36237a7bc39SJason Zhu   }
36337a7bc39SJason Zhu 
36437a7bc39SJason Zhu   new_len = len - rem_len;
36537a7bc39SJason Zhu   block_nb = new_len / AVB_SHA512_BLOCK_SIZE;
36637a7bc39SJason Zhu 
36737a7bc39SJason Zhu   shifted_data = data + rem_len;
36837a7bc39SJason Zhu 
36937a7bc39SJason Zhu   SHA512_transform(ctx, ctx->block, 1);
37037a7bc39SJason Zhu   SHA512_transform(ctx, shifted_data, block_nb);
37137a7bc39SJason Zhu 
37237a7bc39SJason Zhu   rem_len = new_len % AVB_SHA512_BLOCK_SIZE;
37337a7bc39SJason Zhu 
37437a7bc39SJason Zhu   avb_memcpy(ctx->block, &shifted_data[block_nb << 7], rem_len);
37537a7bc39SJason Zhu 
37637a7bc39SJason Zhu   ctx->len = rem_len;
37737a7bc39SJason Zhu   ctx->tot_len += (block_nb + 1) << 7;
37837a7bc39SJason Zhu }
37937a7bc39SJason Zhu 
38037a7bc39SJason Zhu uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
38169fdc596SJason Zhu   size_t block_nb;
38269fdc596SJason Zhu   size_t pm_len;
38369fdc596SJason Zhu   uint64_t len_b;
38437a7bc39SJason Zhu 
38537a7bc39SJason Zhu #ifndef UNROLL_LOOPS_SHA512
38669fdc596SJason Zhu   size_t i;
38737a7bc39SJason Zhu #endif
38837a7bc39SJason Zhu 
38937a7bc39SJason Zhu   block_nb =
39037a7bc39SJason Zhu       1 + ((AVB_SHA512_BLOCK_SIZE - 17) < (ctx->len % AVB_SHA512_BLOCK_SIZE));
39137a7bc39SJason Zhu 
39237a7bc39SJason Zhu   len_b = (ctx->tot_len + ctx->len) << 3;
39337a7bc39SJason Zhu   pm_len = block_nb << 7;
39437a7bc39SJason Zhu 
39537a7bc39SJason Zhu   avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
39637a7bc39SJason Zhu   ctx->block[ctx->len] = 0x80;
39769fdc596SJason Zhu   UNPACK64(len_b, ctx->block + pm_len - 8);
39837a7bc39SJason Zhu 
39937a7bc39SJason Zhu   SHA512_transform(ctx, ctx->block, block_nb);
40037a7bc39SJason Zhu 
40137a7bc39SJason Zhu #ifdef UNROLL_LOOPS_SHA512
40237a7bc39SJason Zhu   UNPACK64(ctx->h[0], &ctx->buf[0]);
40337a7bc39SJason Zhu   UNPACK64(ctx->h[1], &ctx->buf[8]);
40437a7bc39SJason Zhu   UNPACK64(ctx->h[2], &ctx->buf[16]);
40537a7bc39SJason Zhu   UNPACK64(ctx->h[3], &ctx->buf[24]);
40637a7bc39SJason Zhu   UNPACK64(ctx->h[4], &ctx->buf[32]);
40737a7bc39SJason Zhu   UNPACK64(ctx->h[5], &ctx->buf[40]);
40837a7bc39SJason Zhu   UNPACK64(ctx->h[6], &ctx->buf[48]);
40937a7bc39SJason Zhu   UNPACK64(ctx->h[7], &ctx->buf[56]);
41037a7bc39SJason Zhu #else
41137a7bc39SJason Zhu   for (i = 0; i < 8; i++)
41237a7bc39SJason Zhu     UNPACK64(ctx->h[i], &ctx->buf[i << 3]);
41337a7bc39SJason Zhu #endif /* UNROLL_LOOPS_SHA512 */
41437a7bc39SJason Zhu 
41537a7bc39SJason Zhu   return ctx->buf;
41637a7bc39SJason Zhu }
417*5b0bc491SJoseph Chen #endif
418