1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
9 * Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ***************************************************************************/
24 #include "curl_setup.h"
26 #ifndef CURL_DISABLE_CRYPTO_AUTH
29 #include "curl_sha256.h"
30 #include "curl_hmac.h"
33 #include <wolfssl/options.h>
35 #define USE_OPENSSL_SHA256
39 #if defined(USE_OPENSSL)
41 #include <openssl/opensslv.h>
43 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
44 #define USE_OPENSSL_SHA256
47 #endif /* USE_OPENSSL */
50 #include <mbedtls/version.h>
52 #if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
53 (MBEDTLS_VERSION_NUMBER < 0x03000000)
54 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
56 #endif /* USE_MBEDTLS */
58 /* Please keep the SSL backend-specific #if branches in this order:
63 * 4. USE_COMMON_CRYPTO
66 * This ensures that the same SSL branch gets activated throughout this source
67 * file even if multiple backends are enabled at the same time.
70 #if defined(USE_OPENSSL_SHA256)
72 /* When OpenSSL or wolfSSL is available is available we use their
75 #if defined(USE_OPENSSL)
76 #include <openssl/evp.h>
77 #elif defined(USE_WOLFSSL)
78 #include <wolfssl/openssl/evp.h>
81 #include "curl_memory.h"
83 /* The last #include file should be: */
87 EVP_MD_CTX *openssl_ctx;
89 typedef struct sha256_ctx my_sha256_ctx;
91 static CURLcode my_sha256_init(my_sha256_ctx *ctx)
93 ctx->openssl_ctx = EVP_MD_CTX_create();
95 return CURLE_OUT_OF_MEMORY;
97 EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL);
101 static void my_sha256_update(my_sha256_ctx *ctx,
102 const unsigned char *data,
105 EVP_DigestUpdate(ctx->openssl_ctx, data, length);
108 static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
110 EVP_DigestFinal_ex(ctx->openssl_ctx, digest, NULL);
111 EVP_MD_CTX_destroy(ctx->openssl_ctx);
114 #elif defined(USE_GNUTLS)
116 #include <nettle/sha.h>
118 #include "curl_memory.h"
120 /* The last #include file should be: */
121 #include "memdebug.h"
123 typedef struct sha256_ctx my_sha256_ctx;
125 static CURLcode my_sha256_init(my_sha256_ctx *ctx)
131 static void my_sha256_update(my_sha256_ctx *ctx,
132 const unsigned char *data,
135 sha256_update(ctx, length, data);
138 static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
140 sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
143 #elif defined(USE_MBEDTLS)
145 #include <mbedtls/sha256.h>
147 #include "curl_memory.h"
149 /* The last #include file should be: */
150 #include "memdebug.h"
152 typedef mbedtls_sha256_context my_sha256_ctx;
154 static CURLcode my_sha256_init(my_sha256_ctx *ctx)
156 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
157 (void) mbedtls_sha256_starts(ctx, 0);
159 (void) mbedtls_sha256_starts_ret(ctx, 0);
164 static void my_sha256_update(my_sha256_ctx *ctx,
165 const unsigned char *data,
168 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
169 (void) mbedtls_sha256_update(ctx, data, length);
171 (void) mbedtls_sha256_update_ret(ctx, data, length);
175 static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
177 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
178 (void) mbedtls_sha256_finish(ctx, digest);
180 (void) mbedtls_sha256_finish_ret(ctx, digest);
184 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
185 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
186 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
187 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
189 #include <CommonCrypto/CommonDigest.h>
191 #include "curl_memory.h"
193 /* The last #include file should be: */
194 #include "memdebug.h"
196 typedef CC_SHA256_CTX my_sha256_ctx;
198 static CURLcode my_sha256_init(my_sha256_ctx *ctx)
200 (void) CC_SHA256_Init(ctx);
204 static void my_sha256_update(my_sha256_ctx *ctx,
205 const unsigned char *data,
208 (void) CC_SHA256_Update(ctx, data, length);
211 static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
213 (void) CC_SHA256_Final(digest, ctx);
216 #elif defined(USE_WIN32_CRYPTO)
218 #include <wincrypt.h>
221 HCRYPTPROV hCryptProv;
224 typedef struct sha256_ctx my_sha256_ctx;
226 #if !defined(CALG_SHA_256)
227 #define CALG_SHA_256 0x0000800c
230 static CURLcode my_sha256_init(my_sha256_ctx *ctx)
232 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
233 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
234 CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
240 static void my_sha256_update(my_sha256_ctx *ctx,
241 const unsigned char *data,
244 CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
247 static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
249 unsigned long length = 0;
251 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
252 if(length == SHA256_DIGEST_LENGTH)
253 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
256 CryptDestroyHash(ctx->hHash);
259 CryptReleaseContext(ctx->hCryptProv, 0);
264 /* When no other crypto library is available we use this code segment */
266 /* This is based on SHA256 implementation in LibTomCrypt that was released into
267 * public domain by Tom St Denis. */
269 #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
270 (((unsigned long)(a)[1]) << 16) | \
271 (((unsigned long)(a)[2]) << 8) | \
272 ((unsigned long)(a)[3]))
273 #define WPA_PUT_BE32(a, val) \
275 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
276 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
277 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \
278 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \
282 #define WPA_PUT_BE64(a, val) \
284 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \
285 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \
286 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \
287 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \
288 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \
289 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \
290 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \
291 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
294 #define WPA_PUT_BE64(a, val) \
296 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \
297 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \
298 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \
299 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \
300 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \
301 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \
302 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \
303 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
307 struct sha256_state {
309 unsigned long long length;
311 unsigned __int64 length;
313 unsigned long state[8], curlen;
314 unsigned char buf[64];
316 typedef struct sha256_state my_sha256_ctx;
319 static const unsigned long K[64] = {
320 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
321 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
322 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
323 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
324 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
325 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
326 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
327 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
328 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
329 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
330 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
331 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
332 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
335 /* Various logical functions */
337 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
338 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
339 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
340 #define Maj(x,y,z) (((x | y) & z) | (x & y))
341 #define S(x, n) RORc((x), (n))
342 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
343 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
344 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
345 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
346 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
348 /* Compress 512-bits */
349 static int sha256_compress(struct sha256_state *md,
352 unsigned long S[8], W[64];
355 /* Copy state into S */
356 for(i = 0; i < 8; i++) {
359 /* copy the state into 512-bits into W[0..15] */
360 for(i = 0; i < 16; i++)
361 W[i] = WPA_GET_BE32(buf + (4 * i));
363 for(i = 16; i < 64; i++) {
364 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
369 #define RND(a,b,c,d,e,f,g,h,i) \
371 unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
372 unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
377 for(i = 0; i < 64; ++i) {
379 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
380 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
381 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
385 for(i = 0; i < 8; i++) {
386 md->state[i] = md->state[i] + S[i];
392 /* Initialize the hash state */
393 static CURLcode my_sha256_init(struct sha256_state *md)
397 md->state[0] = 0x6A09E667UL;
398 md->state[1] = 0xBB67AE85UL;
399 md->state[2] = 0x3C6EF372UL;
400 md->state[3] = 0xA54FF53AUL;
401 md->state[4] = 0x510E527FUL;
402 md->state[5] = 0x9B05688CUL;
403 md->state[6] = 0x1F83D9ABUL;
404 md->state[7] = 0x5BE0CD19UL;
410 Process a block of memory though the hash
411 @param md The hash state
412 @param in The data to hash
413 @param inlen The length of the data (octets)
414 @return 0 if successful
416 static int my_sha256_update(struct sha256_state *md,
417 const unsigned char *in,
422 #define block_size 64
423 if(md->curlen > sizeof(md->buf))
426 if(md->curlen == 0 && inlen >= block_size) {
427 if(sha256_compress(md, (unsigned char *)in) < 0)
429 md->length += block_size * 8;
434 n = CURLMIN(inlen, (block_size - md->curlen));
435 memcpy(md->buf + md->curlen, in, n);
439 if(md->curlen == block_size) {
440 if(sha256_compress(md, md->buf) < 0)
442 md->length += 8 * block_size;
452 Terminate the hash to get the digest
453 @param md The hash state
454 @param out [out] The destination of the hash (32 bytes)
455 @return 0 if successful
457 static int my_sha256_final(unsigned char *out,
458 struct sha256_state *md)
462 if(md->curlen >= sizeof(md->buf))
465 /* Increase the length of the message */
466 md->length += md->curlen * 8;
468 /* Append the '1' bit */
469 md->buf[md->curlen++] = (unsigned char)0x80;
471 /* If the length is currently above 56 bytes we append zeros
472 * then compress. Then we can fall back to padding zeros and length
473 * encoding like normal.
475 if(md->curlen > 56) {
476 while(md->curlen < 64) {
477 md->buf[md->curlen++] = (unsigned char)0;
479 sha256_compress(md, md->buf);
483 /* Pad up to 56 bytes of zeroes */
484 while(md->curlen < 56) {
485 md->buf[md->curlen++] = (unsigned char)0;
489 WPA_PUT_BE64(md->buf + 56, md->length);
490 sha256_compress(md, md->buf);
493 for(i = 0; i < 8; i++)
494 WPA_PUT_BE32(out + (4 * i), md->state[i]);
499 #endif /* CRYPTO LIBS */
504 * Generates a SHA256 hash for the given input data.
508 * output [in/out] - The output buffer.
509 * input [in] - The input data.
510 * length [in] - The input length.
512 * Returns CURLE_OK on success.
514 CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
520 result = my_sha256_init(&ctx);
522 my_sha256_update(&ctx, input, curlx_uztoui(length));
523 my_sha256_final(output, &ctx);
529 const struct HMAC_params Curl_HMAC_SHA256[] = {
531 /* Hash initialization function. */
532 CURLX_FUNCTION_CAST(HMAC_hinit_func, my_sha256_init),
533 /* Hash update function. */
534 CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_sha256_update),
535 /* Hash computation end function. */
536 CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_sha256_final),
537 /* Size of hash context structure. */
538 sizeof(my_sha256_ctx),
539 /* Maximum key length. */
547 #endif /* CURL_DISABLE_CRYPTO_AUTH */