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