1 /********************************************************************** 2 Copyright(c) 2011-2016 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 "sha512_mb_internal.h" 32 #include "memcpy_inline.h" 33 #include "endian_helper.h" 34 35 #ifdef _MSC_VER 36 #include <intrin.h> 37 #define inline __inline 38 #endif 39 40 /* From the FIPS, these are the same as for SHA256, but operating on 64 bit words 41 * instead of 32 bit. 42 */ 43 #define ch(e, f, g) ((e & f) ^ (g & ~e)) 44 #define maj(a, b, c) ((a & b) ^ (a & c) ^ (b & c)) 45 46 /* Sigma functions have same form as SHA256 but 47 * - change the word size to 64bit 48 * - change the amount to rotate 49 */ 50 #define ror64(x, r) (((x) >> (r)) ^ ((x) << (64 - (r)))) 51 52 /* Technically, s0 should be S0 as these are "capital sigma" functions, and likewise the case 53 * of the S0 should be s0, but keep as-is to avoid confusion with the other reference functions. 54 */ 55 #define s0(a) (ror64(a, 28) ^ ror64(a, 34) ^ ror64(a, 39)) 56 #define s1(e) (ror64(e, 14) ^ ror64(e, 18) ^ ror64(e, 41)) 57 58 #define S0(w) (ror64(w, 1) ^ ror64(w, 8) ^ (w >> 7)) 59 #define S1(w) (ror64(w, 19) ^ ror64(w, 61) ^ (w >> 6)) 60 61 #define W(x) w[(x) & 15] 62 63 #define step(i, a, b, c, d, e, f, g, h, k) \ 64 if (i < 16) \ 65 W(i) = to_be64(ww[i]); \ 66 else \ 67 W(i) = W(i - 16) + S0(W(i - 15)) + W(i - 7) + S1(W(i - 2)); \ 68 t2 = s0(a) + maj(a, b, c); \ 69 t1 = h + s1(e) + ch(e, f, g) + k + W(i); \ 70 d += t1; \ 71 h = t1 + t2; 72 73 static void 74 sha512_init(ISAL_SHA512_HASH_CTX *ctx, const void *buffer, uint32_t len); 75 static void 76 sha512_update(ISAL_SHA512_HASH_CTX *ctx, const void *buffer, uint32_t len); 77 static void 78 sha512_final(ISAL_SHA512_HASH_CTX *ctx); 79 static void 80 sha512_single(const void *data, uint64_t digest[]); 81 static inline void 82 hash_init_digest(ISAL_SHA512_WORD_T *digest); 83 84 void _sha512_ctx_mgr_init_base(ISAL_SHA512_HASH_CTX_MGR * mgr)85 _sha512_ctx_mgr_init_base(ISAL_SHA512_HASH_CTX_MGR *mgr) 86 { 87 } 88 89 ISAL_SHA512_HASH_CTX * _sha512_ctx_mgr_submit_base(ISAL_SHA512_HASH_CTX_MGR * mgr,ISAL_SHA512_HASH_CTX * ctx,const void * buffer,uint32_t len,ISAL_HASH_CTX_FLAG flags)90 _sha512_ctx_mgr_submit_base(ISAL_SHA512_HASH_CTX_MGR *mgr, ISAL_SHA512_HASH_CTX *ctx, 91 const void *buffer, uint32_t len, ISAL_HASH_CTX_FLAG flags) 92 { 93 if (flags & (~ISAL_HASH_ENTIRE)) { 94 // User should not pass anything other than FIRST, UPDATE, or LAST 95 ctx->error = ISAL_HASH_CTX_ERROR_INVALID_FLAGS; 96 return ctx; 97 } 98 99 if ((ctx->status & ISAL_HASH_CTX_STS_PROCESSING) && (flags == ISAL_HASH_ENTIRE)) { 100 // Cannot submit a new entire job to a currently processing job. 101 ctx->error = ISAL_HASH_CTX_ERROR_ALREADY_PROCESSING; 102 return ctx; 103 } 104 105 if ((ctx->status & ISAL_HASH_CTX_STS_COMPLETE) && !(flags & ISAL_HASH_FIRST)) { 106 // Cannot update a finished job. 107 ctx->error = ISAL_HASH_CTX_ERROR_ALREADY_COMPLETED; 108 return ctx; 109 } 110 111 if (flags == ISAL_HASH_FIRST) { 112 113 sha512_init(ctx, buffer, len); 114 sha512_update(ctx, buffer, len); 115 } 116 117 if (flags == ISAL_HASH_UPDATE) { 118 sha512_update(ctx, buffer, len); 119 } 120 121 if (flags == ISAL_HASH_LAST) { 122 sha512_update(ctx, buffer, len); 123 sha512_final(ctx); 124 } 125 126 if (flags == ISAL_HASH_ENTIRE) { 127 sha512_init(ctx, buffer, len); 128 sha512_update(ctx, buffer, len); 129 sha512_final(ctx); 130 } 131 132 return ctx; 133 } 134 135 ISAL_SHA512_HASH_CTX * _sha512_ctx_mgr_flush_base(ISAL_SHA512_HASH_CTX_MGR * mgr)136 _sha512_ctx_mgr_flush_base(ISAL_SHA512_HASH_CTX_MGR *mgr) 137 { 138 return NULL; 139 } 140 141 static void sha512_init(ISAL_SHA512_HASH_CTX * ctx,const void * buffer,uint32_t len)142 sha512_init(ISAL_SHA512_HASH_CTX *ctx, const void *buffer, uint32_t len) 143 { 144 // Init digest 145 hash_init_digest(ctx->job.result_digest); 146 147 // Reset byte counter 148 ctx->total_length = 0; 149 150 // Clear extra blocks 151 ctx->partial_block_buffer_length = 0; 152 153 // If we made it here, there were no errors during this call to submit 154 ctx->error = ISAL_HASH_CTX_ERROR_NONE; 155 156 // Mark it as processing 157 ctx->status = ISAL_HASH_CTX_STS_PROCESSING; 158 } 159 160 static void sha512_update(ISAL_SHA512_HASH_CTX * ctx,const void * buffer,uint32_t len)161 sha512_update(ISAL_SHA512_HASH_CTX *ctx, const void *buffer, uint32_t len) 162 { 163 uint32_t remain_len = len; 164 uint64_t *digest = ctx->job.result_digest; 165 166 // Advance byte counter 167 ctx->total_length += len; 168 169 // If there is anything currently buffered in the extra blocks, append to it until it 170 // contains a whole block. Or if the user's buffer contains less than a whole block, append 171 // as much as possible to the extra block. 172 if ((ctx->partial_block_buffer_length) | (remain_len < ISAL_SHA512_BLOCK_SIZE)) { 173 // Compute how many bytes to copy from user buffer into extra block 174 uint32_t copy_len = ISAL_SHA512_BLOCK_SIZE - ctx->partial_block_buffer_length; 175 if (remain_len < copy_len) { 176 copy_len = remain_len; 177 } 178 179 if (copy_len) { 180 // Copy and update relevant pointers and counters 181 memcpy(&ctx->partial_block_buffer[ctx->partial_block_buffer_length], buffer, 182 copy_len); 183 184 ctx->partial_block_buffer_length += copy_len; 185 remain_len -= copy_len; 186 buffer = (void *) ((uint8_t *) buffer + copy_len); 187 } 188 // The extra block should never contain more than 1 block here 189 assert(ctx->partial_block_buffer_length <= ISAL_SHA512_BLOCK_SIZE); 190 191 // If the extra block buffer contains exactly 1 block, it can be hashed. 192 if (ctx->partial_block_buffer_length >= ISAL_SHA512_BLOCK_SIZE) { 193 ctx->partial_block_buffer_length = 0; 194 sha512_single(ctx->partial_block_buffer, digest); 195 } 196 } 197 // If the extra blocks are empty, begin hashing what remains in the user's buffer. 198 if (ctx->partial_block_buffer_length == 0) { 199 while (remain_len >= ISAL_SHA512_BLOCK_SIZE) { 200 sha512_single(buffer, digest); 201 buffer = (void *) ((uint8_t *) buffer + ISAL_SHA512_BLOCK_SIZE); 202 remain_len -= ISAL_SHA512_BLOCK_SIZE; 203 } 204 } 205 206 if (remain_len > 0) { 207 memcpy(&ctx->partial_block_buffer, buffer, remain_len); 208 ctx->partial_block_buffer_length = remain_len; 209 } 210 211 ctx->status = ISAL_HASH_CTX_STS_IDLE; 212 return; 213 } 214 215 static void sha512_final(ISAL_SHA512_HASH_CTX * ctx)216 sha512_final(ISAL_SHA512_HASH_CTX *ctx) 217 { 218 const void *buffer = ctx->partial_block_buffer; 219 uint32_t i = ctx->partial_block_buffer_length; 220 uint8_t buf[2 * ISAL_SHA512_BLOCK_SIZE]; 221 uint64_t *digest = ctx->job.result_digest; 222 223 memcpy(buf, buffer, i); 224 buf[i++] = 0x80; 225 for (uint32_t j = i; j < (2 * ISAL_SHA512_BLOCK_SIZE); j++) { 226 buf[j] = 0; 227 } 228 229 if (i > ISAL_SHA512_BLOCK_SIZE - ISAL_SHA512_PADLENGTHFIELD_SIZE) { 230 i = 2 * ISAL_SHA512_BLOCK_SIZE; 231 } else { 232 i = ISAL_SHA512_BLOCK_SIZE; 233 } 234 235 *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) ctx->total_length * 8); 236 237 sha512_single(buf, digest); 238 if (i == 2 * ISAL_SHA512_BLOCK_SIZE) { 239 sha512_single(buf + ISAL_SHA512_BLOCK_SIZE, digest); 240 } 241 242 ctx->status = ISAL_HASH_CTX_STS_COMPLETE; 243 } 244 245 void sha512_single(const void * data,uint64_t digest[])246 sha512_single(const void *data, uint64_t digest[]) 247 { 248 /* Check these are all uint64_t */ 249 uint64_t a, b, c, d, e, f, g, h, t1, t2; 250 uint64_t w[16]; 251 uint64_t *ww = (uint64_t *) data; 252 253 a = digest[0]; 254 b = digest[1]; 255 c = digest[2]; 256 d = digest[3]; 257 e = digest[4]; 258 f = digest[5]; 259 g = digest[6]; 260 h = digest[7]; 261 262 step(0, a, b, c, d, e, f, g, h, 0x428a2f98d728ae22); 263 step(1, h, a, b, c, d, e, f, g, 0x7137449123ef65cd); 264 step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2f); 265 step(3, f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbc); 266 step(4, e, f, g, h, a, b, c, d, 0x3956c25bf348b538); 267 step(5, d, e, f, g, h, a, b, c, 0x59f111f1b605d019); 268 step(6, c, d, e, f, g, h, a, b, 0x923f82a4af194f9b); 269 step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118); 270 step(8, a, b, c, d, e, f, g, h, 0xd807aa98a3030242); 271 step(9, h, a, b, c, d, e, f, g, 0x12835b0145706fbe); 272 step(10, g, h, a, b, c, d, e, f, 0x243185be4ee4b28c); 273 step(11, f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2); 274 step(12, e, f, g, h, a, b, c, d, 0x72be5d74f27b896f); 275 step(13, d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1); 276 step(14, c, d, e, f, g, h, a, b, 0x9bdc06a725c71235); 277 step(15, b, c, d, e, f, g, h, a, 0xc19bf174cf692694); 278 step(16, a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2); 279 step(17, h, a, b, c, d, e, f, g, 0xefbe4786384f25e3); 280 step(18, g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5); 281 step(19, f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65); 282 step(20, e, f, g, h, a, b, c, d, 0x2de92c6f592b0275); 283 step(21, d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483); 284 step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4); 285 step(23, b, c, d, e, f, g, h, a, 0x76f988da831153b5); 286 step(24, a, b, c, d, e, f, g, h, 0x983e5152ee66dfab); 287 step(25, h, a, b, c, d, e, f, g, 0xa831c66d2db43210); 288 step(26, g, h, a, b, c, d, e, f, 0xb00327c898fb213f); 289 step(27, f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4); 290 step(28, e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2); 291 step(29, d, e, f, g, h, a, b, c, 0xd5a79147930aa725); 292 step(30, c, d, e, f, g, h, a, b, 0x06ca6351e003826f); 293 step(31, b, c, d, e, f, g, h, a, 0x142929670a0e6e70); 294 step(32, a, b, c, d, e, f, g, h, 0x27b70a8546d22ffc); 295 step(33, h, a, b, c, d, e, f, g, 0x2e1b21385c26c926); 296 step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aed); 297 step(35, f, g, h, a, b, c, d, e, 0x53380d139d95b3df); 298 step(36, e, f, g, h, a, b, c, d, 0x650a73548baf63de); 299 step(37, d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8); 300 step(38, c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6); 301 step(39, b, c, d, e, f, g, h, a, 0x92722c851482353b); 302 step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364); 303 step(41, h, a, b, c, d, e, f, g, 0xa81a664bbc423001); 304 step(42, g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791); 305 step(43, f, g, h, a, b, c, d, e, 0xc76c51a30654be30); 306 step(44, e, f, g, h, a, b, c, d, 0xd192e819d6ef5218); 307 step(45, d, e, f, g, h, a, b, c, 0xd69906245565a910); 308 step(46, c, d, e, f, g, h, a, b, 0xf40e35855771202a); 309 step(47, b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8); 310 step(48, a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8); 311 step(49, h, a, b, c, d, e, f, g, 0x1e376c085141ab53); 312 step(50, g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99); 313 step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8); 314 step(52, e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63); 315 step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acb); 316 step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373); 317 step(55, b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3); 318 step(56, a, b, c, d, e, f, g, h, 0x748f82ee5defb2fc); 319 step(57, h, a, b, c, d, e, f, g, 0x78a5636f43172f60); 320 step(58, g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72); 321 step(59, f, g, h, a, b, c, d, e, 0x8cc702081a6439ec); 322 step(60, e, f, g, h, a, b, c, d, 0x90befffa23631e28); 323 step(61, d, e, f, g, h, a, b, c, 0xa4506cebde82bde9); 324 step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915); 325 step(63, b, c, d, e, f, g, h, a, 0xc67178f2e372532b); // step 63 326 step(64, a, b, c, d, e, f, g, h, 0xca273eceea26619c); 327 step(65, h, a, b, c, d, e, f, g, 0xd186b8c721c0c207); 328 step(66, g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1e); 329 step(67, f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178); 330 step(68, e, f, g, h, a, b, c, d, 0x06f067aa72176fba); 331 step(69, d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6); 332 step(70, c, d, e, f, g, h, a, b, 0x113f9804bef90dae); 333 step(71, b, c, d, e, f, g, h, a, 0x1b710b35131c471b); 334 step(72, a, b, c, d, e, f, g, h, 0x28db77f523047d84); 335 step(73, h, a, b, c, d, e, f, g, 0x32caab7b40c72493); 336 step(74, g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebc); 337 step(75, f, g, h, a, b, c, d, e, 0x431d67c49c100d4c); 338 step(76, e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6); 339 step(77, d, e, f, g, h, a, b, c, 0x597f299cfc657e2a); 340 step(78, c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faec); 341 step(79, b, c, d, e, f, g, h, a, 0x6c44198c4a475817); // step 79 342 343 digest[0] += a; 344 digest[1] += b; 345 digest[2] += c; 346 digest[3] += d; 347 digest[4] += e; 348 digest[5] += f; 349 digest[6] += g; 350 digest[7] += h; 351 } 352 353 static inline void hash_init_digest(ISAL_SHA512_WORD_T * digest)354 hash_init_digest(ISAL_SHA512_WORD_T *digest) 355 { 356 static const ISAL_SHA512_WORD_T hash_initial_digest[ISAL_SHA512_DIGEST_NWORDS] = { 357 ISAL_SHA512_INITIAL_DIGEST 358 }; 359 memcpy_fixedlen(digest, hash_initial_digest, sizeof(hash_initial_digest)); 360 } 361 362 struct slver { 363 uint16_t snum; 364 uint8_t ver; 365 uint8_t core; 366 }; 367 struct slver sha512_ctx_mgr_init_base_slver_000002f3; 368 struct slver sha512_ctx_mgr_init_base_slver = { 0x02f3, 0x00, 0x00 }; 369 370 struct slver sha512_ctx_mgr_submit_base_slver_000002f4; 371 struct slver sha512_ctx_mgr_submit_base_slver = { 0x02f4, 0x00, 0x00 }; 372 373 struct slver sha512_ctx_mgr_flush_base_slver_000002f5; 374 struct slver sha512_ctx_mgr_flush_base_slver = { 0x02f5, 0x00, 0x00 }; 375