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