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 "mh_sha256_internal.h"
317dc32ad5SXiaodong Liu #include <string.h>
327dc32ad5SXiaodong Liu
337dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
347dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
357dc32ad5SXiaodong Liu // Base multi-hash SHA256 Functions
367dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
377dc32ad5SXiaodong Liu ////////////////////////////////////////////////////////////////////////
387dc32ad5SXiaodong Liu // store_w is only used for step 0 ~ 15
3927316f25SMarcel Cornu #define store_w(s, i, w, ww) (w[i][s] = to_be32(ww[i * ISAL_HASH_SEGS + s]))
407dc32ad5SXiaodong Liu #define Ws(x, s) w[(x) & 15][s]
417dc32ad5SXiaodong Liu // update_w is used for step > 15
427dc32ad5SXiaodong Liu #define update_w(s, i, w) \
437dc32ad5SXiaodong Liu Ws(i, s) = Ws(i - 16, s) + S0(Ws(i - 15, s)) + Ws(i - 7, s) + S1(Ws(i - 2, s))
447dc32ad5SXiaodong Liu #define update_t2(s, a, b, c) t2[s] = s0(a[s]) + maj(a[s], b[s], c[s])
457dc32ad5SXiaodong Liu #define update_t1(s, h, e, f, g, i, k) \
467dc32ad5SXiaodong Liu t1[s] = h[s] + s1(e[s]) + ch(e[s], f[s], g[s]) + k + Ws(i, s);
477dc32ad5SXiaodong Liu #define update_d(s) d[s] += t1[s]
487dc32ad5SXiaodong Liu #define update_h(s) h[s] = t1[s] + t2[s]
497dc32ad5SXiaodong Liu
507dc32ad5SXiaodong Liu // s is a iterator
517dc32ad5SXiaodong Liu #define STORE_W(s, i, w, ww) \
5227316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
537dc32ad5SXiaodong Liu store_w(s, i, w, ww);
547dc32ad5SXiaodong Liu #define UPDATE_W(s, i, w) \
5527316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
567dc32ad5SXiaodong Liu update_w(s, i, w);
577dc32ad5SXiaodong Liu #define UPDATE_T2(s, a, b, c) \
5827316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
597dc32ad5SXiaodong Liu update_t2(s, a, b, c);
607dc32ad5SXiaodong Liu #define UPDATE_T1(s, h, e, f, g, i, k) \
6127316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
627dc32ad5SXiaodong Liu update_t1(s, h, e, f, g, i, k);
637dc32ad5SXiaodong Liu #define UPDATE_D(s) \
6427316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
657dc32ad5SXiaodong Liu update_d(s);
667dc32ad5SXiaodong Liu #define UPDATE_H(s) \
6727316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++) \
687dc32ad5SXiaodong Liu update_h(s);
697dc32ad5SXiaodong Liu
7038e16e11SMarcel Cornu static inline void
step(int i,uint32_t * a,uint32_t * b,uint32_t * c,uint32_t * d,uint32_t * e,uint32_t * f,uint32_t * g,uint32_t * h,uint32_t k,uint32_t * t1,uint32_t * t2,uint32_t (* w)[ISAL_HASH_SEGS],uint32_t * ww)7138e16e11SMarcel Cornu step(int i, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, uint32_t *f,
7227316f25SMarcel Cornu uint32_t *g, uint32_t *h, uint32_t k, uint32_t *t1, uint32_t *t2,
7327316f25SMarcel Cornu uint32_t (*w)[ISAL_HASH_SEGS], uint32_t *ww)
747dc32ad5SXiaodong Liu {
757dc32ad5SXiaodong Liu uint8_t s;
767dc32ad5SXiaodong Liu if (i < 16) {
777dc32ad5SXiaodong Liu STORE_W(s, i, w, ww);
787dc32ad5SXiaodong Liu } else {
797dc32ad5SXiaodong Liu UPDATE_W(s, i, w);
807dc32ad5SXiaodong Liu }
817dc32ad5SXiaodong Liu UPDATE_T2(s, a, b, c);
827dc32ad5SXiaodong Liu UPDATE_T1(s, h, e, f, g, i, k);
837dc32ad5SXiaodong Liu UPDATE_D(s);
847dc32ad5SXiaodong Liu UPDATE_H(s);
857dc32ad5SXiaodong Liu }
867dc32ad5SXiaodong Liu
8738e16e11SMarcel Cornu static inline void
init_abcdefgh(uint32_t * xx,uint32_t n,uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS])8815f45959SMarcel Cornu init_abcdefgh(uint32_t *xx, uint32_t n, uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS])
897dc32ad5SXiaodong Liu {
907dc32ad5SXiaodong Liu uint8_t s;
9127316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++)
927dc32ad5SXiaodong Liu xx[s] = digests[n][s];
937dc32ad5SXiaodong Liu }
947dc32ad5SXiaodong Liu
9538e16e11SMarcel Cornu static inline void
add_abcdefgh(uint32_t * xx,uint32_t n,uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS])9615f45959SMarcel Cornu add_abcdefgh(uint32_t *xx, uint32_t n, uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS])
977dc32ad5SXiaodong Liu {
987dc32ad5SXiaodong Liu uint8_t s;
9927316f25SMarcel Cornu for (s = 0; s < ISAL_HASH_SEGS; s++)
1007dc32ad5SXiaodong Liu digests[n][s] += xx[s];
1017dc32ad5SXiaodong Liu }
1027dc32ad5SXiaodong Liu
1037dc32ad5SXiaodong Liu /*
1047dc32ad5SXiaodong Liu * API to perform 0-64 steps of the multi-hash algorithm for
1057dc32ad5SXiaodong Liu * a single block of data. The caller is responsible for ensuring
1067dc32ad5SXiaodong Liu * a full block of data input.
1077dc32ad5SXiaodong Liu *
1087dc32ad5SXiaodong Liu * Argument:
1097dc32ad5SXiaodong Liu * input - the pointer to the data
1107dc32ad5SXiaodong Liu * digest - the space to hold the digests for all segments.
1117dc32ad5SXiaodong Liu *
1127dc32ad5SXiaodong Liu * Return:
1137dc32ad5SXiaodong Liu * N/A
1147dc32ad5SXiaodong Liu */
11538e16e11SMarcel Cornu void
mh_sha256_single(const uint8_t * input,uint32_t (* digests)[ISAL_HASH_SEGS],uint8_t * frame_buffer)11627316f25SMarcel Cornu mh_sha256_single(const uint8_t *input, uint32_t (*digests)[ISAL_HASH_SEGS], uint8_t *frame_buffer)
1177dc32ad5SXiaodong Liu {
1187dc32ad5SXiaodong Liu uint8_t i;
11927316f25SMarcel Cornu uint32_t aa[ISAL_HASH_SEGS], bb[ISAL_HASH_SEGS], cc[ISAL_HASH_SEGS], dd[ISAL_HASH_SEGS];
12027316f25SMarcel Cornu uint32_t ee[ISAL_HASH_SEGS], ff[ISAL_HASH_SEGS], gg[ISAL_HASH_SEGS], hh[ISAL_HASH_SEGS];
12127316f25SMarcel Cornu uint32_t t1[ISAL_HASH_SEGS], t2[ISAL_HASH_SEGS];
1227dc32ad5SXiaodong Liu uint32_t *ww = (uint32_t *) input;
12327316f25SMarcel Cornu uint32_t(*w)[ISAL_HASH_SEGS];
1247dc32ad5SXiaodong Liu
1257dc32ad5SXiaodong Liu const static uint32_t k[64] = {
12638e16e11SMarcel Cornu 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
12738e16e11SMarcel Cornu 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
12838e16e11SMarcel Cornu 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
12938e16e11SMarcel Cornu 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
13038e16e11SMarcel Cornu 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
13138e16e11SMarcel Cornu 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
13238e16e11SMarcel Cornu 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
13338e16e11SMarcel Cornu 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
13438e16e11SMarcel Cornu 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
13538e16e11SMarcel Cornu 0xc67178f2
1367dc32ad5SXiaodong Liu };
1377dc32ad5SXiaodong Liu
13827316f25SMarcel Cornu w = (uint32_t(*)[ISAL_HASH_SEGS]) frame_buffer;
1397dc32ad5SXiaodong Liu
1407dc32ad5SXiaodong Liu init_abcdefgh(aa, 0, digests);
1417dc32ad5SXiaodong Liu init_abcdefgh(bb, 1, digests);
1427dc32ad5SXiaodong Liu init_abcdefgh(cc, 2, digests);
1437dc32ad5SXiaodong Liu init_abcdefgh(dd, 3, digests);
1447dc32ad5SXiaodong Liu init_abcdefgh(ee, 4, digests);
1457dc32ad5SXiaodong Liu init_abcdefgh(ff, 5, digests);
1467dc32ad5SXiaodong Liu init_abcdefgh(gg, 6, digests);
1477dc32ad5SXiaodong Liu init_abcdefgh(hh, 7, digests);
1487dc32ad5SXiaodong Liu
1497dc32ad5SXiaodong Liu for (i = 0; i < 64; i += 8) {
1507dc32ad5SXiaodong Liu step(i, aa, bb, cc, dd, ee, ff, gg, hh, k[i], t1, t2, w, ww);
1517dc32ad5SXiaodong Liu step(i + 1, hh, aa, bb, cc, dd, ee, ff, gg, k[i + 1], t1, t2, w, ww);
1527dc32ad5SXiaodong Liu step(i + 2, gg, hh, aa, bb, cc, dd, ee, ff, k[i + 2], t1, t2, w, ww);
1537dc32ad5SXiaodong Liu step(i + 3, ff, gg, hh, aa, bb, cc, dd, ee, k[i + 3], t1, t2, w, ww);
1547dc32ad5SXiaodong Liu step(i + 4, ee, ff, gg, hh, aa, bb, cc, dd, k[i + 4], t1, t2, w, ww);
1557dc32ad5SXiaodong Liu step(i + 5, dd, ee, ff, gg, hh, aa, bb, cc, k[i + 5], t1, t2, w, ww);
1567dc32ad5SXiaodong Liu step(i + 6, cc, dd, ee, ff, gg, hh, aa, bb, k[i + 6], t1, t2, w, ww);
1577dc32ad5SXiaodong Liu step(i + 7, bb, cc, dd, ee, ff, gg, hh, aa, k[i + 7], t1, t2, w, ww);
1587dc32ad5SXiaodong Liu }
1597dc32ad5SXiaodong Liu
1607dc32ad5SXiaodong Liu add_abcdefgh(aa, 0, digests);
1617dc32ad5SXiaodong Liu add_abcdefgh(bb, 1, digests);
1627dc32ad5SXiaodong Liu add_abcdefgh(cc, 2, digests);
1637dc32ad5SXiaodong Liu add_abcdefgh(dd, 3, digests);
1647dc32ad5SXiaodong Liu add_abcdefgh(ee, 4, digests);
1657dc32ad5SXiaodong Liu add_abcdefgh(ff, 5, digests);
1667dc32ad5SXiaodong Liu add_abcdefgh(gg, 6, digests);
1677dc32ad5SXiaodong Liu add_abcdefgh(hh, 7, digests);
1687dc32ad5SXiaodong Liu }
1697dc32ad5SXiaodong Liu
17038e16e11SMarcel Cornu void
_mh_sha256_block_base(const uint8_t * input_data,uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS],uint8_t frame_buffer[ISAL_MH_SHA256_BLOCK_SIZE],uint32_t num_blocks)171*a922b2ebSMarcel Cornu _mh_sha256_block_base(const uint8_t *input_data,
17215f45959SMarcel Cornu uint32_t digests[ISAL_SHA256_DIGEST_WORDS][ISAL_HASH_SEGS],
17315f45959SMarcel Cornu uint8_t frame_buffer[ISAL_MH_SHA256_BLOCK_SIZE], uint32_t num_blocks)
1747dc32ad5SXiaodong Liu {
1757dc32ad5SXiaodong Liu uint32_t i;
1767dc32ad5SXiaodong Liu
1777dc32ad5SXiaodong Liu for (i = 0; i < num_blocks; i++) {
1787dc32ad5SXiaodong Liu mh_sha256_single(input_data, digests, frame_buffer);
17915f45959SMarcel Cornu input_data += ISAL_MH_SHA256_BLOCK_SIZE;
1807dc32ad5SXiaodong Liu }
1817dc32ad5SXiaodong Liu
1827dc32ad5SXiaodong Liu return;
1837dc32ad5SXiaodong Liu }
184