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