Coverage Report

Created: 2022-10-16 06:45

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