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