1 /********************************************************************** 2 Copyright(c) 2011-2017 Intel Corporation All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions 6 are met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above copyright 10 notice, this list of conditions and the following disclaimer in 11 the documentation and/or other materials provided with the 12 distribution. 13 * Neither the name of Intel Corporation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 **********************************************************************/ 29 30 #include "mh_sha256_internal.h" 31 #include <string.h> 32 33 //////////////////////////////////////////////////////////////////////// 34 //////////////////////////////////////////////////////////////////////// 35 // Base multi-hash SHA256 Functions 36 //////////////////////////////////////////////////////////////////////// 37 //////////////////////////////////////////////////////////////////////// 38 // store_w is only used for step 0 ~ 15 39 #define store_w(s, i, w, ww) (w[i][s] = to_be32(ww[i*HASH_SEGS+s])) 40 #define Ws(x, s) w[(x) & 15][s] 41 // update_w is used for step > 15 42 #define update_w(s, i, w) \ 43 Ws(i, s) = Ws(i-16, s) + S0(Ws(i-15, s)) + Ws(i-7, s) + S1(Ws(i-2, s)) 44 #define update_t2(s, a, b, c) t2[s] = s0(a[s]) + maj(a[s],b[s],c[s]) 45 #define update_t1(s, h, e, f, g, i, k) \ 46 t1[s] = h[s] + s1(e[s]) + ch(e[s],f[s],g[s]) + k + Ws(i, s); 47 #define update_d(s) d[s] += t1[s] 48 #define update_h(s) h[s] = t1[s] + t2[s] 49 50 // s is a iterator 51 #define STORE_W(s, i, w, ww) \ 52 for(s = 0; s < HASH_SEGS; s++) \ 53 store_w(s, i, w, ww); 54 #define UPDATE_W(s, i, w) \ 55 for(s = 0; s < HASH_SEGS; s++) \ 56 update_w(s, i, w); 57 #define UPDATE_T2(s, a, b, c) \ 58 for(s = 0; s < HASH_SEGS; s++) \ 59 update_t2(s, a, b, c); 60 #define UPDATE_T1(s, h, e, f, g, i, k) \ 61 for(s = 0; s < HASH_SEGS; s++) \ 62 update_t1(s, h, e, f, g, i, k); 63 #define UPDATE_D(s) \ 64 for(s = 0; s < HASH_SEGS; s++) \ 65 update_d(s); 66 #define UPDATE_H(s) \ 67 for(s = 0; s < HASH_SEGS; s++) \ 68 update_h(s); 69 70 static inline void step(int i, uint32_t * a, uint32_t * b, uint32_t * c, 71 uint32_t * d, uint32_t * e, uint32_t * f, 72 uint32_t * g, uint32_t * h, uint32_t k, 73 uint32_t * t1, uint32_t * t2, uint32_t(*w)[HASH_SEGS], uint32_t * ww) 74 { 75 uint8_t s; 76 if (i < 16) { 77 STORE_W(s, i, w, ww); 78 } else { 79 UPDATE_W(s, i, w); 80 } 81 UPDATE_T2(s, a, b, c); 82 UPDATE_T1(s, h, e, f, g, i, k); 83 UPDATE_D(s); 84 UPDATE_H(s); 85 } 86 87 static inline void init_abcdefgh(uint32_t * xx, uint32_t n, 88 uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS]) 89 { 90 uint8_t s; 91 for (s = 0; s < HASH_SEGS; s++) 92 xx[s] = digests[n][s]; 93 } 94 95 static inline void add_abcdefgh(uint32_t * xx, uint32_t n, 96 uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS]) 97 { 98 uint8_t s; 99 for (s = 0; s < HASH_SEGS; s++) 100 digests[n][s] += xx[s]; 101 } 102 103 /* 104 * API to perform 0-64 steps of the multi-hash algorithm for 105 * a single block of data. The caller is responsible for ensuring 106 * a full block of data input. 107 * 108 * Argument: 109 * input - the pointer to the data 110 * digest - the space to hold the digests for all segments. 111 * 112 * Return: 113 * N/A 114 */ 115 void mh_sha256_single(const uint8_t * input, uint32_t(*digests)[HASH_SEGS], 116 uint8_t * frame_buffer) 117 { 118 uint8_t i; 119 uint32_t aa[HASH_SEGS], bb[HASH_SEGS], cc[HASH_SEGS], dd[HASH_SEGS]; 120 uint32_t ee[HASH_SEGS], ff[HASH_SEGS], gg[HASH_SEGS], hh[HASH_SEGS]; 121 uint32_t t1[HASH_SEGS], t2[HASH_SEGS]; 122 uint32_t *ww = (uint32_t *) input; 123 uint32_t(*w)[HASH_SEGS]; 124 125 const static uint32_t k[64] = { 126 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 127 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 128 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 129 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 130 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 131 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 132 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 133 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 134 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 135 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 136 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 137 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 138 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 139 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 140 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 141 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 142 }; 143 144 w = (uint32_t(*)[HASH_SEGS]) frame_buffer; 145 146 init_abcdefgh(aa, 0, digests); 147 init_abcdefgh(bb, 1, digests); 148 init_abcdefgh(cc, 2, digests); 149 init_abcdefgh(dd, 3, digests); 150 init_abcdefgh(ee, 4, digests); 151 init_abcdefgh(ff, 5, digests); 152 init_abcdefgh(gg, 6, digests); 153 init_abcdefgh(hh, 7, digests); 154 155 for (i = 0; i < 64; i += 8) { 156 step(i, aa, bb, cc, dd, ee, ff, gg, hh, k[i], t1, t2, w, ww); 157 step(i + 1, hh, aa, bb, cc, dd, ee, ff, gg, k[i + 1], t1, t2, w, ww); 158 step(i + 2, gg, hh, aa, bb, cc, dd, ee, ff, k[i + 2], t1, t2, w, ww); 159 step(i + 3, ff, gg, hh, aa, bb, cc, dd, ee, k[i + 3], t1, t2, w, ww); 160 step(i + 4, ee, ff, gg, hh, aa, bb, cc, dd, k[i + 4], t1, t2, w, ww); 161 step(i + 5, dd, ee, ff, gg, hh, aa, bb, cc, k[i + 5], t1, t2, w, ww); 162 step(i + 6, cc, dd, ee, ff, gg, hh, aa, bb, k[i + 6], t1, t2, w, ww); 163 step(i + 7, bb, cc, dd, ee, ff, gg, hh, aa, k[i + 7], t1, t2, w, ww); 164 } 165 166 add_abcdefgh(aa, 0, digests); 167 add_abcdefgh(bb, 1, digests); 168 add_abcdefgh(cc, 2, digests); 169 add_abcdefgh(dd, 3, digests); 170 add_abcdefgh(ee, 4, digests); 171 add_abcdefgh(ff, 5, digests); 172 add_abcdefgh(gg, 6, digests); 173 add_abcdefgh(hh, 7, digests); 174 } 175 176 void mh_sha256_block_base(const uint8_t * input_data, 177 uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS], 178 uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE], uint32_t num_blocks) 179 { 180 uint32_t i; 181 182 for (i = 0; i < num_blocks; i++) { 183 mh_sha256_single(input_data, digests, frame_buffer); 184 input_data += MH_SHA256_BLOCK_SIZE; 185 } 186 187 return; 188 } 189