curl_sha512_256.c (30617B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Evgeny Grin (Karlson2k), <k2k@narod.ru>. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 #include "curl_setup.h" 26 27 #if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256) 28 29 #include "curl_sha512_256.h" 30 #include "curlx/warnless.h" 31 32 /* The recommended order of the TLS backends: 33 * * OpenSSL 34 * * GnuTLS 35 * * wolfSSL 36 * * Schannel SSPI 37 * * mbedTLS 38 * * Rustls 39 * Skip the backend if it does not support the required algorithm */ 40 41 #if defined(USE_OPENSSL) 42 # include <openssl/opensslv.h> 43 # if (!defined(LIBRESSL_VERSION_NUMBER) && \ 44 defined(OPENSSL_VERSION_NUMBER) && \ 45 (OPENSSL_VERSION_NUMBER >= 0x10101000L)) || \ 46 (defined(LIBRESSL_VERSION_NUMBER) && \ 47 (LIBRESSL_VERSION_NUMBER >= 0x3080000fL)) 48 # include <openssl/opensslconf.h> 49 # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) 50 # include <openssl/evp.h> 51 # define USE_OPENSSL_SHA512_256 1 52 # define HAS_SHA512_256_IMPLEMENTATION 1 53 # ifdef __NetBSD__ 54 /* Some NetBSD versions has a bug in SHA-512/256. 55 * See https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 56 * The problematic versions: 57 * - NetBSD before 9.4 58 * - NetBSD 9 all development versions (9.99.x) 59 * - NetBSD 10 development versions (10.99.x) before 10.99.11 60 * The bug was fixed in NetBSD 9.4 release, NetBSD 10.0 release, 61 * NetBSD 10.99.11 development. 62 * It is safe to apply the workaround even if the bug is not present, as 63 * the workaround just reduces performance slightly. */ 64 # include <sys/param.h> 65 # if __NetBSD_Version__ < 904000000 || \ 66 (__NetBSD_Version__ >= 999000000 && \ 67 __NetBSD_Version__ < 1000000000) || \ 68 (__NetBSD_Version__ >= 1099000000 && \ 69 __NetBSD_Version__ < 1099001100) 70 # define NEED_NETBSD_SHA512_256_WORKAROUND 1 71 # include <string.h> 72 # endif 73 # endif 74 # endif 75 # endif 76 #endif /* USE_OPENSSL */ 77 78 79 #if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS) 80 # include <nettle/sha.h> 81 # if defined(SHA512_256_DIGEST_SIZE) 82 # define USE_GNUTLS_SHA512_256 1 83 # endif 84 #endif /* ! HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */ 85 86 #if defined(USE_OPENSSL_SHA512_256) 87 88 /* OpenSSL does not provide macros for SHA-512/256 sizes */ 89 90 /** 91 * Size of the SHA-512/256 single processing block in bytes. 92 */ 93 #define CURL_SHA512_256_BLOCK_SIZE 128 94 95 /** 96 * Size of the SHA-512/256 resulting digest in bytes. 97 * This is the final digest size, not intermediate hash. 98 */ 99 #define CURL_SHA512_256_DIGEST_SIZE CURL_SHA512_256_DIGEST_LENGTH 100 101 /** 102 * Context type used for SHA-512/256 calculations 103 */ 104 typedef EVP_MD_CTX *Curl_sha512_256_ctx; 105 106 /** 107 * Initialise structure for SHA-512/256 calculation. 108 * 109 * @param context the calculation context 110 * @return CURLE_OK if succeed, 111 * error code otherwise 112 */ 113 static CURLcode 114 Curl_sha512_256_init(void *context) 115 { 116 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 117 118 *ctx = EVP_MD_CTX_create(); 119 if(!*ctx) 120 return CURLE_OUT_OF_MEMORY; 121 122 if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) { 123 /* Check whether the header and this file use the same numbers */ 124 DEBUGASSERT(EVP_MD_CTX_size(*ctx) == CURL_SHA512_256_DIGEST_SIZE); 125 /* Check whether the block size is correct */ 126 DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == CURL_SHA512_256_BLOCK_SIZE); 127 128 return CURLE_OK; /* Success */ 129 } 130 131 /* Cleanup */ 132 EVP_MD_CTX_destroy(*ctx); 133 return CURLE_FAILED_INIT; 134 } 135 136 137 /** 138 * Process portion of bytes. 139 * 140 * @param context the calculation context 141 * @param data bytes to add to hash 142 * @return CURLE_OK if succeed, 143 * error code otherwise 144 */ 145 static CURLcode 146 Curl_sha512_256_update(void *context, 147 const unsigned char *data, 148 size_t length) 149 { 150 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 151 152 if(!EVP_DigestUpdate(*ctx, data, length)) 153 return CURLE_SSL_CIPHER; 154 155 return CURLE_OK; 156 } 157 158 159 /** 160 * Finalise SHA-512/256 calculation, return digest. 161 * 162 * @param context the calculation context 163 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE 164 # bytes 165 * @return CURLE_OK if succeed, 166 * error code otherwise 167 */ 168 static CURLcode 169 Curl_sha512_256_finish(unsigned char *digest, 170 void *context) 171 { 172 CURLcode ret; 173 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 174 175 #ifdef NEED_NETBSD_SHA512_256_WORKAROUND 176 /* Use a larger buffer to work around a bug in NetBSD: 177 https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */ 178 unsigned char tmp_digest[CURL_SHA512_256_DIGEST_SIZE * 2]; 179 ret = EVP_DigestFinal_ex(*ctx, 180 tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER; 181 if(ret == CURLE_OK) 182 memcpy(digest, tmp_digest, CURL_SHA512_256_DIGEST_SIZE); 183 explicit_memset(tmp_digest, 0, sizeof(tmp_digest)); 184 #else /* ! NEED_NETBSD_SHA512_256_WORKAROUND */ 185 ret = EVP_DigestFinal_ex(*ctx, digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER; 186 #endif /* ! NEED_NETBSD_SHA512_256_WORKAROUND */ 187 188 EVP_MD_CTX_destroy(*ctx); 189 *ctx = NULL; 190 191 return ret; 192 } 193 194 #elif defined(USE_GNUTLS_SHA512_256) 195 196 #define CURL_SHA512_256_BLOCK_SIZE SHA512_256_BLOCK_SIZE 197 #define CURL_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE 198 199 /** 200 * Context type used for SHA-512/256 calculations 201 */ 202 typedef struct sha512_256_ctx Curl_sha512_256_ctx; 203 204 /** 205 * Initialise structure for SHA-512/256 calculation. 206 * 207 * @param context the calculation context 208 * @return always CURLE_OK 209 */ 210 static CURLcode 211 Curl_sha512_256_init(void *context) 212 { 213 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 214 215 /* Check whether the header and this file use the same numbers */ 216 DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); 217 218 sha512_256_init(ctx); 219 220 return CURLE_OK; 221 } 222 223 224 /** 225 * Process portion of bytes. 226 * 227 * @param context the calculation context 228 * @param data bytes to add to hash 229 * @param length number of bytes in @a data 230 * @return always CURLE_OK 231 */ 232 static CURLcode 233 Curl_sha512_256_update(void *context, 234 const unsigned char *data, 235 size_t length) 236 { 237 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 238 239 DEBUGASSERT((data != NULL) || (length == 0)); 240 241 sha512_256_update(ctx, length, (const uint8_t *)data); 242 243 return CURLE_OK; 244 } 245 246 247 /** 248 * Finalise SHA-512/256 calculation, return digest. 249 * 250 * @param context the calculation context 251 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE 252 # bytes 253 * @return always CURLE_OK 254 */ 255 static CURLcode 256 Curl_sha512_256_finish(unsigned char *digest, 257 void *context) 258 { 259 Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context; 260 261 sha512_256_digest(ctx, 262 (size_t)CURL_SHA512_256_DIGEST_SIZE, (uint8_t *)digest); 263 264 return CURLE_OK; 265 } 266 267 #else /* No system or TLS backend SHA-512/256 implementation available */ 268 269 /* ** This implementation of SHA-512/256 hash calculation was originally ** * 270 * ** written by Evgeny Grin (Karlson2k) for GNU libmicrohttpd. ** * 271 * ** The author ported the code to libcurl. The ported code is provided ** * 272 * ** under curl license. ** * 273 * ** This is a minimal version with minimal optimizations. Performance ** * 274 * ** can be significantly improved. Big-endian store and load macros ** * 275 * ** are obvious targets for optimization. ** */ 276 277 #ifdef __GNUC__ 278 # if defined(__has_attribute) && defined(__STDC_VERSION__) 279 # if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901 280 # define CURL_FORCEINLINE CURL_INLINE __attribute__((always_inline)) 281 # endif 282 # endif 283 #endif 284 285 #if !defined(CURL_FORCEINLINE) && \ 286 defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__) 287 # define CURL_FORCEINLINE __forceinline 288 #endif 289 290 #if !defined(CURL_FORCEINLINE) 291 /* Assume that 'CURL_INLINE' keyword works or the 292 * macro was already defined correctly. */ 293 # define CURL_FORCEINLINE CURL_INLINE 294 #endif 295 296 /* Bits manipulation macros and functions. 297 Can be moved to other headers to reuse. */ 298 299 #define CURL_GET_64BIT_BE(ptr) \ 300 ( ((curl_uint64_t)(((const unsigned char*)(ptr))[0]) << 56) | \ 301 ((curl_uint64_t)(((const unsigned char*)(ptr))[1]) << 48) | \ 302 ((curl_uint64_t)(((const unsigned char*)(ptr))[2]) << 40) | \ 303 ((curl_uint64_t)(((const unsigned char*)(ptr))[3]) << 32) | \ 304 ((curl_uint64_t)(((const unsigned char*)(ptr))[4]) << 24) | \ 305 ((curl_uint64_t)(((const unsigned char*)(ptr))[5]) << 16) | \ 306 ((curl_uint64_t)(((const unsigned char*)(ptr))[6]) << 8) | \ 307 (curl_uint64_t)(((const unsigned char*)(ptr))[7]) ) 308 309 #define CURL_PUT_64BIT_BE(ptr,val) do { \ 310 ((unsigned char*)(ptr))[7]=(unsigned char)((curl_uint64_t)(val)); \ 311 ((unsigned char*)(ptr))[6]=(unsigned char)(((curl_uint64_t)(val)) >> 8); \ 312 ((unsigned char*)(ptr))[5]=(unsigned char)(((curl_uint64_t)(val)) >> 16); \ 313 ((unsigned char*)(ptr))[4]=(unsigned char)(((curl_uint64_t)(val)) >> 24); \ 314 ((unsigned char*)(ptr))[3]=(unsigned char)(((curl_uint64_t)(val)) >> 32); \ 315 ((unsigned char*)(ptr))[2]=(unsigned char)(((curl_uint64_t)(val)) >> 40); \ 316 ((unsigned char*)(ptr))[1]=(unsigned char)(((curl_uint64_t)(val)) >> 48); \ 317 ((unsigned char*)(ptr))[0]=(unsigned char)(((curl_uint64_t)(val)) >> 56); \ 318 } while(0) 319 320 /* Defined as a function. The macro version may duplicate the binary code 321 * size as each argument is used twice, so if any calculation is used 322 * as an argument, the calculation could be done twice. */ 323 static CURL_FORCEINLINE curl_uint64_t 324 Curl_rotr64(curl_uint64_t value, unsigned int bits) 325 { 326 bits %= 64; 327 if(0 == bits) 328 return value; 329 /* Defined in a form which modern compiler could optimize. */ 330 return (value >> bits) | (value << (64 - bits)); 331 } 332 333 /* SHA-512/256 specific data */ 334 335 /** 336 * Number of bits in a single SHA-512/256 word. 337 */ 338 #define SHA512_256_WORD_SIZE_BITS 64 339 340 /** 341 * Number of bytes in a single SHA-512/256 word. 342 */ 343 #define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8) 344 345 /** 346 * Hash is kept internally as 8 64-bit words. 347 * This is the intermediate hash size, used during computing the final digest. 348 */ 349 #define SHA512_256_HASH_SIZE_WORDS 8 350 351 /** 352 * Size of the SHA-512/256 resulting digest in words. 353 * This is the final digest size, not intermediate hash. 354 */ 355 #define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2) 356 357 /** 358 * Size of the SHA-512/256 resulting digest in bytes 359 * This is the final digest size, not intermediate hash. 360 */ 361 #define CURL_SHA512_256_DIGEST_SIZE \ 362 (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD) 363 364 /** 365 * Size of the SHA-512/256 single processing block in bits. 366 */ 367 #define SHA512_256_BLOCK_SIZE_BITS 1024 368 369 /** 370 * Size of the SHA-512/256 single processing block in bytes. 371 */ 372 #define CURL_SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8) 373 374 /** 375 * Size of the SHA-512/256 single processing block in words. 376 */ 377 #define SHA512_256_BLOCK_SIZE_WORDS \ 378 (SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS) 379 380 /** 381 * SHA-512/256 calculation context 382 */ 383 struct Curl_sha512_256ctx 384 { 385 /** 386 * Intermediate hash value. The variable is properly aligned. Smart 387 * compilers may automatically use fast load/store instruction for big 388 * endian data on little endian machine. 389 */ 390 curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS]; 391 /** 392 * SHA-512/256 input data buffer. The buffer is properly aligned. Smart 393 * compilers may automatically use fast load/store instruction for big 394 * endian data on little endian machine. 395 */ 396 curl_uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS]; 397 /** 398 * The number of bytes, lower part 399 */ 400 curl_uint64_t count; 401 /** 402 * The number of bits, high part. Unlike lower part, this counts the number 403 * of bits, not bytes. 404 */ 405 curl_uint64_t count_bits_hi; 406 }; 407 408 /** 409 * Context type used for SHA-512/256 calculations 410 */ 411 typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx; 412 413 414 /** 415 * Initialise structure for SHA-512/256 calculation. 416 * 417 * @param context the calculation context 418 * @return always CURLE_OK 419 */ 420 static CURLcode 421 Curl_sha512_256_init(void *context) 422 { 423 struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; 424 425 /* Check whether the header and this file use the same numbers */ 426 DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); 427 428 DEBUGASSERT(sizeof(curl_uint64_t) == 8); 429 430 /* Initial hash values, see FIPS PUB 180-4 section 5.3.6.2 */ 431 /* Values generated by "IV Generation Function" as described in 432 * section 5.3.6 */ 433 ctx->H[0] = CURL_UINT64_C(0x22312194FC2BF72C); 434 ctx->H[1] = CURL_UINT64_C(0x9F555FA3C84C64C2); 435 ctx->H[2] = CURL_UINT64_C(0x2393B86B6F53B151); 436 ctx->H[3] = CURL_UINT64_C(0x963877195940EABD); 437 ctx->H[4] = CURL_UINT64_C(0x96283EE2A88EFFE3); 438 ctx->H[5] = CURL_UINT64_C(0xBE5E1E2553863992); 439 ctx->H[6] = CURL_UINT64_C(0x2B0199FC2C85B8AA); 440 ctx->H[7] = CURL_UINT64_C(0x0EB72DDC81C52CA2); 441 442 /* Initialise number of bytes and high part of number of bits. */ 443 ctx->count = CURL_UINT64_C(0); 444 ctx->count_bits_hi = CURL_UINT64_C(0); 445 446 return CURLE_OK; 447 } 448 449 450 /** 451 * Base of the SHA-512/256 transformation. 452 * Gets a full 128 bytes block of data and updates hash values; 453 * @param H hash values 454 * @param data the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block 455 */ 456 static void 457 Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS], 458 const void *data) 459 { 460 /* Working variables, 461 see FIPS PUB 180-4 section 6.7, 6.4. */ 462 curl_uint64_t a = H[0]; 463 curl_uint64_t b = H[1]; 464 curl_uint64_t c = H[2]; 465 curl_uint64_t d = H[3]; 466 curl_uint64_t e = H[4]; 467 curl_uint64_t f = H[5]; 468 curl_uint64_t g = H[6]; 469 curl_uint64_t h = H[7]; 470 471 /* Data buffer, used as a cyclic buffer. 472 See FIPS PUB 180-4 section 5.2.2, 6.7, 6.4. */ 473 curl_uint64_t W[16]; 474 475 /* 'Ch' and 'Maj' macro functions are defined with widely-used optimization. 476 See FIPS PUB 180-4 formulae 4.8, 4.9. */ 477 #define Sha512_Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) ) 478 #define Sha512_Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) 479 480 /* Four 'Sigma' macro functions. 481 See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */ 482 #define SIG0(x) \ 483 ( Curl_rotr64((x), 28) ^ Curl_rotr64((x), 34) ^ Curl_rotr64((x), 39) ) 484 #define SIG1(x) \ 485 ( Curl_rotr64((x), 14) ^ Curl_rotr64((x), 18) ^ Curl_rotr64((x), 41) ) 486 #define sig0(x) \ 487 ( Curl_rotr64((x), 1) ^ Curl_rotr64((x), 8) ^ ((x) >> 7) ) 488 #define sig1(x) \ 489 ( Curl_rotr64((x), 19) ^ Curl_rotr64((x), 61) ^ ((x) >> 6) ) 490 491 if(1) { 492 unsigned int t; 493 /* K constants array. 494 See FIPS PUB 180-4 section 4.2.3 for K values. */ 495 static const curl_uint64_t K[80] = { 496 CURL_UINT64_C(0x428a2f98d728ae22), CURL_UINT64_C(0x7137449123ef65cd), 497 CURL_UINT64_C(0xb5c0fbcfec4d3b2f), CURL_UINT64_C(0xe9b5dba58189dbbc), 498 CURL_UINT64_C(0x3956c25bf348b538), CURL_UINT64_C(0x59f111f1b605d019), 499 CURL_UINT64_C(0x923f82a4af194f9b), CURL_UINT64_C(0xab1c5ed5da6d8118), 500 CURL_UINT64_C(0xd807aa98a3030242), CURL_UINT64_C(0x12835b0145706fbe), 501 CURL_UINT64_C(0x243185be4ee4b28c), CURL_UINT64_C(0x550c7dc3d5ffb4e2), 502 CURL_UINT64_C(0x72be5d74f27b896f), CURL_UINT64_C(0x80deb1fe3b1696b1), 503 CURL_UINT64_C(0x9bdc06a725c71235), CURL_UINT64_C(0xc19bf174cf692694), 504 CURL_UINT64_C(0xe49b69c19ef14ad2), CURL_UINT64_C(0xefbe4786384f25e3), 505 CURL_UINT64_C(0x0fc19dc68b8cd5b5), CURL_UINT64_C(0x240ca1cc77ac9c65), 506 CURL_UINT64_C(0x2de92c6f592b0275), CURL_UINT64_C(0x4a7484aa6ea6e483), 507 CURL_UINT64_C(0x5cb0a9dcbd41fbd4), CURL_UINT64_C(0x76f988da831153b5), 508 CURL_UINT64_C(0x983e5152ee66dfab), CURL_UINT64_C(0xa831c66d2db43210), 509 CURL_UINT64_C(0xb00327c898fb213f), CURL_UINT64_C(0xbf597fc7beef0ee4), 510 CURL_UINT64_C(0xc6e00bf33da88fc2), CURL_UINT64_C(0xd5a79147930aa725), 511 CURL_UINT64_C(0x06ca6351e003826f), CURL_UINT64_C(0x142929670a0e6e70), 512 CURL_UINT64_C(0x27b70a8546d22ffc), CURL_UINT64_C(0x2e1b21385c26c926), 513 CURL_UINT64_C(0x4d2c6dfc5ac42aed), CURL_UINT64_C(0x53380d139d95b3df), 514 CURL_UINT64_C(0x650a73548baf63de), CURL_UINT64_C(0x766a0abb3c77b2a8), 515 CURL_UINT64_C(0x81c2c92e47edaee6), CURL_UINT64_C(0x92722c851482353b), 516 CURL_UINT64_C(0xa2bfe8a14cf10364), CURL_UINT64_C(0xa81a664bbc423001), 517 CURL_UINT64_C(0xc24b8b70d0f89791), CURL_UINT64_C(0xc76c51a30654be30), 518 CURL_UINT64_C(0xd192e819d6ef5218), CURL_UINT64_C(0xd69906245565a910), 519 CURL_UINT64_C(0xf40e35855771202a), CURL_UINT64_C(0x106aa07032bbd1b8), 520 CURL_UINT64_C(0x19a4c116b8d2d0c8), CURL_UINT64_C(0x1e376c085141ab53), 521 CURL_UINT64_C(0x2748774cdf8eeb99), CURL_UINT64_C(0x34b0bcb5e19b48a8), 522 CURL_UINT64_C(0x391c0cb3c5c95a63), CURL_UINT64_C(0x4ed8aa4ae3418acb), 523 CURL_UINT64_C(0x5b9cca4f7763e373), CURL_UINT64_C(0x682e6ff3d6b2b8a3), 524 CURL_UINT64_C(0x748f82ee5defb2fc), CURL_UINT64_C(0x78a5636f43172f60), 525 CURL_UINT64_C(0x84c87814a1f0ab72), CURL_UINT64_C(0x8cc702081a6439ec), 526 CURL_UINT64_C(0x90befffa23631e28), CURL_UINT64_C(0xa4506cebde82bde9), 527 CURL_UINT64_C(0xbef9a3f7b2c67915), CURL_UINT64_C(0xc67178f2e372532b), 528 CURL_UINT64_C(0xca273eceea26619c), CURL_UINT64_C(0xd186b8c721c0c207), 529 CURL_UINT64_C(0xeada7dd6cde0eb1e), CURL_UINT64_C(0xf57d4f7fee6ed178), 530 CURL_UINT64_C(0x06f067aa72176fba), CURL_UINT64_C(0x0a637dc5a2c898a6), 531 CURL_UINT64_C(0x113f9804bef90dae), CURL_UINT64_C(0x1b710b35131c471b), 532 CURL_UINT64_C(0x28db77f523047d84), CURL_UINT64_C(0x32caab7b40c72493), 533 CURL_UINT64_C(0x3c9ebe0a15c9bebc), CURL_UINT64_C(0x431d67c49c100d4c), 534 CURL_UINT64_C(0x4cc5d4becb3e42b6), CURL_UINT64_C(0x597f299cfc657e2a), 535 CURL_UINT64_C(0x5fcb6fab3ad6faec), CURL_UINT64_C(0x6c44198c4a475817) 536 }; 537 538 /* One step of SHA-512/256 computation, 539 see FIPS PUB 180-4 section 6.4.2 step 3. 540 * Note: this macro updates working variables in-place, without rotation. 541 * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in 542 FIPS PUB 180-4 section 6.4.2 step 3. 543 the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in 544 FIPS PUB 180-4 section 6.4.2 step 3. 545 * Note: 'wt' must be used exactly one time in this macro as macro for 546 'wt' calculation may change other data as well every time when 547 used. */ 548 #define SHA2STEP64(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \ 549 (vD) += ((vH) += SIG1((vE)) + Sha512_Ch((vE),(vF),(vG)) + (kt) + (wt)); \ 550 (vH) += SIG0((vA)) + Sha512_Maj((vA),(vB),(vC)); } while (0) 551 552 /* One step of SHA-512/256 computation with working variables rotation, 553 see FIPS PUB 180-4 section 6.4.2 step 3. This macro version reassigns 554 all working variables on each step. */ 555 #define SHA2STEP64RV(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \ 556 curl_uint64_t tmp_h_ = (vH); \ 557 SHA2STEP64((vA),(vB),(vC),(vD),(vE),(vF),(vG),tmp_h_,(kt),(wt)); \ 558 (vH) = (vG); \ 559 (vG) = (vF); \ 560 (vF) = (vE); \ 561 (vE) = (vD); \ 562 (vD) = (vC); \ 563 (vC) = (vB); \ 564 (vB) = (vA); \ 565 (vA) = tmp_h_; } while(0) 566 567 /* Get value of W(t) from input data buffer for 0 <= t <= 15, 568 See FIPS PUB 180-4 section 6.2. 569 Input data must be read in big-endian bytes order, 570 see FIPS PUB 180-4 section 3.1.2. */ 571 #define SHA512_GET_W_FROM_DATA(buf,t) \ 572 CURL_GET_64BIT_BE( \ 573 ((const unsigned char*) (buf)) + (t) * SHA512_256_BYTES_IN_WORD) 574 575 /* During first 16 steps, before making any calculation on each step, the 576 W element is read from the input data buffer as a big-endian value and 577 stored in the array of W elements. */ 578 for(t = 0; t < 16; ++t) { 579 SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \ 580 W[t] = SHA512_GET_W_FROM_DATA(data, t)); 581 } 582 583 /* 'W' generation and assignment for 16 <= t <= 79. 584 See FIPS PUB 180-4 section 6.4.2. 585 As only the last 16 'W' are used in calculations, it is possible to 586 use 16 elements array of W as a cyclic buffer. 587 Note: ((t-16) & 15) have same value as (t & 15) */ 588 #define Wgen(w,t) \ 589 (curl_uint64_t)( (w)[(t - 16) & 15] + sig1((w)[((t) - 2) & 15]) \ 590 + (w)[((t) - 7) & 15] + sig0((w)[((t) - 15) & 15]) ) 591 592 /* During the last 64 steps, before making any calculation on each step, 593 current W element is generated from other W elements of the cyclic 594 buffer and the generated value is stored back in the cyclic buffer. */ 595 for(t = 16; t < 80; ++t) { 596 SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \ 597 W[t & 15] = Wgen(W, t)); 598 } 599 } 600 601 /* Compute and store the intermediate hash. 602 See FIPS PUB 180-4 section 6.4.2 step 4. */ 603 H[0] += a; 604 H[1] += b; 605 H[2] += c; 606 H[3] += d; 607 H[4] += e; 608 H[5] += f; 609 H[6] += g; 610 H[7] += h; 611 } 612 613 614 /** 615 * Process portion of bytes. 616 * 617 * @param context the calculation context 618 * @param data bytes to add to hash 619 * @param length number of bytes in @a data 620 * @return always CURLE_OK 621 */ 622 static CURLcode 623 Curl_sha512_256_update(void *context, 624 const unsigned char *data, 625 size_t length) 626 { 627 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 628 struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; 629 /* the void pointer here is required to mute Intel compiler warning */ 630 void *const ctx_buf = ctx->buffer; 631 632 DEBUGASSERT((data != NULL) || (length == 0)); 633 634 if(0 == length) 635 return CURLE_OK; /* Shortcut, do nothing */ 636 637 /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) 638 equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ 639 bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); 640 ctx->count += length; 641 if(length > ctx->count) 642 ctx->count_bits_hi += 1U << 3; /* Value wrap */ 643 ctx->count_bits_hi += ctx->count >> 61; 644 ctx->count &= CURL_UINT64_C(0x1FFFFFFFFFFFFFFF); 645 646 if(0 != bytes_have) { 647 unsigned int bytes_left = CURL_SHA512_256_BLOCK_SIZE - bytes_have; 648 if(length >= bytes_left) { 649 /* Combine new data with data in the buffer and process the full 650 block. */ 651 memcpy(((unsigned char *) ctx_buf) + bytes_have, 652 data, 653 bytes_left); 654 data += bytes_left; 655 length -= bytes_left; 656 Curl_sha512_256_transform(ctx->H, ctx->buffer); 657 bytes_have = 0; 658 } 659 } 660 661 while(CURL_SHA512_256_BLOCK_SIZE <= length) { 662 /* Process any full blocks of new data directly, 663 without copying to the buffer. */ 664 Curl_sha512_256_transform(ctx->H, data); 665 data += CURL_SHA512_256_BLOCK_SIZE; 666 length -= CURL_SHA512_256_BLOCK_SIZE; 667 } 668 669 if(0 != length) { 670 /* Copy incomplete block of new data (if any) 671 to the buffer. */ 672 memcpy(((unsigned char *) ctx_buf) + bytes_have, data, length); 673 } 674 675 return CURLE_OK; 676 } 677 678 679 680 /** 681 * Size of "length" insertion in bits. 682 * See FIPS PUB 180-4 section 5.1.2. 683 */ 684 #define SHA512_256_SIZE_OF_LEN_ADD_BITS 128 685 686 /** 687 * Size of "length" insertion in bytes. 688 */ 689 #define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8) 690 691 /** 692 * Finalise SHA-512/256 calculation, return digest. 693 * 694 * @param context the calculation context 695 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE 696 # bytes 697 * @return always CURLE_OK 698 */ 699 static CURLcode 700 Curl_sha512_256_finish(unsigned char *digest, 701 void *context) 702 { 703 struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context; 704 curl_uint64_t num_bits; /**< Number of processed bits */ 705 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 706 /* the void pointer here is required to mute Intel compiler warning */ 707 void *const ctx_buf = ctx->buffer; 708 709 /* Memorise the number of processed bits. 710 The padding and other data added here during the postprocessing must 711 not change the amount of hashed data. */ 712 num_bits = ctx->count << 3; 713 714 /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) 715 equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ 716 bytes_have = (unsigned int) (ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); 717 718 /* Input data must be padded with a single bit "1", then with zeros and 719 the finally the length of data in bits must be added as the final bytes 720 of the last block. 721 See FIPS PUB 180-4 section 5.1.2. */ 722 723 /* Data is always processed in form of bytes (not by individual bits), 724 therefore position of the first padding bit in byte is always 725 predefined (0x80). */ 726 /* Buffer always have space at least for one byte (as full buffers are 727 processed when formed). */ 728 ((unsigned char *) ctx_buf)[bytes_have++] = 0x80U; 729 730 if(CURL_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) { 731 /* No space in the current block to put the total length of message. 732 Pad the current block with zeros and process it. */ 733 if(bytes_have < CURL_SHA512_256_BLOCK_SIZE) 734 memset(((unsigned char *) ctx_buf) + bytes_have, 0, 735 CURL_SHA512_256_BLOCK_SIZE - bytes_have); 736 /* Process the full block. */ 737 Curl_sha512_256_transform(ctx->H, ctx->buffer); 738 /* Start the new block. */ 739 bytes_have = 0; 740 } 741 742 /* Pad the rest of the buffer with zeros. */ 743 memset(((unsigned char *) ctx_buf) + bytes_have, 0, 744 CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); 745 /* Put high part of number of bits in processed message and then lower 746 part of number of bits as big-endian values. 747 See FIPS PUB 180-4 section 5.1.2. */ 748 /* Note: the target location is predefined and buffer is always aligned */ 749 CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ 750 + CURL_SHA512_256_BLOCK_SIZE \ 751 - SHA512_256_SIZE_OF_LEN_ADD, \ 752 ctx->count_bits_hi); 753 CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \ 754 + CURL_SHA512_256_BLOCK_SIZE \ 755 - SHA512_256_SIZE_OF_LEN_ADD \ 756 + SHA512_256_BYTES_IN_WORD, \ 757 num_bits); 758 /* Process the full final block. */ 759 Curl_sha512_256_transform(ctx->H, ctx->buffer); 760 761 /* Put in BE mode the leftmost part of the hash as the final digest. 762 See FIPS PUB 180-4 section 6.7. */ 763 764 CURL_PUT_64BIT_BE((digest + 0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]); 765 CURL_PUT_64BIT_BE((digest + 1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]); 766 CURL_PUT_64BIT_BE((digest + 2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]); 767 CURL_PUT_64BIT_BE((digest + 3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]); 768 769 /* Erase potentially sensitive data. */ 770 memset(ctx, 0, sizeof(struct Curl_sha512_256ctx)); 771 772 return CURLE_OK; 773 } 774 775 #endif /* Local SHA-512/256 code */ 776 777 778 /** 779 * Compute SHA-512/256 hash for the given data in one function call 780 * @param[out] output the pointer to put the hash 781 * @param[in] input the pointer to the data to process 782 * @param input_size the size of the data pointed by @a input 783 * @return always #CURLE_OK 784 */ 785 CURLcode 786 Curl_sha512_256it(unsigned char *output, const unsigned char *input, 787 size_t input_size) 788 { 789 Curl_sha512_256_ctx ctx; 790 CURLcode res; 791 792 res = Curl_sha512_256_init(&ctx); 793 if(res != CURLE_OK) 794 return res; 795 796 res = Curl_sha512_256_update(&ctx, (const void *) input, input_size); 797 798 if(res != CURLE_OK) { 799 (void) Curl_sha512_256_finish(output, &ctx); 800 return res; 801 } 802 803 return Curl_sha512_256_finish(output, &ctx); 804 } 805 806 /* Wrapper function, takes 'unsigned int' as length type, returns void */ 807 static void 808 Curl_sha512_256_update_i(void *context, 809 const unsigned char *data, 810 unsigned int length) 811 { 812 /* Hypothetically the function may fail, but assume it does not */ 813 (void) Curl_sha512_256_update(context, data, length); 814 } 815 816 /* Wrapper function, returns void */ 817 static void 818 Curl_sha512_256_finish_v(unsigned char *result, 819 void *context) 820 { 821 /* Hypothetically the function may fail, but assume it does not */ 822 (void) Curl_sha512_256_finish(result, context); 823 } 824 825 /* Wrapper function, takes 'unsigned int' as length type, returns void */ 826 827 const struct HMAC_params Curl_HMAC_SHA512_256[] = { 828 { 829 /* Initialize context procedure. */ 830 Curl_sha512_256_init, 831 /* Update context with data. */ 832 Curl_sha512_256_update_i, 833 /* Get final result procedure. */ 834 Curl_sha512_256_finish_v, 835 /* Context structure size. */ 836 sizeof(Curl_sha512_256_ctx), 837 /* Maximum key length (bytes). */ 838 CURL_SHA512_256_BLOCK_SIZE, 839 /* Result length (bytes). */ 840 CURL_SHA512_256_DIGEST_SIZE 841 } 842 }; 843 844 #endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */