1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Florin Petriuc, <petriuc.florin@gmail.com> 9 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 10 * 11 * This software is licensed as described in the file COPYING, which 12 * you should have received as part of this distribution. The terms 13 * are also available at https://curl.se/docs/copyright.html. 14 * 15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 16 * copies of the Software, and permit persons to whom the Software is 17 * furnished to do so, under the terms of the COPYING file. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 * SPDX-License-Identifier: curl 23 * 24 ***************************************************************************/ 25 26#include "curl_setup.h" 27 28#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \ 29 || defined(USE_LIBSSH2) 30 31#include "warnless.h" 32#include "curl_sha256.h" 33#include "curl_hmac.h" 34 35#ifdef USE_WOLFSSL 36#include <wolfssl/options.h> 37#ifndef NO_SHA256 38#define USE_OPENSSL_SHA256 39#endif 40#endif 41 42#if defined(USE_OPENSSL) 43 44#include <openssl/opensslv.h> 45 46#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) 47#define USE_OPENSSL_SHA256 48#endif 49 50#endif /* USE_OPENSSL */ 51 52#ifdef USE_MBEDTLS 53#include <mbedtls/version.h> 54 55#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \ 56 (MBEDTLS_VERSION_NUMBER < 0x03000000) 57 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS 58#endif 59#endif /* USE_MBEDTLS */ 60 61#if defined(USE_OPENSSL_SHA256) 62 63/* When OpenSSL or wolfSSL is available we use their SHA256-functions. */ 64#if defined(USE_OPENSSL) 65#include <openssl/evp.h> 66#elif defined(USE_WOLFSSL) 67#include <wolfssl/openssl/evp.h> 68#endif 69 70#elif defined(USE_GNUTLS) 71#include <nettle/sha.h> 72#elif defined(USE_MBEDTLS) 73#include <mbedtls/sha256.h> 74#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ 75 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ 76 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ 77 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) 78#include <CommonCrypto/CommonDigest.h> 79#define AN_APPLE_OS 80#elif defined(USE_WIN32_CRYPTO) 81#include <wincrypt.h> 82#endif 83 84/* The last 3 #include files should be in this order */ 85#include "curl_printf.h" 86#include "curl_memory.h" 87#include "memdebug.h" 88 89/* Please keep the SSL backend-specific #if branches in this order: 90 * 91 * 1. USE_OPENSSL 92 * 2. USE_GNUTLS 93 * 3. USE_MBEDTLS 94 * 4. USE_COMMON_CRYPTO 95 * 5. USE_WIN32_CRYPTO 96 * 97 * This ensures that the same SSL branch gets activated throughout this source 98 * file even if multiple backends are enabled at the same time. 99 */ 100 101#if defined(USE_OPENSSL_SHA256) 102 103struct sha256_ctx { 104 EVP_MD_CTX *openssl_ctx; 105}; 106typedef struct sha256_ctx my_sha256_ctx; 107 108static CURLcode my_sha256_init(my_sha256_ctx *ctx) 109{ 110 ctx->openssl_ctx = EVP_MD_CTX_create(); 111 if(!ctx->openssl_ctx) 112 return CURLE_OUT_OF_MEMORY; 113 114 if(!EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL)) { 115 EVP_MD_CTX_destroy(ctx->openssl_ctx); 116 return CURLE_FAILED_INIT; 117 } 118 return CURLE_OK; 119} 120 121static void my_sha256_update(my_sha256_ctx *ctx, 122 const unsigned char *data, 123 unsigned int length) 124{ 125 EVP_DigestUpdate(ctx->openssl_ctx, data, length); 126} 127 128static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) 129{ 130 EVP_DigestFinal_ex(ctx->openssl_ctx, digest, NULL); 131 EVP_MD_CTX_destroy(ctx->openssl_ctx); 132} 133 134#elif defined(USE_GNUTLS) 135 136typedef struct sha256_ctx my_sha256_ctx; 137 138static CURLcode my_sha256_init(my_sha256_ctx *ctx) 139{ 140 sha256_init(ctx); 141 return CURLE_OK; 142} 143 144static void my_sha256_update(my_sha256_ctx *ctx, 145 const unsigned char *data, 146 unsigned int length) 147{ 148 sha256_update(ctx, length, data); 149} 150 151static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) 152{ 153 sha256_digest(ctx, SHA256_DIGEST_SIZE, digest); 154} 155 156#elif defined(USE_MBEDTLS) 157 158typedef mbedtls_sha256_context my_sha256_ctx; 159 160static CURLcode my_sha256_init(my_sha256_ctx *ctx) 161{ 162#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 163 (void) mbedtls_sha256_starts(ctx, 0); 164#else 165 (void) mbedtls_sha256_starts_ret(ctx, 0); 166#endif 167 return CURLE_OK; 168} 169 170static void my_sha256_update(my_sha256_ctx *ctx, 171 const unsigned char *data, 172 unsigned int length) 173{ 174#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 175 (void) mbedtls_sha256_update(ctx, data, length); 176#else 177 (void) mbedtls_sha256_update_ret(ctx, data, length); 178#endif 179} 180 181static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) 182{ 183#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 184 (void) mbedtls_sha256_finish(ctx, digest); 185#else 186 (void) mbedtls_sha256_finish_ret(ctx, digest); 187#endif 188} 189 190#elif defined(AN_APPLE_OS) 191typedef CC_SHA256_CTX my_sha256_ctx; 192 193static CURLcode my_sha256_init(my_sha256_ctx *ctx) 194{ 195 (void) CC_SHA256_Init(ctx); 196 return CURLE_OK; 197} 198 199static void my_sha256_update(my_sha256_ctx *ctx, 200 const unsigned char *data, 201 unsigned int length) 202{ 203 (void) CC_SHA256_Update(ctx, data, length); 204} 205 206static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) 207{ 208 (void) CC_SHA256_Final(digest, ctx); 209} 210 211#elif defined(USE_WIN32_CRYPTO) 212 213struct sha256_ctx { 214 HCRYPTPROV hCryptProv; 215 HCRYPTHASH hHash; 216}; 217typedef struct sha256_ctx my_sha256_ctx; 218 219#if !defined(CALG_SHA_256) 220#define CALG_SHA_256 0x0000800c 221#endif 222 223static CURLcode my_sha256_init(my_sha256_ctx *ctx) 224{ 225 if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES, 226 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 227 return CURLE_OUT_OF_MEMORY; 228 229 if(!CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash)) { 230 CryptReleaseContext(ctx->hCryptProv, 0); 231 ctx->hCryptProv = 0; 232 return CURLE_FAILED_INIT; 233 } 234 235 return CURLE_OK; 236} 237 238static void my_sha256_update(my_sha256_ctx *ctx, 239 const unsigned char *data, 240 unsigned int length) 241{ 242 CryptHashData(ctx->hHash, (unsigned char *) data, length, 0); 243} 244 245static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx) 246{ 247 unsigned long length = 0; 248 249 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); 250 if(length == SHA256_DIGEST_LENGTH) 251 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); 252 253 if(ctx->hHash) 254 CryptDestroyHash(ctx->hHash); 255 256 if(ctx->hCryptProv) 257 CryptReleaseContext(ctx->hCryptProv, 0); 258} 259 260#else 261 262/* When no other crypto library is available we use this code segment */ 263 264/* This is based on SHA256 implementation in LibTomCrypt that was released into 265 * public domain by Tom St Denis. */ 266 267#define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \ 268 (((unsigned long)(a)[1]) << 16) | \ 269 (((unsigned long)(a)[2]) << 8) | \ 270 ((unsigned long)(a)[3])) 271#define WPA_PUT_BE32(a, val) \ 272do { \ 273 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \ 274 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \ 275 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \ 276 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \ 277} while(0) 278 279#ifdef HAVE_LONGLONG 280#define WPA_PUT_BE64(a, val) \ 281do { \ 282 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \ 283 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \ 284 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \ 285 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \ 286 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \ 287 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \ 288 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \ 289 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \ 290} while(0) 291#else 292#define WPA_PUT_BE64(a, val) \ 293do { \ 294 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \ 295 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \ 296 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \ 297 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \ 298 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \ 299 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \ 300 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \ 301 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \ 302} while(0) 303#endif 304 305struct sha256_state { 306#ifdef HAVE_LONGLONG 307 unsigned long long length; 308#else 309 unsigned __int64 length; 310#endif 311 unsigned long state[8], curlen; 312 unsigned char buf[64]; 313}; 314typedef struct sha256_state my_sha256_ctx; 315 316/* The K array */ 317static const unsigned long K[64] = { 318 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 319 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 320 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 321 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 322 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 323 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 324 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 325 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 326 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 327 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 328 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 329 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 330 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 331}; 332 333/* Various logical functions */ 334#define RORc(x, y) \ 335(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \ 336 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL) 337#define Ch(x,y,z) (z ^ (x & (y ^ z))) 338#define Maj(x,y,z) (((x | y) & z) | (x & y)) 339#define S(x, n) RORc((x), (n)) 340#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) 341#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 342#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 343#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 344#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 345 346/* Compress 512-bits */ 347static int sha256_compress(struct sha256_state *md, 348 unsigned char *buf) 349{ 350 unsigned long S[8], W[64]; 351 int i; 352 353 /* Copy state into S */ 354 for(i = 0; i < 8; i++) { 355 S[i] = md->state[i]; 356 } 357 /* copy the state into 512-bits into W[0..15] */ 358 for(i = 0; i < 16; i++) 359 W[i] = WPA_GET_BE32(buf + (4 * i)); 360 /* fill W[16..63] */ 361 for(i = 16; i < 64; i++) { 362 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + 363 W[i - 16]; 364 } 365 366 /* Compress */ 367#define RND(a,b,c,d,e,f,g,h,i) \ 368 do { \ 369 unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 370 unsigned long t1 = Sigma0(a) + Maj(a, b, c); \ 371 d += t0; \ 372 h = t0 + t1; \ 373 } while(0) 374 375 for(i = 0; i < 64; ++i) { 376 unsigned long t; 377 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); 378 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 379 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; 380 } 381 382 /* Feedback */ 383 for(i = 0; i < 8; i++) { 384 md->state[i] = md->state[i] + S[i]; 385 } 386 387 return 0; 388} 389 390/* Initialize the hash state */ 391static CURLcode my_sha256_init(struct sha256_state *md) 392{ 393 md->curlen = 0; 394 md->length = 0; 395 md->state[0] = 0x6A09E667UL; 396 md->state[1] = 0xBB67AE85UL; 397 md->state[2] = 0x3C6EF372UL; 398 md->state[3] = 0xA54FF53AUL; 399 md->state[4] = 0x510E527FUL; 400 md->state[5] = 0x9B05688CUL; 401 md->state[6] = 0x1F83D9ABUL; 402 md->state[7] = 0x5BE0CD19UL; 403 404 return CURLE_OK; 405} 406 407/* 408 Process a block of memory though the hash 409 @param md The hash state 410 @param in The data to hash 411 @param inlen The length of the data (octets) 412 @return 0 if successful 413*/ 414static int my_sha256_update(struct sha256_state *md, 415 const unsigned char *in, 416 unsigned long inlen) 417{ 418 unsigned long n; 419 420#define block_size 64 421 if(md->curlen > sizeof(md->buf)) 422 return -1; 423 while(inlen > 0) { 424 if(md->curlen == 0 && inlen >= block_size) { 425 if(sha256_compress(md, (unsigned char *)in) < 0) 426 return -1; 427 md->length += block_size * 8; 428 in += block_size; 429 inlen -= block_size; 430 } 431 else { 432 n = CURLMIN(inlen, (block_size - md->curlen)); 433 memcpy(md->buf + md->curlen, in, n); 434 md->curlen += n; 435 in += n; 436 inlen -= n; 437 if(md->curlen == block_size) { 438 if(sha256_compress(md, md->buf) < 0) 439 return -1; 440 md->length += 8 * block_size; 441 md->curlen = 0; 442 } 443 } 444 } 445 446 return 0; 447} 448 449/* 450 Terminate the hash to get the digest 451 @param md The hash state 452 @param out [out] The destination of the hash (32 bytes) 453 @return 0 if successful 454*/ 455static int my_sha256_final(unsigned char *out, 456 struct sha256_state *md) 457{ 458 int i; 459 460 if(md->curlen >= sizeof(md->buf)) 461 return -1; 462 463 /* Increase the length of the message */ 464 md->length += md->curlen * 8; 465 466 /* Append the '1' bit */ 467 md->buf[md->curlen++] = (unsigned char)0x80; 468 469 /* If the length is currently above 56 bytes we append zeros 470 * then compress. Then we can fall back to padding zeros and length 471 * encoding like normal. 472 */ 473 if(md->curlen > 56) { 474 while(md->curlen < 64) { 475 md->buf[md->curlen++] = (unsigned char)0; 476 } 477 sha256_compress(md, md->buf); 478 md->curlen = 0; 479 } 480 481 /* Pad up to 56 bytes of zeroes */ 482 while(md->curlen < 56) { 483 md->buf[md->curlen++] = (unsigned char)0; 484 } 485 486 /* Store length */ 487 WPA_PUT_BE64(md->buf + 56, md->length); 488 sha256_compress(md, md->buf); 489 490 /* Copy output */ 491 for(i = 0; i < 8; i++) 492 WPA_PUT_BE32(out + (4 * i), md->state[i]); 493 494 return 0; 495} 496 497#endif /* CRYPTO LIBS */ 498 499/* 500 * Curl_sha256it() 501 * 502 * Generates a SHA256 hash for the given input data. 503 * 504 * Parameters: 505 * 506 * output [in/out] - The output buffer. 507 * input [in] - The input data. 508 * length [in] - The input length. 509 * 510 * Returns CURLE_OK on success. 511 */ 512CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input, 513 const size_t length) 514{ 515 CURLcode result; 516 my_sha256_ctx ctx; 517 518 result = my_sha256_init(&ctx); 519 if(!result) { 520 my_sha256_update(&ctx, input, curlx_uztoui(length)); 521 my_sha256_final(output, &ctx); 522 } 523 return result; 524} 525 526 527const struct HMAC_params Curl_HMAC_SHA256[] = { 528 { 529 /* Hash initialization function. */ 530 CURLX_FUNCTION_CAST(HMAC_hinit_func, my_sha256_init), 531 /* Hash update function. */ 532 CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_sha256_update), 533 /* Hash computation end function. */ 534 CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_sha256_final), 535 /* Size of hash context structure. */ 536 sizeof(my_sha256_ctx), 537 /* Maximum key length. */ 538 64, 539 /* Result size. */ 540 32 541 } 542}; 543 544 545#endif /* AWS, DIGEST, or libSSH2 */ 546