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