xref: /isa-l_crypto/mh_sha256/mh_sha256_ref.c (revision 15f45959d342594afa975e58d4e7e8bbe34e2f0b)
17dc32ad5SXiaodong Liu /**********************************************************************
27dc32ad5SXiaodong Liu   Copyright(c) 2011-2017 Intel Corporation All rights reserved.
37dc32ad5SXiaodong Liu 
47dc32ad5SXiaodong Liu   Redistribution and use in source and binary forms, with or without
57dc32ad5SXiaodong Liu   modification, are permitted provided that the following conditions
67dc32ad5SXiaodong Liu   are met:
77dc32ad5SXiaodong Liu     * Redistributions of source code must retain the above copyright
87dc32ad5SXiaodong Liu       notice, this list of conditions and the following disclaimer.
97dc32ad5SXiaodong Liu     * Redistributions in binary form must reproduce the above copyright
107dc32ad5SXiaodong Liu       notice, this list of conditions and the following disclaimer in
117dc32ad5SXiaodong Liu       the documentation and/or other materials provided with the
127dc32ad5SXiaodong Liu       distribution.
137dc32ad5SXiaodong Liu     * Neither the name of Intel Corporation nor the names of its
147dc32ad5SXiaodong Liu       contributors may be used to endorse or promote products derived
157dc32ad5SXiaodong Liu       from this software without specific prior written permission.
167dc32ad5SXiaodong Liu 
177dc32ad5SXiaodong Liu   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187dc32ad5SXiaodong Liu   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
197dc32ad5SXiaodong Liu   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
207dc32ad5SXiaodong Liu   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
217dc32ad5SXiaodong Liu   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
227dc32ad5SXiaodong Liu   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
237dc32ad5SXiaodong Liu   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
247dc32ad5SXiaodong Liu   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
257dc32ad5SXiaodong Liu   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
267dc32ad5SXiaodong Liu   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
277dc32ad5SXiaodong Liu   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
287dc32ad5SXiaodong Liu **********************************************************************/
297dc32ad5SXiaodong Liu 
307dc32ad5SXiaodong Liu #include <string.h>
317dc32ad5SXiaodong Liu #include "mh_sha256_internal.h"
327dc32ad5SXiaodong Liu 
337dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
347dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
357dc32ad5SXiaodong Liu //  Macros and sub-functions which already exist in source code file
367dc32ad5SXiaodong Liu //  (sha256_for_mh_sha256.c) is part of ISA-L library as internal functions.
377dc32ad5SXiaodong Liu //  The reason why writing them twice is the linking issue caused by
387dc32ad5SXiaodong Liu //  mh_sha256_ref(). mh_sha256_ref() needs these macros and sub-functions
397dc32ad5SXiaodong Liu //  without linking ISA-L library. So mh_sha256_ref() includes them in
407dc32ad5SXiaodong Liu //  order to contain essential sub-functions in its own object file.
417dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
427dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
437dc32ad5SXiaodong Liu 
447dc32ad5SXiaodong Liu #define W(x) w[(x) & 15]
457dc32ad5SXiaodong Liu 
467dc32ad5SXiaodong Liu #define step(i, a, b, c, d, e, f, g, h, k)                                                         \
4738e16e11SMarcel Cornu         if (i < 16)                                                                                \
4838e16e11SMarcel Cornu                 W(i) = to_be32(ww[i]);                                                             \
497dc32ad5SXiaodong Liu         else                                                                                       \
507dc32ad5SXiaodong Liu                 W(i) = W(i - 16) + S0(W(i - 15)) + W(i - 7) + S1(W(i - 2));                        \
517dc32ad5SXiaodong Liu         t2 = s0(a) + maj(a, b, c);                                                                 \
527dc32ad5SXiaodong Liu         t1 = h + s1(e) + ch(e, f, g) + k + W(i);                                                   \
537dc32ad5SXiaodong Liu         d += t1;                                                                                   \
547dc32ad5SXiaodong Liu         h = t1 + t2;
557dc32ad5SXiaodong Liu 
5638e16e11SMarcel Cornu void
sha256_single_for_mh_sha256_ref(const uint8_t * data,uint32_t digest[])5738e16e11SMarcel Cornu sha256_single_for_mh_sha256_ref(const uint8_t *data, uint32_t digest[])
587dc32ad5SXiaodong Liu {
597dc32ad5SXiaodong Liu         uint32_t a, b, c, d, e, f, g, h, t1, t2;
607dc32ad5SXiaodong Liu         uint32_t w[16];
617dc32ad5SXiaodong Liu         uint32_t *ww = (uint32_t *) data;
627dc32ad5SXiaodong Liu 
637dc32ad5SXiaodong Liu         a = digest[0];
647dc32ad5SXiaodong Liu         b = digest[1];
657dc32ad5SXiaodong Liu         c = digest[2];
667dc32ad5SXiaodong Liu         d = digest[3];
677dc32ad5SXiaodong Liu         e = digest[4];
687dc32ad5SXiaodong Liu         f = digest[5];
697dc32ad5SXiaodong Liu         g = digest[6];
707dc32ad5SXiaodong Liu         h = digest[7];
717dc32ad5SXiaodong Liu 
727dc32ad5SXiaodong Liu         step(0, a, b, c, d, e, f, g, h, 0x428a2f98);
737dc32ad5SXiaodong Liu         step(1, h, a, b, c, d, e, f, g, 0x71374491);
747dc32ad5SXiaodong Liu         step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcf);
757dc32ad5SXiaodong Liu         step(3, f, g, h, a, b, c, d, e, 0xe9b5dba5);
767dc32ad5SXiaodong Liu         step(4, e, f, g, h, a, b, c, d, 0x3956c25b);
777dc32ad5SXiaodong Liu         step(5, d, e, f, g, h, a, b, c, 0x59f111f1);
787dc32ad5SXiaodong Liu         step(6, c, d, e, f, g, h, a, b, 0x923f82a4);
797dc32ad5SXiaodong Liu         step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5);
807dc32ad5SXiaodong Liu         step(8, a, b, c, d, e, f, g, h, 0xd807aa98);
817dc32ad5SXiaodong Liu         step(9, h, a, b, c, d, e, f, g, 0x12835b01);
827dc32ad5SXiaodong Liu         step(10, g, h, a, b, c, d, e, f, 0x243185be);
837dc32ad5SXiaodong Liu         step(11, f, g, h, a, b, c, d, e, 0x550c7dc3);
847dc32ad5SXiaodong Liu         step(12, e, f, g, h, a, b, c, d, 0x72be5d74);
857dc32ad5SXiaodong Liu         step(13, d, e, f, g, h, a, b, c, 0x80deb1fe);
867dc32ad5SXiaodong Liu         step(14, c, d, e, f, g, h, a, b, 0x9bdc06a7);
877dc32ad5SXiaodong Liu         step(15, b, c, d, e, f, g, h, a, 0xc19bf174);
887dc32ad5SXiaodong Liu         step(16, a, b, c, d, e, f, g, h, 0xe49b69c1);
897dc32ad5SXiaodong Liu         step(17, h, a, b, c, d, e, f, g, 0xefbe4786);
907dc32ad5SXiaodong Liu         step(18, g, h, a, b, c, d, e, f, 0x0fc19dc6);
917dc32ad5SXiaodong Liu         step(19, f, g, h, a, b, c, d, e, 0x240ca1cc);
927dc32ad5SXiaodong Liu         step(20, e, f, g, h, a, b, c, d, 0x2de92c6f);
937dc32ad5SXiaodong Liu         step(21, d, e, f, g, h, a, b, c, 0x4a7484aa);
947dc32ad5SXiaodong Liu         step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dc);
957dc32ad5SXiaodong Liu         step(23, b, c, d, e, f, g, h, a, 0x76f988da);
967dc32ad5SXiaodong Liu         step(24, a, b, c, d, e, f, g, h, 0x983e5152);
977dc32ad5SXiaodong Liu         step(25, h, a, b, c, d, e, f, g, 0xa831c66d);
987dc32ad5SXiaodong Liu         step(26, g, h, a, b, c, d, e, f, 0xb00327c8);
997dc32ad5SXiaodong Liu         step(27, f, g, h, a, b, c, d, e, 0xbf597fc7);
1007dc32ad5SXiaodong Liu         step(28, e, f, g, h, a, b, c, d, 0xc6e00bf3);
1017dc32ad5SXiaodong Liu         step(29, d, e, f, g, h, a, b, c, 0xd5a79147);
1027dc32ad5SXiaodong Liu         step(30, c, d, e, f, g, h, a, b, 0x06ca6351);
1037dc32ad5SXiaodong Liu         step(31, b, c, d, e, f, g, h, a, 0x14292967);
1047dc32ad5SXiaodong Liu         step(32, a, b, c, d, e, f, g, h, 0x27b70a85);
1057dc32ad5SXiaodong Liu         step(33, h, a, b, c, d, e, f, g, 0x2e1b2138);
1067dc32ad5SXiaodong Liu         step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc);
1077dc32ad5SXiaodong Liu         step(35, f, g, h, a, b, c, d, e, 0x53380d13);
1087dc32ad5SXiaodong Liu         step(36, e, f, g, h, a, b, c, d, 0x650a7354);
1097dc32ad5SXiaodong Liu         step(37, d, e, f, g, h, a, b, c, 0x766a0abb);
1107dc32ad5SXiaodong Liu         step(38, c, d, e, f, g, h, a, b, 0x81c2c92e);
1117dc32ad5SXiaodong Liu         step(39, b, c, d, e, f, g, h, a, 0x92722c85);
1127dc32ad5SXiaodong Liu         step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a1);
1137dc32ad5SXiaodong Liu         step(41, h, a, b, c, d, e, f, g, 0xa81a664b);
1147dc32ad5SXiaodong Liu         step(42, g, h, a, b, c, d, e, f, 0xc24b8b70);
1157dc32ad5SXiaodong Liu         step(43, f, g, h, a, b, c, d, e, 0xc76c51a3);
1167dc32ad5SXiaodong Liu         step(44, e, f, g, h, a, b, c, d, 0xd192e819);
1177dc32ad5SXiaodong Liu         step(45, d, e, f, g, h, a, b, c, 0xd6990624);
1187dc32ad5SXiaodong Liu         step(46, c, d, e, f, g, h, a, b, 0xf40e3585);
1197dc32ad5SXiaodong Liu         step(47, b, c, d, e, f, g, h, a, 0x106aa070);
1207dc32ad5SXiaodong Liu         step(48, a, b, c, d, e, f, g, h, 0x19a4c116);
1217dc32ad5SXiaodong Liu         step(49, h, a, b, c, d, e, f, g, 0x1e376c08);
1227dc32ad5SXiaodong Liu         step(50, g, h, a, b, c, d, e, f, 0x2748774c);
1237dc32ad5SXiaodong Liu         step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5);
1247dc32ad5SXiaodong Liu         step(52, e, f, g, h, a, b, c, d, 0x391c0cb3);
1257dc32ad5SXiaodong Liu         step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4a);
1267dc32ad5SXiaodong Liu         step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f);
1277dc32ad5SXiaodong Liu         step(55, b, c, d, e, f, g, h, a, 0x682e6ff3);
1287dc32ad5SXiaodong Liu         step(56, a, b, c, d, e, f, g, h, 0x748f82ee);
1297dc32ad5SXiaodong Liu         step(57, h, a, b, c, d, e, f, g, 0x78a5636f);
1307dc32ad5SXiaodong Liu         step(58, g, h, a, b, c, d, e, f, 0x84c87814);
1317dc32ad5SXiaodong Liu         step(59, f, g, h, a, b, c, d, e, 0x8cc70208);
1327dc32ad5SXiaodong Liu         step(60, e, f, g, h, a, b, c, d, 0x90befffa);
1337dc32ad5SXiaodong Liu         step(61, d, e, f, g, h, a, b, c, 0xa4506ceb);
1347dc32ad5SXiaodong Liu         step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7);
1357dc32ad5SXiaodong Liu         step(63, b, c, d, e, f, g, h, a, 0xc67178f2);
1367dc32ad5SXiaodong Liu 
1377dc32ad5SXiaodong Liu         digest[0] += a;
1387dc32ad5SXiaodong Liu         digest[1] += b;
1397dc32ad5SXiaodong Liu         digest[2] += c;
1407dc32ad5SXiaodong Liu         digest[3] += d;
1417dc32ad5SXiaodong Liu         digest[4] += e;
1427dc32ad5SXiaodong Liu         digest[5] += f;
1437dc32ad5SXiaodong Liu         digest[6] += g;
1447dc32ad5SXiaodong Liu         digest[7] += h;
1457dc32ad5SXiaodong Liu }
1467dc32ad5SXiaodong Liu 
14738e16e11SMarcel Cornu void
sha256_for_mh_sha256_ref(const uint8_t * input_data,uint32_t * digest,const uint32_t len)14838e16e11SMarcel Cornu sha256_for_mh_sha256_ref(const uint8_t *input_data, uint32_t *digest, const uint32_t len)
1497dc32ad5SXiaodong Liu {
1507dc32ad5SXiaodong Liu         uint32_t i, j;
151*15f45959SMarcel Cornu         uint8_t buf[2 * ISAL_SHA256_BLOCK_SIZE];
1527dc32ad5SXiaodong Liu 
1537dc32ad5SXiaodong Liu         digest[0] = MH_SHA256_H0;
1547dc32ad5SXiaodong Liu         digest[1] = MH_SHA256_H1;
1557dc32ad5SXiaodong Liu         digest[2] = MH_SHA256_H2;
1567dc32ad5SXiaodong Liu         digest[3] = MH_SHA256_H3;
1577dc32ad5SXiaodong Liu         digest[4] = MH_SHA256_H4;
1587dc32ad5SXiaodong Liu         digest[5] = MH_SHA256_H5;
1597dc32ad5SXiaodong Liu         digest[6] = MH_SHA256_H6;
1607dc32ad5SXiaodong Liu         digest[7] = MH_SHA256_H7;
1617dc32ad5SXiaodong Liu 
1627dc32ad5SXiaodong Liu         i = len;
163*15f45959SMarcel Cornu         while (i >= ISAL_SHA256_BLOCK_SIZE) {
164cd6caf6aSGreg Tucker                 sha256_single_for_mh_sha256_ref(input_data, digest);
165*15f45959SMarcel Cornu                 input_data += ISAL_SHA256_BLOCK_SIZE;
166*15f45959SMarcel Cornu                 i -= ISAL_SHA256_BLOCK_SIZE;
1677dc32ad5SXiaodong Liu         }
1687dc32ad5SXiaodong Liu 
1697dc32ad5SXiaodong Liu         memcpy(buf, input_data, i);
1707dc32ad5SXiaodong Liu         buf[i++] = 0x80;
171*15f45959SMarcel Cornu         for (j = i; j < ((2 * ISAL_SHA256_BLOCK_SIZE) - 8); j++)
1727dc32ad5SXiaodong Liu                 buf[j] = 0;
1737dc32ad5SXiaodong Liu 
174*15f45959SMarcel Cornu         if (i > ISAL_SHA256_BLOCK_SIZE - 8)
175*15f45959SMarcel Cornu                 i = 2 * ISAL_SHA256_BLOCK_SIZE;
1767dc32ad5SXiaodong Liu         else
177*15f45959SMarcel Cornu                 i = ISAL_SHA256_BLOCK_SIZE;
1787dc32ad5SXiaodong Liu 
179e3f7d4fbSUlrich Weigand         *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) len * 8);
1807dc32ad5SXiaodong Liu 
1817dc32ad5SXiaodong Liu         sha256_single_for_mh_sha256_ref(buf, digest);
182*15f45959SMarcel Cornu         if (i == (2 * ISAL_SHA256_BLOCK_SIZE))
183*15f45959SMarcel Cornu                 sha256_single_for_mh_sha256_ref(buf + ISAL_SHA256_BLOCK_SIZE, digest);
1847dc32ad5SXiaodong Liu }
1857dc32ad5SXiaodong Liu 
1867dc32ad5SXiaodong Liu /*
1877dc32ad5SXiaodong Liu  * buffer to rearrange one segment data from one block.
1887dc32ad5SXiaodong Liu  *
1897dc32ad5SXiaodong Liu  * Layout of new_data:
1907dc32ad5SXiaodong Liu  *  segment
1917dc32ad5SXiaodong Liu  *  -------------------------
1927dc32ad5SXiaodong Liu  *   w0  |  w1  | ... |  w15
1937dc32ad5SXiaodong Liu  *
1947dc32ad5SXiaodong Liu  */
19538e16e11SMarcel Cornu static inline void
transform_input_single(uint32_t * new_data,uint32_t * input,uint32_t segment)19638e16e11SMarcel Cornu transform_input_single(uint32_t *new_data, uint32_t *input, uint32_t segment)
1977dc32ad5SXiaodong Liu {
1987dc32ad5SXiaodong Liu         new_data[16 * segment + 0] = input[16 * 0 + segment];
1997dc32ad5SXiaodong Liu         new_data[16 * segment + 1] = input[16 * 1 + segment];
2007dc32ad5SXiaodong Liu         new_data[16 * segment + 2] = input[16 * 2 + segment];
2017dc32ad5SXiaodong Liu         new_data[16 * segment + 3] = input[16 * 3 + segment];
2027dc32ad5SXiaodong Liu         new_data[16 * segment + 4] = input[16 * 4 + segment];
2037dc32ad5SXiaodong Liu         new_data[16 * segment + 5] = input[16 * 5 + segment];
2047dc32ad5SXiaodong Liu         new_data[16 * segment + 6] = input[16 * 6 + segment];
2057dc32ad5SXiaodong Liu         new_data[16 * segment + 7] = input[16 * 7 + segment];
2067dc32ad5SXiaodong Liu         new_data[16 * segment + 8] = input[16 * 8 + segment];
2077dc32ad5SXiaodong Liu         new_data[16 * segment + 9] = input[16 * 9 + segment];
2087dc32ad5SXiaodong Liu         new_data[16 * segment + 10] = input[16 * 10 + segment];
2097dc32ad5SXiaodong Liu         new_data[16 * segment + 11] = input[16 * 11 + segment];
2107dc32ad5SXiaodong Liu         new_data[16 * segment + 12] = input[16 * 12 + segment];
2117dc32ad5SXiaodong Liu         new_data[16 * segment + 13] = input[16 * 13 + segment];
2127dc32ad5SXiaodong Liu         new_data[16 * segment + 14] = input[16 * 14 + segment];
2137dc32ad5SXiaodong Liu         new_data[16 * segment + 15] = input[16 * 15 + segment];
2147dc32ad5SXiaodong Liu }
2157dc32ad5SXiaodong Liu 
2167dc32ad5SXiaodong Liu // Adapt parameters to sha256_single_for_mh_sha256_ref
2177dc32ad5SXiaodong Liu #define sha256_update_one_seg(data, digest)                                                        \
2187dc32ad5SXiaodong Liu         sha256_single_for_mh_sha256_ref((const uint8_t *) (data), (uint32_t *) (digest))
2197dc32ad5SXiaodong Liu 
2207dc32ad5SXiaodong Liu /*
2217dc32ad5SXiaodong Liu  * buffer to Rearrange all segments data from one block.
2227dc32ad5SXiaodong Liu  *
2237dc32ad5SXiaodong Liu  * Layout of new_data:
2247dc32ad5SXiaodong Liu  *  segment
2257dc32ad5SXiaodong Liu  *  -------------------------
2267dc32ad5SXiaodong Liu  *   seg0:   | w0  |  w1  | ... |  w15
2277dc32ad5SXiaodong Liu  *   seg1:   | w0  |  w1  | ... |  w15
2287dc32ad5SXiaodong Liu  *   seg2:   | w0  |  w1  | ... |  w15
2297dc32ad5SXiaodong Liu  *   ....
2307dc32ad5SXiaodong Liu  *   seg15: | w0  |  w1  | ... |  w15
2317dc32ad5SXiaodong Liu  *
2327dc32ad5SXiaodong Liu  */
23338e16e11SMarcel Cornu static inline void
transform_input(uint32_t * new_data,uint32_t * input,uint32_t block)23438e16e11SMarcel Cornu transform_input(uint32_t *new_data, uint32_t *input, uint32_t block)
2357dc32ad5SXiaodong Liu {
236*15f45959SMarcel Cornu         uint32_t *current_input = input + block * ISAL_MH_SHA256_BLOCK_SIZE / 4;
2377dc32ad5SXiaodong Liu 
2387dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 0);
2397dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 1);
2407dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 2);
2417dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 3);
2427dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 4);
2437dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 5);
2447dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 6);
2457dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 7);
2467dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 8);
2477dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 9);
2487dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 10);
2497dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 11);
2507dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 12);
2517dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 13);
2527dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 14);
2537dc32ad5SXiaodong Liu         transform_input_single(new_data, current_input, 15);
2547dc32ad5SXiaodong Liu }
2557dc32ad5SXiaodong Liu 
2567dc32ad5SXiaodong Liu /*
2577dc32ad5SXiaodong Liu  * buffer to Calculate all segments' digests from one block.
2587dc32ad5SXiaodong Liu  *
2597dc32ad5SXiaodong Liu  * Layout of seg_digest:
2607dc32ad5SXiaodong Liu  *  segment
2617dc32ad5SXiaodong Liu  *  -------------------------
2627dc32ad5SXiaodong Liu  *   seg0:   | H0  |  H1  | ... |  H7
2637dc32ad5SXiaodong Liu  *   seg1:   | H0  |  H1  | ... |  H7
2647dc32ad5SXiaodong Liu  *   seg2:   | H0  |  H1  | ... |  H7
2657dc32ad5SXiaodong Liu  *   ....
2667dc32ad5SXiaodong Liu  *   seg15: | H0  |  H1  | ... |  H7
2677dc32ad5SXiaodong Liu  *
2687dc32ad5SXiaodong Liu  */
26938e16e11SMarcel Cornu static inline void
sha256_update_all_segs(uint32_t * new_data,uint32_t (* mh_sha256_seg_digests)[ISAL_SHA256_DIGEST_WORDS])270*15f45959SMarcel Cornu sha256_update_all_segs(uint32_t *new_data,
271*15f45959SMarcel Cornu                        uint32_t (*mh_sha256_seg_digests)[ISAL_SHA256_DIGEST_WORDS])
2727dc32ad5SXiaodong Liu {
2737dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 0], mh_sha256_seg_digests[0]);
2747dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 1], mh_sha256_seg_digests[1]);
2757dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 2], mh_sha256_seg_digests[2]);
2767dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 3], mh_sha256_seg_digests[3]);
2777dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 4], mh_sha256_seg_digests[4]);
2787dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 5], mh_sha256_seg_digests[5]);
2797dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 6], mh_sha256_seg_digests[6]);
2807dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 7], mh_sha256_seg_digests[7]);
2817dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 8], mh_sha256_seg_digests[8]);
2827dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 9], mh_sha256_seg_digests[9]);
2837dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 10], mh_sha256_seg_digests[10]);
2847dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 11], mh_sha256_seg_digests[11]);
2857dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 12], mh_sha256_seg_digests[12]);
2867dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 13], mh_sha256_seg_digests[13]);
2877dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 14], mh_sha256_seg_digests[14]);
2887dc32ad5SXiaodong Liu         sha256_update_one_seg(&(new_data)[16 * 15], mh_sha256_seg_digests[15]);
2897dc32ad5SXiaodong Liu }
2907dc32ad5SXiaodong Liu 
29138e16e11SMarcel Cornu void
mh_sha256_block_ref(const uint8_t * input_data,uint32_t (* digests)[ISAL_HASH_SEGS],uint8_t frame_buffer[ISAL_MH_SHA256_BLOCK_SIZE],uint32_t num_blocks)29227316f25SMarcel Cornu mh_sha256_block_ref(const uint8_t *input_data, uint32_t (*digests)[ISAL_HASH_SEGS],
293*15f45959SMarcel Cornu                     uint8_t frame_buffer[ISAL_MH_SHA256_BLOCK_SIZE], uint32_t num_blocks)
2947dc32ad5SXiaodong Liu {
2957dc32ad5SXiaodong Liu         uint32_t i, j;
2967dc32ad5SXiaodong Liu         uint32_t *temp_buffer = (uint32_t *) frame_buffer;
297*15f45959SMarcel Cornu         uint32_t(*trans_digests)[ISAL_SHA256_DIGEST_WORDS];
2987dc32ad5SXiaodong Liu 
299*15f45959SMarcel Cornu         trans_digests = (uint32_t(*)[ISAL_SHA256_DIGEST_WORDS]) digests;
3007dc32ad5SXiaodong Liu 
3017dc32ad5SXiaodong Liu         // Re-structure seg_digests from 5*16 to 16*5
30227316f25SMarcel Cornu         for (j = 0; j < ISAL_HASH_SEGS; j++) {
303*15f45959SMarcel Cornu                 for (i = 0; i < ISAL_SHA256_DIGEST_WORDS; i++) {
304*15f45959SMarcel Cornu                         temp_buffer[j * ISAL_SHA256_DIGEST_WORDS + i] = digests[i][j];
3057dc32ad5SXiaodong Liu                 }
3067dc32ad5SXiaodong Liu         }
307*15f45959SMarcel Cornu         memcpy(trans_digests, temp_buffer, 4 * ISAL_SHA256_DIGEST_WORDS * ISAL_HASH_SEGS);
3087dc32ad5SXiaodong Liu 
3097dc32ad5SXiaodong Liu         // Calculate digests for all segments, leveraging sha256 API
3107dc32ad5SXiaodong Liu         for (i = 0; i < num_blocks; i++) {
3117dc32ad5SXiaodong Liu                 transform_input(temp_buffer, (uint32_t *) input_data, i);
3127dc32ad5SXiaodong Liu                 sha256_update_all_segs(temp_buffer, trans_digests);
3137dc32ad5SXiaodong Liu         }
3147dc32ad5SXiaodong Liu 
3157dc32ad5SXiaodong Liu         // Re-structure seg_digests from 16*5 to 5*16
31627316f25SMarcel Cornu         for (j = 0; j < ISAL_HASH_SEGS; j++) {
317*15f45959SMarcel Cornu                 for (i = 0; i < ISAL_SHA256_DIGEST_WORDS; i++) {
31827316f25SMarcel Cornu                         temp_buffer[i * ISAL_HASH_SEGS + j] = trans_digests[j][i];
3197dc32ad5SXiaodong Liu                 }
3207dc32ad5SXiaodong Liu         }
321*15f45959SMarcel Cornu         memcpy(digests, temp_buffer, 4 * ISAL_SHA256_DIGEST_WORDS * ISAL_HASH_SEGS);
3227dc32ad5SXiaodong Liu 
3237dc32ad5SXiaodong Liu         return;
3247dc32ad5SXiaodong Liu }
3257dc32ad5SXiaodong Liu 
32638e16e11SMarcel Cornu void
mh_sha256_tail_ref(uint8_t * partial_buffer,uint32_t total_len,uint32_t (* mh_sha256_segs_digests)[ISAL_HASH_SEGS],uint8_t * frame_buffer,uint32_t digests[ISAL_SHA256_DIGEST_WORDS])32738e16e11SMarcel Cornu mh_sha256_tail_ref(uint8_t *partial_buffer, uint32_t total_len,
32827316f25SMarcel Cornu                    uint32_t (*mh_sha256_segs_digests)[ISAL_HASH_SEGS], uint8_t *frame_buffer,
329*15f45959SMarcel Cornu                    uint32_t digests[ISAL_SHA256_DIGEST_WORDS])
3307dc32ad5SXiaodong Liu {
3317dc32ad5SXiaodong Liu         uint64_t partial_buffer_len, len_in_bit;
3327dc32ad5SXiaodong Liu 
333*15f45959SMarcel Cornu         partial_buffer_len = total_len % ISAL_MH_SHA256_BLOCK_SIZE;
3347dc32ad5SXiaodong Liu 
3357dc32ad5SXiaodong Liu         // Padding the first block
3367dc32ad5SXiaodong Liu         partial_buffer[partial_buffer_len] = 0x80;
3377dc32ad5SXiaodong Liu         partial_buffer_len++;
338*15f45959SMarcel Cornu         memset(partial_buffer + partial_buffer_len, 0,
339*15f45959SMarcel Cornu                ISAL_MH_SHA256_BLOCK_SIZE - partial_buffer_len);
3407dc32ad5SXiaodong Liu 
3417dc32ad5SXiaodong Liu         // Calculate the first block without total_length if padding needs 2 block
342*15f45959SMarcel Cornu         if (partial_buffer_len > (ISAL_MH_SHA256_BLOCK_SIZE - 8)) {
3437dc32ad5SXiaodong Liu                 mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1);
3447dc32ad5SXiaodong Liu                 // Padding the second block
345*15f45959SMarcel Cornu                 memset(partial_buffer, 0, ISAL_MH_SHA256_BLOCK_SIZE);
3467dc32ad5SXiaodong Liu         }
3477dc32ad5SXiaodong Liu         // Padding the block
348e3f7d4fbSUlrich Weigand         len_in_bit = to_be64((uint64_t) total_len * 8);
349*15f45959SMarcel Cornu         *(uint64_t *) (partial_buffer + ISAL_MH_SHA256_BLOCK_SIZE - 8) = len_in_bit;
3507dc32ad5SXiaodong Liu         mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1);
3517dc32ad5SXiaodong Liu 
3527dc32ad5SXiaodong Liu         // Calculate multi-hash SHA256 digests (segment digests as input message)
3537dc32ad5SXiaodong Liu         sha256_for_mh_sha256_ref((uint8_t *) mh_sha256_segs_digests, digests,
354*15f45959SMarcel Cornu                                  4 * ISAL_SHA256_DIGEST_WORDS * ISAL_HASH_SEGS);
3557dc32ad5SXiaodong Liu 
3567dc32ad5SXiaodong Liu         return;
3577dc32ad5SXiaodong Liu }
3587dc32ad5SXiaodong Liu 
35938e16e11SMarcel Cornu void
mh_sha256_ref(const void * buffer,uint32_t len,uint32_t * mh_sha256_digest)36038e16e11SMarcel Cornu mh_sha256_ref(const void *buffer, uint32_t len, uint32_t *mh_sha256_digest)
3617dc32ad5SXiaodong Liu {
3627dc32ad5SXiaodong Liu         uint64_t total_len;
363*15f45959SMarcel Cornu         uint32_t num_blocks, mh_sha256_segs_digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS];
364*15f45959SMarcel Cornu         uint8_t frame_buffer[ISAL_MH_SHA256_BLOCK_SIZE];
365*15f45959SMarcel Cornu         uint8_t partial_block_buffer[ISAL_MH_SHA256_BLOCK_SIZE * 2];
366*15f45959SMarcel Cornu         uint32_t mh_sha256_hash_dword[ISAL_SHA256_DIGEST_WORDS];
3677dc32ad5SXiaodong Liu         uint32_t i;
3687dc32ad5SXiaodong Liu         const uint8_t *input_data = (const uint8_t *) buffer;
3697dc32ad5SXiaodong Liu 
3707dc32ad5SXiaodong Liu         /* Initialize digests of all segments */
37127316f25SMarcel Cornu         for (i = 0; i < ISAL_HASH_SEGS; i++) {
3727dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[0][i] = MH_SHA256_H0;
3737dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[1][i] = MH_SHA256_H1;
3747dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[2][i] = MH_SHA256_H2;
3757dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[3][i] = MH_SHA256_H3;
3767dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[4][i] = MH_SHA256_H4;
3777dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[5][i] = MH_SHA256_H5;
3787dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[6][i] = MH_SHA256_H6;
3797dc32ad5SXiaodong Liu                 mh_sha256_segs_digests[7][i] = MH_SHA256_H7;
3807dc32ad5SXiaodong Liu         }
3817dc32ad5SXiaodong Liu 
3827dc32ad5SXiaodong Liu         total_len = len;
3837dc32ad5SXiaodong Liu 
3847dc32ad5SXiaodong Liu         // Calculate blocks
385*15f45959SMarcel Cornu         num_blocks = len / ISAL_MH_SHA256_BLOCK_SIZE;
3867dc32ad5SXiaodong Liu         if (num_blocks > 0) {
3877dc32ad5SXiaodong Liu                 // do num_blocks process
38838e16e11SMarcel Cornu                 mh_sha256_block_ref(input_data, mh_sha256_segs_digests, frame_buffer, num_blocks);
389*15f45959SMarcel Cornu                 len -= num_blocks * ISAL_MH_SHA256_BLOCK_SIZE;
390*15f45959SMarcel Cornu                 input_data += num_blocks * ISAL_MH_SHA256_BLOCK_SIZE;
3917dc32ad5SXiaodong Liu         }
3927dc32ad5SXiaodong Liu         // Store the partial block
3937dc32ad5SXiaodong Liu         if (len != 0) {
3947dc32ad5SXiaodong Liu                 memcpy(partial_block_buffer, input_data, len);
3957dc32ad5SXiaodong Liu         }
3967dc32ad5SXiaodong Liu 
3977dc32ad5SXiaodong Liu         /* Finalize */
398122c1779SMarcel Cornu         mh_sha256_tail_ref(partial_block_buffer, (uint32_t) total_len, mh_sha256_segs_digests,
399122c1779SMarcel Cornu                            frame_buffer, mh_sha256_hash_dword);
4007dc32ad5SXiaodong Liu 
4017dc32ad5SXiaodong Liu         // Output the digests of mh_sha256
4027dc32ad5SXiaodong Liu         if (mh_sha256_digest != NULL) {
4037dc32ad5SXiaodong Liu                 mh_sha256_digest[0] = mh_sha256_hash_dword[0];
4047dc32ad5SXiaodong Liu                 mh_sha256_digest[1] = mh_sha256_hash_dword[1];
4057dc32ad5SXiaodong Liu                 mh_sha256_digest[2] = mh_sha256_hash_dword[2];
4067dc32ad5SXiaodong Liu                 mh_sha256_digest[3] = mh_sha256_hash_dword[3];
4077dc32ad5SXiaodong Liu                 mh_sha256_digest[4] = mh_sha256_hash_dword[4];
4087dc32ad5SXiaodong Liu                 mh_sha256_digest[5] = mh_sha256_hash_dword[5];
4097dc32ad5SXiaodong Liu                 mh_sha256_digest[6] = mh_sha256_hash_dword[6];
4107dc32ad5SXiaodong Liu                 mh_sha256_digest[7] = mh_sha256_hash_dword[7];
4117dc32ad5SXiaodong Liu         }
4127dc32ad5SXiaodong Liu 
4137dc32ad5SXiaodong Liu         return;
4147dc32ad5SXiaodong Liu }
415