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 <string.h> 31 #include "mh_sha256_internal.h" 32 33 //////////////////////////////////////////////////////////////////////// 34 //////////////////////////////////////////////////////////////////////// 35 // Macros and sub-functions which already exist in source code file 36 // (sha256_for_mh_sha256.c) is part of ISA-L library as internal functions. 37 // The reason why writing them twice is the linking issue caused by 38 // mh_sha256_ref(). mh_sha256_ref() needs these macros and sub-functions 39 // without linking ISA-L library. So mh_sha256_ref() includes them in 40 // order to contain essential sub-functions in its own object file. 41 //////////////////////////////////////////////////////////////////////// 42 //////////////////////////////////////////////////////////////////////// 43 44 #define W(x) w[(x) & 15] 45 46 #define step(i,a,b,c,d,e,f,g,h,k) \ 47 if (i<16) W(i) = to_be32(ww[i]); \ 48 else \ 49 W(i) = W(i-16) + S0(W(i-15)) + W(i-7) + S1(W(i-2)); \ 50 t2 = s0(a) + maj(a,b,c); \ 51 t1 = h + s1(e) + ch(e,f,g) + k + W(i); \ 52 d += t1; \ 53 h = t1 + t2; 54 55 void sha256_single_for_mh_sha256_ref(const uint8_t * data, uint32_t digest[]) 56 { 57 uint32_t a, b, c, d, e, f, g, h, t1, t2; 58 uint32_t w[16]; 59 uint32_t *ww = (uint32_t *) data; 60 61 a = digest[0]; 62 b = digest[1]; 63 c = digest[2]; 64 d = digest[3]; 65 e = digest[4]; 66 f = digest[5]; 67 g = digest[6]; 68 h = digest[7]; 69 70 step(0, a, b, c, d, e, f, g, h, 0x428a2f98); 71 step(1, h, a, b, c, d, e, f, g, 0x71374491); 72 step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcf); 73 step(3, f, g, h, a, b, c, d, e, 0xe9b5dba5); 74 step(4, e, f, g, h, a, b, c, d, 0x3956c25b); 75 step(5, d, e, f, g, h, a, b, c, 0x59f111f1); 76 step(6, c, d, e, f, g, h, a, b, 0x923f82a4); 77 step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5); 78 step(8, a, b, c, d, e, f, g, h, 0xd807aa98); 79 step(9, h, a, b, c, d, e, f, g, 0x12835b01); 80 step(10, g, h, a, b, c, d, e, f, 0x243185be); 81 step(11, f, g, h, a, b, c, d, e, 0x550c7dc3); 82 step(12, e, f, g, h, a, b, c, d, 0x72be5d74); 83 step(13, d, e, f, g, h, a, b, c, 0x80deb1fe); 84 step(14, c, d, e, f, g, h, a, b, 0x9bdc06a7); 85 step(15, b, c, d, e, f, g, h, a, 0xc19bf174); 86 step(16, a, b, c, d, e, f, g, h, 0xe49b69c1); 87 step(17, h, a, b, c, d, e, f, g, 0xefbe4786); 88 step(18, g, h, a, b, c, d, e, f, 0x0fc19dc6); 89 step(19, f, g, h, a, b, c, d, e, 0x240ca1cc); 90 step(20, e, f, g, h, a, b, c, d, 0x2de92c6f); 91 step(21, d, e, f, g, h, a, b, c, 0x4a7484aa); 92 step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dc); 93 step(23, b, c, d, e, f, g, h, a, 0x76f988da); 94 step(24, a, b, c, d, e, f, g, h, 0x983e5152); 95 step(25, h, a, b, c, d, e, f, g, 0xa831c66d); 96 step(26, g, h, a, b, c, d, e, f, 0xb00327c8); 97 step(27, f, g, h, a, b, c, d, e, 0xbf597fc7); 98 step(28, e, f, g, h, a, b, c, d, 0xc6e00bf3); 99 step(29, d, e, f, g, h, a, b, c, 0xd5a79147); 100 step(30, c, d, e, f, g, h, a, b, 0x06ca6351); 101 step(31, b, c, d, e, f, g, h, a, 0x14292967); 102 step(32, a, b, c, d, e, f, g, h, 0x27b70a85); 103 step(33, h, a, b, c, d, e, f, g, 0x2e1b2138); 104 step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc); 105 step(35, f, g, h, a, b, c, d, e, 0x53380d13); 106 step(36, e, f, g, h, a, b, c, d, 0x650a7354); 107 step(37, d, e, f, g, h, a, b, c, 0x766a0abb); 108 step(38, c, d, e, f, g, h, a, b, 0x81c2c92e); 109 step(39, b, c, d, e, f, g, h, a, 0x92722c85); 110 step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a1); 111 step(41, h, a, b, c, d, e, f, g, 0xa81a664b); 112 step(42, g, h, a, b, c, d, e, f, 0xc24b8b70); 113 step(43, f, g, h, a, b, c, d, e, 0xc76c51a3); 114 step(44, e, f, g, h, a, b, c, d, 0xd192e819); 115 step(45, d, e, f, g, h, a, b, c, 0xd6990624); 116 step(46, c, d, e, f, g, h, a, b, 0xf40e3585); 117 step(47, b, c, d, e, f, g, h, a, 0x106aa070); 118 step(48, a, b, c, d, e, f, g, h, 0x19a4c116); 119 step(49, h, a, b, c, d, e, f, g, 0x1e376c08); 120 step(50, g, h, a, b, c, d, e, f, 0x2748774c); 121 step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5); 122 step(52, e, f, g, h, a, b, c, d, 0x391c0cb3); 123 step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4a); 124 step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f); 125 step(55, b, c, d, e, f, g, h, a, 0x682e6ff3); 126 step(56, a, b, c, d, e, f, g, h, 0x748f82ee); 127 step(57, h, a, b, c, d, e, f, g, 0x78a5636f); 128 step(58, g, h, a, b, c, d, e, f, 0x84c87814); 129 step(59, f, g, h, a, b, c, d, e, 0x8cc70208); 130 step(60, e, f, g, h, a, b, c, d, 0x90befffa); 131 step(61, d, e, f, g, h, a, b, c, 0xa4506ceb); 132 step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7); 133 step(63, b, c, d, e, f, g, h, a, 0xc67178f2); 134 135 digest[0] += a; 136 digest[1] += b; 137 digest[2] += c; 138 digest[3] += d; 139 digest[4] += e; 140 digest[5] += f; 141 digest[6] += g; 142 digest[7] += h; 143 } 144 145 void sha256_for_mh_sha256_ref(const uint8_t * input_data, uint32_t * digest, 146 const uint32_t len) 147 { 148 uint32_t i, j; 149 uint8_t buf[2 * SHA256_BLOCK_SIZE]; 150 151 digest[0] = MH_SHA256_H0; 152 digest[1] = MH_SHA256_H1; 153 digest[2] = MH_SHA256_H2; 154 digest[3] = MH_SHA256_H3; 155 digest[4] = MH_SHA256_H4; 156 digest[5] = MH_SHA256_H5; 157 digest[6] = MH_SHA256_H6; 158 digest[7] = MH_SHA256_H7; 159 160 i = len; 161 while (i >= SHA256_BLOCK_SIZE) { 162 sha256_single_for_mh_sha256_ref(input_data, digest); 163 input_data += SHA256_BLOCK_SIZE; 164 i -= SHA256_BLOCK_SIZE; 165 } 166 167 memcpy(buf, input_data, i); 168 buf[i++] = 0x80; 169 for (j = i; j < ((2 * SHA256_BLOCK_SIZE) - 8); j++) 170 buf[j] = 0; 171 172 if (i > SHA256_BLOCK_SIZE - 8) 173 i = 2 * SHA256_BLOCK_SIZE; 174 else 175 i = SHA256_BLOCK_SIZE; 176 177 *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) len * 8); 178 179 sha256_single_for_mh_sha256_ref(buf, digest); 180 if (i == (2 * SHA256_BLOCK_SIZE)) 181 sha256_single_for_mh_sha256_ref(buf + SHA256_BLOCK_SIZE, digest); 182 } 183 184 /* 185 * buffer to rearrange one segment data from one block. 186 * 187 * Layout of new_data: 188 * segment 189 * ------------------------- 190 * w0 | w1 | ... | w15 191 * 192 */ 193 static inline void transform_input_single(uint32_t * new_data, uint32_t * input, 194 uint32_t segment) 195 { 196 new_data[16 * segment + 0] = input[16 * 0 + segment]; 197 new_data[16 * segment + 1] = input[16 * 1 + segment]; 198 new_data[16 * segment + 2] = input[16 * 2 + segment]; 199 new_data[16 * segment + 3] = input[16 * 3 + segment]; 200 new_data[16 * segment + 4] = input[16 * 4 + segment]; 201 new_data[16 * segment + 5] = input[16 * 5 + segment]; 202 new_data[16 * segment + 6] = input[16 * 6 + segment]; 203 new_data[16 * segment + 7] = input[16 * 7 + segment]; 204 new_data[16 * segment + 8] = input[16 * 8 + segment]; 205 new_data[16 * segment + 9] = input[16 * 9 + segment]; 206 new_data[16 * segment + 10] = input[16 * 10 + segment]; 207 new_data[16 * segment + 11] = input[16 * 11 + segment]; 208 new_data[16 * segment + 12] = input[16 * 12 + segment]; 209 new_data[16 * segment + 13] = input[16 * 13 + segment]; 210 new_data[16 * segment + 14] = input[16 * 14 + segment]; 211 new_data[16 * segment + 15] = input[16 * 15 + segment]; 212 } 213 214 // Adapt parameters to sha256_single_for_mh_sha256_ref 215 #define sha256_update_one_seg(data, digest) \ 216 sha256_single_for_mh_sha256_ref((const uint8_t *)(data), (uint32_t *)(digest)) 217 218 /* 219 * buffer to Rearrange all segments data from one block. 220 * 221 * Layout of new_data: 222 * segment 223 * ------------------------- 224 * seg0: | w0 | w1 | ... | w15 225 * seg1: | w0 | w1 | ... | w15 226 * seg2: | w0 | w1 | ... | w15 227 * .... 228 * seg15: | w0 | w1 | ... | w15 229 * 230 */ 231 static inline void transform_input(uint32_t * new_data, uint32_t * input, uint32_t block) 232 { 233 uint32_t *current_input = input + block * MH_SHA256_BLOCK_SIZE / 4; 234 235 transform_input_single(new_data, current_input, 0); 236 transform_input_single(new_data, current_input, 1); 237 transform_input_single(new_data, current_input, 2); 238 transform_input_single(new_data, current_input, 3); 239 transform_input_single(new_data, current_input, 4); 240 transform_input_single(new_data, current_input, 5); 241 transform_input_single(new_data, current_input, 6); 242 transform_input_single(new_data, current_input, 7); 243 transform_input_single(new_data, current_input, 8); 244 transform_input_single(new_data, current_input, 9); 245 transform_input_single(new_data, current_input, 10); 246 transform_input_single(new_data, current_input, 11); 247 transform_input_single(new_data, current_input, 12); 248 transform_input_single(new_data, current_input, 13); 249 transform_input_single(new_data, current_input, 14); 250 transform_input_single(new_data, current_input, 15); 251 252 } 253 254 /* 255 * buffer to Calculate all segments' digests from one block. 256 * 257 * Layout of seg_digest: 258 * segment 259 * ------------------------- 260 * seg0: | H0 | H1 | ... | H7 261 * seg1: | H0 | H1 | ... | H7 262 * seg2: | H0 | H1 | ... | H7 263 * .... 264 * seg15: | H0 | H1 | ... | H7 265 * 266 */ 267 static inline void sha256_update_all_segs(uint32_t * new_data, uint32_t(*mh_sha256_seg_digests) 268 [SHA256_DIGEST_WORDS]) 269 { 270 sha256_update_one_seg(&(new_data)[16 * 0], mh_sha256_seg_digests[0]); 271 sha256_update_one_seg(&(new_data)[16 * 1], mh_sha256_seg_digests[1]); 272 sha256_update_one_seg(&(new_data)[16 * 2], mh_sha256_seg_digests[2]); 273 sha256_update_one_seg(&(new_data)[16 * 3], mh_sha256_seg_digests[3]); 274 sha256_update_one_seg(&(new_data)[16 * 4], mh_sha256_seg_digests[4]); 275 sha256_update_one_seg(&(new_data)[16 * 5], mh_sha256_seg_digests[5]); 276 sha256_update_one_seg(&(new_data)[16 * 6], mh_sha256_seg_digests[6]); 277 sha256_update_one_seg(&(new_data)[16 * 7], mh_sha256_seg_digests[7]); 278 sha256_update_one_seg(&(new_data)[16 * 8], mh_sha256_seg_digests[8]); 279 sha256_update_one_seg(&(new_data)[16 * 9], mh_sha256_seg_digests[9]); 280 sha256_update_one_seg(&(new_data)[16 * 10], mh_sha256_seg_digests[10]); 281 sha256_update_one_seg(&(new_data)[16 * 11], mh_sha256_seg_digests[11]); 282 sha256_update_one_seg(&(new_data)[16 * 12], mh_sha256_seg_digests[12]); 283 sha256_update_one_seg(&(new_data)[16 * 13], mh_sha256_seg_digests[13]); 284 sha256_update_one_seg(&(new_data)[16 * 14], mh_sha256_seg_digests[14]); 285 sha256_update_one_seg(&(new_data)[16 * 15], mh_sha256_seg_digests[15]); 286 } 287 288 void mh_sha256_block_ref(const uint8_t * input_data, uint32_t(*digests)[HASH_SEGS], 289 uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE], uint32_t num_blocks) 290 { 291 uint32_t i, j; 292 uint32_t *temp_buffer = (uint32_t *) frame_buffer; 293 uint32_t(*trans_digests)[SHA256_DIGEST_WORDS]; 294 295 trans_digests = (uint32_t(*)[SHA256_DIGEST_WORDS]) digests; 296 297 // Re-structure seg_digests from 5*16 to 16*5 298 for (j = 0; j < HASH_SEGS; j++) { 299 for (i = 0; i < SHA256_DIGEST_WORDS; i++) { 300 temp_buffer[j * SHA256_DIGEST_WORDS + i] = digests[i][j]; 301 } 302 } 303 memcpy(trans_digests, temp_buffer, 4 * SHA256_DIGEST_WORDS * HASH_SEGS); 304 305 // Calculate digests for all segments, leveraging sha256 API 306 for (i = 0; i < num_blocks; i++) { 307 transform_input(temp_buffer, (uint32_t *) input_data, i); 308 sha256_update_all_segs(temp_buffer, trans_digests); 309 } 310 311 // Re-structure seg_digests from 16*5 to 5*16 312 for (j = 0; j < HASH_SEGS; j++) { 313 for (i = 0; i < SHA256_DIGEST_WORDS; i++) { 314 temp_buffer[i * HASH_SEGS + j] = trans_digests[j][i]; 315 } 316 } 317 memcpy(digests, temp_buffer, 4 * SHA256_DIGEST_WORDS * HASH_SEGS); 318 319 return; 320 } 321 322 void mh_sha256_tail_ref(uint8_t * partial_buffer, uint32_t total_len, 323 uint32_t(*mh_sha256_segs_digests)[HASH_SEGS], uint8_t * frame_buffer, 324 uint32_t digests[SHA256_DIGEST_WORDS]) 325 { 326 uint64_t partial_buffer_len, len_in_bit; 327 328 partial_buffer_len = total_len % MH_SHA256_BLOCK_SIZE; 329 330 // Padding the first block 331 partial_buffer[partial_buffer_len] = 0x80; 332 partial_buffer_len++; 333 memset(partial_buffer + partial_buffer_len, 0, 334 MH_SHA256_BLOCK_SIZE - partial_buffer_len); 335 336 // Calculate the first block without total_length if padding needs 2 block 337 if (partial_buffer_len > (MH_SHA256_BLOCK_SIZE - 8)) { 338 mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1); 339 //Padding the second block 340 memset(partial_buffer, 0, MH_SHA256_BLOCK_SIZE); 341 } 342 //Padding the block 343 len_in_bit = to_be64((uint64_t) total_len * 8); 344 *(uint64_t *) (partial_buffer + MH_SHA256_BLOCK_SIZE - 8) = len_in_bit; 345 mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1); 346 347 //Calculate multi-hash SHA256 digests (segment digests as input message) 348 sha256_for_mh_sha256_ref((uint8_t *) mh_sha256_segs_digests, digests, 349 4 * SHA256_DIGEST_WORDS * HASH_SEGS); 350 351 return; 352 } 353 354 void mh_sha256_ref(const void *buffer, uint32_t len, uint32_t * mh_sha256_digest) 355 { 356 uint64_t total_len; 357 uint64_t num_blocks; 358 uint32_t mh_sha256_segs_digests[SHA256_DIGEST_WORDS][HASH_SEGS]; 359 uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE]; 360 uint8_t partial_block_buffer[MH_SHA256_BLOCK_SIZE * 2]; 361 uint32_t mh_sha256_hash_dword[SHA256_DIGEST_WORDS]; 362 uint32_t i; 363 const uint8_t *input_data = (const uint8_t *)buffer; 364 365 /* Initialize digests of all segments */ 366 for (i = 0; i < HASH_SEGS; i++) { 367 mh_sha256_segs_digests[0][i] = MH_SHA256_H0; 368 mh_sha256_segs_digests[1][i] = MH_SHA256_H1; 369 mh_sha256_segs_digests[2][i] = MH_SHA256_H2; 370 mh_sha256_segs_digests[3][i] = MH_SHA256_H3; 371 mh_sha256_segs_digests[4][i] = MH_SHA256_H4; 372 mh_sha256_segs_digests[5][i] = MH_SHA256_H5; 373 mh_sha256_segs_digests[6][i] = MH_SHA256_H6; 374 mh_sha256_segs_digests[7][i] = MH_SHA256_H7; 375 } 376 377 total_len = len; 378 379 // Calculate blocks 380 num_blocks = len / MH_SHA256_BLOCK_SIZE; 381 if (num_blocks > 0) { 382 //do num_blocks process 383 mh_sha256_block_ref(input_data, mh_sha256_segs_digests, frame_buffer, 384 num_blocks); 385 len -= num_blocks * MH_SHA256_BLOCK_SIZE; 386 input_data += num_blocks * MH_SHA256_BLOCK_SIZE; 387 } 388 // Store the partial block 389 if (len != 0) { 390 memcpy(partial_block_buffer, input_data, len); 391 } 392 393 /* Finalize */ 394 mh_sha256_tail_ref(partial_block_buffer, total_len, mh_sha256_segs_digests, 395 frame_buffer, mh_sha256_hash_dword); 396 397 // Output the digests of mh_sha256 398 if (mh_sha256_digest != NULL) { 399 mh_sha256_digest[0] = mh_sha256_hash_dword[0]; 400 mh_sha256_digest[1] = mh_sha256_hash_dword[1]; 401 mh_sha256_digest[2] = mh_sha256_hash_dword[2]; 402 mh_sha256_digest[3] = mh_sha256_hash_dword[3]; 403 mh_sha256_digest[4] = mh_sha256_hash_dword[4]; 404 mh_sha256_digest[5] = mh_sha256_hash_dword[5]; 405 mh_sha256_digest[6] = mh_sha256_hash_dword[6]; 406 mh_sha256_digest[7] = mh_sha256_hash_dword[7]; 407 } 408 409 return; 410 } 411