Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmcurl/lib/curl_sha512_256.c
Line
Count
Source
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) Evgeny Grin (Karlson2k), <k2k@narod.ru>.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
#include "curl_setup.h"
25
26
#if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256)
27
28
#include "curl_sha512_256.h"
29
30
/* The recommended order of the TLS backends:
31
 * 1. USE_OPENSSL
32
 * 2. USE_WOLFSSL
33
 * 3. USE_GNUTLS
34
 * 4. USE_MBEDTLS (TBD)
35
 * 5. USE_RUSTLS (TBD)
36
 * 6. USE_WIN32_CRYPTO (TBD)
37
 * Skip the backend if it does not support the required algorithm */
38
39
#ifdef USE_OPENSSL
40
#  include <openssl/opensslv.h>
41
#  if !defined(LIBRESSL_VERSION_NUMBER) || \
42
  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3080000fL)
43
#    include <openssl/evp.h>
44
#    define USE_OPENSSL_SHA512_256          1
45
#    define HAS_SHA512_256_IMPLEMENTATION   1
46
#    ifdef __NetBSD__
47
/* Some NetBSD versions has a bug in SHA-512/256.
48
 * See https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039
49
 * The problematic versions:
50
 * - NetBSD before 9.4
51
 * - NetBSD 9 all development versions (9.99.x)
52
 * - NetBSD 10 development versions (10.99.x) before 10.99.11
53
 * The bug was fixed in NetBSD 9.4 release, NetBSD 10.0 release,
54
 * NetBSD 10.99.11 development.
55
 * It is safe to apply the workaround even if the bug is not present, as
56
 * the workaround reduces performance slightly. */
57
#      include <sys/param.h>
58
#      if  __NetBSD_Version__ <   904000000 ||  \
59
          (__NetBSD_Version__ >=  999000000 &&  \
60
           __NetBSD_Version__ <  1000000000) || \
61
          (__NetBSD_Version__ >= 1099000000 &&  \
62
           __NetBSD_Version__ <  1099001100)
63
#        define NEED_NETBSD_SHA512_256_WORKAROUND 1
64
#      endif
65
#    endif
66
#  endif
67
#endif /* USE_OPENSSL */
68
69
#if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_WOLFSSL)
70
#  include <wolfssl/options.h>
71
#  ifndef WOLFSSL_NOSHA512_256
72
#    define USE_WOLFSSL_SHA512_256          1
73
#    define HAS_SHA512_256_IMPLEMENTATION   1
74
#  endif
75
#endif
76
77
#if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS)
78
#  include <nettle/sha.h>
79
#  ifdef SHA512_256_DIGEST_SIZE
80
#    define USE_GNUTLS_SHA512_256           1
81
#  endif
82
#endif /* !HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */
83
84
#ifdef USE_OPENSSL_SHA512_256
85
86
/* OpenSSL does not provide macros for SHA-512/256 sizes */
87
88
/**
89
 * Size of the SHA-512/256 single processing block in bytes.
90
 */
91
#define CURL_SHA512_256_BLOCK_SIZE 128
92
93
/**
94
 * Size of the SHA-512/256 resulting digest in bytes.
95
 * This is the final digest size, not intermediate hash.
96
 */
97
#define CURL_SHA512_256_DIGEST_SIZE CURL_SHA512_256_DIGEST_LENGTH
98
99
/**
100
 * Context type used for SHA-512/256 calculations
101
 */
102
typedef EVP_MD_CTX *Curl_sha512_256_ctx;
103
104
/**
105
 * Initialise structure for SHA-512/256 calculation.
106
 *
107
 * @param context the calculation context
108
 * @return CURLE_OK if succeed,
109
 *         error code otherwise
110
 */
111
static CURLcode Curl_sha512_256_init(void *context)
112
{
113
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
114
115
  *ctx = EVP_MD_CTX_create();
116
  if(!*ctx)
117
    return CURLE_OUT_OF_MEMORY;
118
119
  if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) {
120
    /* Check whether the header and this file use the same numbers */
121
    DEBUGASSERT(EVP_MD_CTX_size(*ctx) == CURL_SHA512_256_DIGEST_SIZE);
122
    /* Check whether the block size is correct */
123
    DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == CURL_SHA512_256_BLOCK_SIZE);
124
125
    return CURLE_OK; /* Success */
126
  }
127
128
  /* Cleanup */
129
  EVP_MD_CTX_destroy(*ctx);
130
  return CURLE_FAILED_INIT;
131
}
132
133
/**
134
 * Process portion of bytes.
135
 *
136
 * @param context the calculation context
137
 * @param data bytes to add to hash
138
 * @return CURLE_OK if succeed,
139
 *         error code otherwise
140
 */
141
static CURLcode Curl_sha512_256_update(void *context,
142
                                       const unsigned char *data,
143
                                       size_t length)
144
{
145
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
146
147
  if(!EVP_DigestUpdate(*ctx, data, length))
148
    return CURLE_SSL_CIPHER;
149
150
  return CURLE_OK;
151
}
152
153
/**
154
 * Finalise SHA-512/256 calculation, return digest.
155
 *
156
 * @param context the calculation context
157
 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE
158
 *             bytes
159
 * @return CURLE_OK if succeed,
160
 *         error code otherwise
161
 */
162
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
163
{
164
  CURLcode result;
165
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
166
167
#ifdef NEED_NETBSD_SHA512_256_WORKAROUND
168
  /* Use a larger buffer to work around a bug in NetBSD:
169
     https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */
170
  unsigned char tmp_digest[CURL_SHA512_256_DIGEST_SIZE * 2];
171
  result = EVP_DigestFinal_ex(*ctx,
172
                           tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER;
173
  if(result == CURLE_OK)
174
    memcpy(digest, tmp_digest, CURL_SHA512_256_DIGEST_SIZE);
175
  explicit_memset(tmp_digest, 0, sizeof(tmp_digest));
176
#else /* !NEED_NETBSD_SHA512_256_WORKAROUND */
177
  result = EVP_DigestFinal_ex(*ctx, digest, NULL) ?
178
    CURLE_OK : CURLE_SSL_CIPHER;
179
#endif /* NEED_NETBSD_SHA512_256_WORKAROUND */
180
181
  EVP_MD_CTX_destroy(*ctx);
182
  *ctx = NULL;
183
184
  return result;
185
}
186
187
#elif defined(USE_WOLFSSL_SHA512_256)
188
#include <wolfssl/wolfcrypt/sha512.h>
189
190
#define CURL_SHA512_256_DIGEST_SIZE WC_SHA512_256_DIGEST_SIZE
191
#define CURL_SHA512_256_BLOCK_SIZE  WC_SHA512_256_BLOCK_SIZE
192
193
typedef struct wc_Sha512 Curl_sha512_256_ctx;
194
195
static CURLcode Curl_sha512_256_init(void *ctx)
196
{
197
  if(wc_InitSha512_256(ctx))
198
    return CURLE_FAILED_INIT;
199
  return CURLE_OK;
200
}
201
202
static CURLcode Curl_sha512_256_update(void *ctx,
203
                                       const unsigned char *data,
204
                                       size_t length)
205
{
206
  do {
207
    word32 ilen = (word32)CURLMIN(length, UINT_MAX);
208
    if(wc_Sha512_256Update(ctx, data, ilen))
209
      return CURLE_SSL_CIPHER;
210
    length -= ilen;
211
    data += ilen;
212
  } while(length);
213
  return CURLE_OK;
214
}
215
216
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *ctx)
217
{
218
  if(wc_Sha512_256Final(ctx, digest))
219
    return CURLE_SSL_CIPHER;
220
  return CURLE_OK;
221
}
222
223
#elif defined(USE_GNUTLS_SHA512_256)
224
225
#define CURL_SHA512_256_BLOCK_SIZE  SHA512_256_BLOCK_SIZE
226
#define CURL_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE
227
228
/**
229
 * Context type used for SHA-512/256 calculations
230
 */
231
typedef struct sha512_256_ctx Curl_sha512_256_ctx;
232
233
/**
234
 * Initialise structure for SHA-512/256 calculation.
235
 *
236
 * @param context the calculation context
237
 * @return always CURLE_OK
238
 */
239
static CURLcode Curl_sha512_256_init(void *context)
240
{
241
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
242
243
  /* Check whether the header and this file use the same numbers */
244
  DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE);
245
246
  sha512_256_init(ctx);
247
248
  return CURLE_OK;
249
}
250
251
/**
252
 * Process portion of bytes.
253
 *
254
 * @param context the calculation context
255
 * @param data bytes to add to hash
256
 * @param length number of bytes in @a data
257
 * @return always CURLE_OK
258
 */
259
static CURLcode Curl_sha512_256_update(void *context,
260
                                       const unsigned char *data,
261
                                       size_t length)
262
{
263
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
264
265
  DEBUGASSERT((data != NULL) || (length == 0));
266
267
  sha512_256_update(ctx, length, (const uint8_t *)data);
268
269
  return CURLE_OK;
270
}
271
272
/**
273
 * Finalise SHA-512/256 calculation, return digest.
274
 *
275
 * @param context the calculation context
276
 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE
277
 *             bytes
278
 * @return always CURLE_OK
279
 */
280
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
281
{
282
  Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context;
283
284
  sha512_256_digest(ctx,
285
                    (size_t)CURL_SHA512_256_DIGEST_SIZE, (uint8_t *)digest);
286
287
  return CURLE_OK;
288
}
289
290
#else /* No system or TLS backend SHA-512/256 implementation available */
291
292
/* ** This implementation of SHA-512/256 hash calculation was originally ** *
293
 * ** written by Evgeny Grin (Karlson2k) for GNU libmicrohttpd.          ** *
294
 * ** The author ported the code to libcurl. The ported code is provided ** *
295
 * ** under curl license.                                                ** */
296
297
#ifdef __GNUC__
298
#  if defined(__has_attribute) && defined(__STDC_VERSION__)
299
#    if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901
300
#      define CURL_FORCEINLINE CURL_INLINE __attribute__((always_inline))
301
#    endif
302
#  endif
303
#endif
304
305
#if !defined(CURL_FORCEINLINE) && \
306
  defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__)
307
#define CURL_FORCEINLINE __forceinline
308
#endif
309
310
/* Assume that 'CURL_INLINE' keyword works or the
311
 * macro was already defined correctly. */
312
#ifndef CURL_FORCEINLINE
313
#define CURL_FORCEINLINE CURL_INLINE
314
#endif
315
316
/* Bits manipulation macros and functions.
317
   Can be moved to other headers to reuse. */
318
319
#define CURL_GET_64BIT_BE(ptr)                       \
320
  (((uint64_t)(((const uint8_t *)(ptr))[0]) << 56) | \
321
   ((uint64_t)(((const uint8_t *)(ptr))[1]) << 48) | \
322
   ((uint64_t)(((const uint8_t *)(ptr))[2]) << 40) | \
323
   ((uint64_t)(((const uint8_t *)(ptr))[3]) << 32) | \
324
   ((uint64_t)(((const uint8_t *)(ptr))[4]) << 24) | \
325
   ((uint64_t)(((const uint8_t *)(ptr))[5]) << 16) | \
326
   ((uint64_t)(((const uint8_t *)(ptr))[6]) << 8)  | \
327
    (uint64_t)(((const uint8_t *)(ptr))[7]))
328
329
#define CURL_PUT_64BIT_BE(ptr, val)                             \
330
0
  do {                                                          \
331
0
    ((uint8_t *)(ptr))[7] = (uint8_t)((uint64_t)(val));         \
332
0
    ((uint8_t *)(ptr))[6] = (uint8_t)(((uint64_t)(val)) >> 8);  \
333
0
    ((uint8_t *)(ptr))[5] = (uint8_t)(((uint64_t)(val)) >> 16); \
334
0
    ((uint8_t *)(ptr))[4] = (uint8_t)(((uint64_t)(val)) >> 24); \
335
0
    ((uint8_t *)(ptr))[3] = (uint8_t)(((uint64_t)(val)) >> 32); \
336
0
    ((uint8_t *)(ptr))[2] = (uint8_t)(((uint64_t)(val)) >> 40); \
337
0
    ((uint8_t *)(ptr))[1] = (uint8_t)(((uint64_t)(val)) >> 48); \
338
0
    ((uint8_t *)(ptr))[0] = (uint8_t)(((uint64_t)(val)) >> 56); \
339
0
  } while(0)
340
341
/* Defined as a function. The macro version may duplicate the binary code
342
 * size as each argument is used twice, so if any calculation is used
343
 * as an argument, the calculation could be done twice. */
344
static CURL_FORCEINLINE uint64_t Curl_rotr64(uint64_t value, unsigned int bits)
345
0
{
346
0
  bits %= 64;
347
0
  if(bits == 0)
348
0
    return value;
349
  /* Defined in a form which modern compiler could optimize. */
350
0
  return (value >> bits) | (value << (64 - bits));
351
0
}
352
353
/* SHA-512/256 specific data */
354
355
/**
356
 * Number of bits in a single SHA-512/256 word.
357
 */
358
#define SHA512_256_WORD_SIZE_BITS 64
359
360
/**
361
 * Number of bytes in a single SHA-512/256 word.
362
 */
363
#define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8)
364
365
/**
366
 * Hash is kept internally as 8 64-bit words.
367
 * This is the intermediate hash size, used during computing the final digest.
368
 */
369
#define SHA512_256_HASH_SIZE_WORDS 8
370
371
/**
372
 * Size of the SHA-512/256 resulting digest in words.
373
 * This is the final digest size, not intermediate hash.
374
 */
375
#define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2)
376
377
/**
378
 * Size of the SHA-512/256 resulting digest in bytes
379
 * This is the final digest size, not intermediate hash.
380
 */
381
#define CURL_SHA512_256_DIGEST_SIZE \
382
  (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD)
383
384
/**
385
 * Size of the SHA-512/256 single processing block in bits.
386
 */
387
0
#define SHA512_256_BLOCK_SIZE_BITS 1024
388
389
/**
390
 * Size of the SHA-512/256 single processing block in bytes.
391
 */
392
0
#define CURL_SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8)
393
394
/**
395
 * Size of the SHA-512/256 single processing block in words.
396
 */
397
#define SHA512_256_BLOCK_SIZE_WORDS \
398
  (SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS)
399
400
/**
401
 * SHA-512/256 calculation context
402
 */
403
struct Curl_sha512_256ctx {
404
  /**
405
   * Intermediate hash value. The variable is properly aligned. Smart
406
   * compilers may automatically use fast load/store instruction for big
407
   * endian data on little endian machine.
408
   */
409
  uint64_t H[SHA512_256_HASH_SIZE_WORDS];
410
  /**
411
   * SHA-512/256 input data buffer. The buffer is properly aligned. Smart
412
   * compilers may automatically use fast load/store instruction for big
413
   * endian data on little endian machine.
414
   */
415
  uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS];
416
  /**
417
   * The number of bytes, lower part
418
   */
419
  uint64_t count;
420
  /**
421
   * The number of bits, high part. Unlike lower part, this counts the number
422
   * of bits, not bytes.
423
   */
424
  uint64_t count_bits_hi;
425
};
426
427
/**
428
 * Context type used for SHA-512/256 calculations
429
 */
430
typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx;
431
432
/**
433
 * Initialise structure for SHA-512/256 calculation.
434
 *
435
 * @param context the calculation context
436
 * @return always CURLE_OK
437
 */
438
static CURLcode Curl_sha512_256_init(void *context)
439
0
{
440
0
  struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
441
442
  /* Check whether the header and this file use the same numbers */
443
0
  DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE);
444
445
0
  DEBUGASSERT(sizeof(uint64_t) == 8);
446
447
  /* Initial hash values, see FIPS PUB 180-4 section 5.3.6.2 */
448
  /* Values generated by "IV Generation Function" as described in
449
   * section 5.3.6 */
450
0
  ctx->H[0] = UINT64_C(0x22312194FC2BF72C);
451
0
  ctx->H[1] = UINT64_C(0x9F555FA3C84C64C2);
452
0
  ctx->H[2] = UINT64_C(0x2393B86B6F53B151);
453
0
  ctx->H[3] = UINT64_C(0x963877195940EABD);
454
0
  ctx->H[4] = UINT64_C(0x96283EE2A88EFFE3);
455
0
  ctx->H[5] = UINT64_C(0xBE5E1E2553863992);
456
0
  ctx->H[6] = UINT64_C(0x2B0199FC2C85B8AA);
457
0
  ctx->H[7] = UINT64_C(0x0EB72DDC81C52CA2);
458
459
  /* Initialise number of bytes and high part of number of bits. */
460
0
  ctx->count = UINT64_C(0);
461
0
  ctx->count_bits_hi = UINT64_C(0);
462
463
0
  return CURLE_OK;
464
0
}
465
466
/**
467
 * Base of the SHA-512/256 transformation.
468
 * Gets a full 128 bytes block of data and updates hash values;
469
 * @param H     hash values
470
 * @param data  the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block
471
 */
472
static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS],
473
                                      const void *data)
474
0
{
475
  /* Working variables,
476
     see FIPS PUB 180-4 section 6.7, 6.4. */
477
0
  uint64_t a = H[0];
478
0
  uint64_t b = H[1];
479
0
  uint64_t c = H[2];
480
0
  uint64_t d = H[3];
481
0
  uint64_t e = H[4];
482
0
  uint64_t f = H[5];
483
0
  uint64_t g = H[6];
484
0
  uint64_t h = H[7];
485
486
  /* Data buffer, used as a cyclic buffer.
487
     See FIPS PUB 180-4 section 5.2.2, 6.7, 6.4. */
488
0
  uint64_t W[16];
489
490
  /* 'Ch' and 'Maj' macro functions are defined with widely-used optimization.
491
     See FIPS PUB 180-4 formulae 4.8, 4.9. */
492
0
#define Sha512_Ch(x, y, z)    ((z) ^ ((x) & ((y) ^ (z))))
493
0
#define Sha512_Maj(x, y, z)   (((x) & (y)) ^ ((z) & ((x) ^ (y))))
494
495
  /* Four 'Sigma' macro functions.
496
     See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */
497
0
#define SIG0(x)                                                  \
498
0
  (Curl_rotr64(x, 28) ^ Curl_rotr64(x, 34) ^ Curl_rotr64(x, 39))
499
0
#define SIG1(x)                                                  \
500
0
  (Curl_rotr64(x, 14) ^ Curl_rotr64(x, 18) ^ Curl_rotr64(x, 41))
501
0
#define sig0(x)                                                  \
502
0
  (Curl_rotr64(x,  1) ^ Curl_rotr64(x,  8) ^ ((x) >> 7))
503
0
#define sig1(x)                                                  \
504
0
  (Curl_rotr64(x, 19) ^ Curl_rotr64(x, 61) ^ ((x) >> 6))
505
506
0
  if(1) {
507
0
    unsigned int t;
508
    /* K constants array.
509
       See FIPS PUB 180-4 section 4.2.3 for K values. */
510
0
    static const uint64_t K[80] = {
511
0
      UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
512
0
      UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
513
0
      UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
514
0
      UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
515
0
      UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
516
0
      UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
517
0
      UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
518
0
      UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
519
0
      UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
520
0
      UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
521
0
      UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
522
0
      UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
523
0
      UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
524
0
      UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
525
0
      UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
526
0
      UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
527
0
      UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
528
0
      UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
529
0
      UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
530
0
      UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
531
0
      UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
532
0
      UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
533
0
      UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
534
0
      UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
535
0
      UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
536
0
      UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
537
0
      UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
538
0
      UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
539
0
      UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
540
0
      UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
541
0
      UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
542
0
      UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
543
0
      UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
544
0
      UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
545
0
      UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
546
0
      UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
547
0
      UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
548
0
      UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
549
0
      UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
550
0
      UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
551
0
    };
552
553
    /* One step of SHA-512/256 computation,
554
       see FIPS PUB 180-4 section 6.4.2 step 3.
555
       * Note: this macro updates working variables in-place, without rotation.
556
       * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in
557
       FIPS PUB 180-4 section 6.4.2 step 3.
558
       the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in
559
       FIPS PUB 180-4 section 6.4.2 step 3.
560
       * Note: 'wt' must be used exactly one time in this macro as macro for
561
       'wt' calculation may change other data as well every time when
562
       used. */
563
0
#define SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt)                    \
564
0
  do {                                                                        \
565
0
    (vD) += ((vH) += SIG1(vE) + Sha512_Ch(vE, vF, vG) + (kt) + (wt));         \
566
0
    (vH) += SIG0(vA) + Sha512_Maj(vA, vB, vC);                                \
567
0
  } while(0)
568
569
    /* One step of SHA-512/256 computation with working variables rotation,
570
       see FIPS PUB 180-4 section 6.4.2 step 3. This macro version reassigns
571
       all working variables on each step. */
572
0
#define SHA2STEP64RV(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt)                  \
573
0
  do {                                                                        \
574
0
    uint64_t tmp_h_ = (vH);                                                   \
575
0
    SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, tmp_h_, kt, wt);                   \
576
0
    (vH) = (vG);                                                              \
577
0
    (vG) = (vF);                                                              \
578
0
    (vF) = (vE);                                                              \
579
0
    (vE) = (vD);                                                              \
580
0
    (vD) = (vC);                                                              \
581
0
    (vC) = (vB);                                                              \
582
0
    (vB) = (vA);                                                              \
583
0
    (vA) = tmp_h_;                                                            \
584
0
  } while(0)
585
586
    /* Get value of W(t) from input data buffer for 0 <= t <= 15,
587
       See FIPS PUB 180-4 section 6.2.
588
       Input data must be read in big-endian bytes order,
589
       see FIPS PUB 180-4 section 3.1.2. */
590
0
#define SHA512_GET_W_FROM_DATA(buf, t) \
591
0
  CURL_GET_64BIT_BE((const uint8_t *)(buf) + ((t) * SHA512_256_BYTES_IN_WORD))
592
593
    /* During first 16 steps, before making any calculation on each step, the
594
       W element is read from the input data buffer as a big-endian value and
595
       stored in the array of W elements. */
596
0
    for(t = 0; t < 16; ++t) {
597
0
      SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t],
598
0
                   W[t] = SHA512_GET_W_FROM_DATA(data, t));
599
0
    }
600
601
    /* 'W' generation and assignment for 16 <= t <= 79.
602
       See FIPS PUB 180-4 section 6.4.2.
603
       As only the last 16 'W' are used in calculations, it is possible to
604
       use 16 elements array of W as a cyclic buffer.
605
       Note: ((t-16) & 15) have same value as (t & 15) */
606
0
#define Wgen(w, t)                                               \
607
0
  (uint64_t)((w)[((t) - 16) & 15] + sig1((w)[((t) -  2) & 15]) + \
608
0
             (w)[((t) -  7) & 15] + sig0((w)[((t) - 15) & 15]))
609
610
    /* During the last 64 steps, before making any calculation on each step,
611
       current W element is generated from other W elements of the cyclic
612
       buffer and the generated value is stored back in the cyclic buffer. */
613
0
    for(t = 16; t < 80; ++t) {
614
0
      SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t],
615
0
                   W[t & 15] = Wgen(W, t));
616
0
    }
617
0
  }
618
619
  /* Compute and store the intermediate hash.
620
     See FIPS PUB 180-4 section 6.4.2 step 4. */
621
0
  H[0] += a;
622
0
  H[1] += b;
623
0
  H[2] += c;
624
0
  H[3] += d;
625
0
  H[4] += e;
626
0
  H[5] += f;
627
0
  H[6] += g;
628
0
  H[7] += h;
629
0
}
630
631
/**
632
 * Process portion of bytes.
633
 *
634
 * @param context the calculation context
635
 * @param data bytes to add to hash
636
 * @param length number of bytes in @a data
637
 * @return always CURLE_OK
638
 */
639
static CURLcode Curl_sha512_256_update(void *context,
640
                                       const unsigned char *data,
641
                                       size_t length)
642
0
{
643
0
  unsigned int bytes_have; /* Number of bytes in the context buffer */
644
0
  struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
645
  /* the void pointer here is required to mute Intel compiler warning */
646
0
  void * const ctx_buf = ctx->buffer;
647
648
0
  DEBUGASSERT((data != NULL) || (length == 0));
649
650
0
  if(length == 0)
651
0
    return CURLE_OK; /* Shortcut, do nothing */
652
653
  /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1))
654
     equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */
655
0
  bytes_have = (unsigned int)(ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1));
656
0
  ctx->count += length;
657
0
  if(length > ctx->count)
658
0
    ctx->count_bits_hi += 1U << 3; /* Value wrap */
659
0
  ctx->count_bits_hi += ctx->count >> 61;
660
0
  ctx->count &= UINT64_C(0x1FFFFFFFFFFFFFFF);
661
662
0
  if(bytes_have) {
663
0
    unsigned int bytes_left = CURL_SHA512_256_BLOCK_SIZE - bytes_have;
664
0
    if(length >= bytes_left) {
665
      /* Combine new data with data in the buffer and process the full
666
         block. */
667
0
      memcpy((unsigned char *)ctx_buf + bytes_have, data, bytes_left);
668
0
      data += bytes_left;
669
0
      length -= bytes_left;
670
0
      Curl_sha512_256_transform(ctx->H, ctx->buffer);
671
0
      bytes_have = 0;
672
0
    }
673
0
  }
674
675
0
  while(CURL_SHA512_256_BLOCK_SIZE <= length) {
676
    /* Process any full blocks of new data directly,
677
       without copying to the buffer. */
678
0
    Curl_sha512_256_transform(ctx->H, data);
679
0
    data += CURL_SHA512_256_BLOCK_SIZE;
680
0
    length -= CURL_SHA512_256_BLOCK_SIZE;
681
0
  }
682
683
0
  if(length) {
684
    /* Copy incomplete block of new data (if any)
685
       to the buffer. */
686
0
    memcpy((unsigned char *)ctx_buf + bytes_have, data, length);
687
0
  }
688
689
0
  return CURLE_OK;
690
0
}
691
692
/**
693
 * Size of "length" insertion in bits.
694
 * See FIPS PUB 180-4 section 5.1.2.
695
 */
696
0
#define SHA512_256_SIZE_OF_LEN_ADD_BITS 128
697
698
/**
699
 * Size of "length" insertion in bytes.
700
 */
701
0
#define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8)
702
703
/**
704
 * Finalise SHA-512/256 calculation, return digest.
705
 *
706
 * @param context the calculation context
707
 * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE
708
 *             bytes
709
 * @return always CURLE_OK
710
 */
711
static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context)
712
0
{
713
0
  struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context;
714
0
  uint64_t num_bits;   /* Number of processed bits */
715
0
  unsigned int bytes_have; /* Number of bytes in the context buffer */
716
  /* the void pointer here is required to mute Intel compiler warning */
717
0
  void * const ctx_buf = ctx->buffer;
718
719
  /* Memorise the number of processed bits.
720
     The padding and other data added here during the postprocessing must
721
     not change the amount of hashed data. */
722
0
  num_bits = ctx->count << 3;
723
724
  /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1))
725
           equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */
726
0
  bytes_have = (unsigned int)(ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1));
727
728
  /* Input data must be padded with a single bit "1", then with zeros and
729
     the finally the length of data in bits must be added as the final bytes
730
     of the last block.
731
     See FIPS PUB 180-4 section 5.1.2. */
732
733
  /* Data is always processed in form of bytes (not by individual bits),
734
     therefore position of the first padding bit in byte is always
735
     predefined (0x80). */
736
  /* Buffer always have space at least for one byte (as full buffers are
737
     processed when formed). */
738
0
  ((unsigned char *)ctx_buf)[bytes_have++] = 0x80U;
739
740
0
  if(CURL_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) {
741
    /* No space in the current block to put the total length of message.
742
       Pad the current block with zeros and process it. */
743
0
    if(bytes_have < CURL_SHA512_256_BLOCK_SIZE)
744
0
      memset((unsigned char *)ctx_buf + bytes_have, 0,
745
0
             CURL_SHA512_256_BLOCK_SIZE - bytes_have);
746
    /* Process the full block. */
747
0
    Curl_sha512_256_transform(ctx->H, ctx->buffer);
748
    /* Start the new block. */
749
0
    bytes_have = 0;
750
0
  }
751
752
  /* Pad the rest of the buffer with zeros. */
753
0
  memset((unsigned char *)ctx_buf + bytes_have, 0,
754
0
         CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have);
755
  /* Put high part of number of bits in processed message and then lower
756
     part of number of bits as big-endian values.
757
     See FIPS PUB 180-4 section 5.1.2. */
758
  /* Note: the target location is predefined and buffer is always aligned */
759
0
  CURL_PUT_64BIT_BE((unsigned char *)ctx_buf +
760
0
                    CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD,
761
0
                    ctx->count_bits_hi);
762
0
  CURL_PUT_64BIT_BE((unsigned char *)ctx_buf +
763
0
                    CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD +
764
0
                    SHA512_256_BYTES_IN_WORD,
765
0
                    num_bits);
766
  /* Process the full final block. */
767
0
  Curl_sha512_256_transform(ctx->H, ctx->buffer);
768
769
  /* Put in BE mode the leftmost part of the hash as the final digest.
770
     See FIPS PUB 180-4 section 6.7. */
771
772
0
  CURL_PUT_64BIT_BE(digest + (0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]);
773
0
  CURL_PUT_64BIT_BE(digest + (1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]);
774
0
  CURL_PUT_64BIT_BE(digest + (2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]);
775
0
  CURL_PUT_64BIT_BE(digest + (3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]);
776
777
  /* Erase potentially sensitive data. */
778
0
  memset(ctx, 0, sizeof(struct Curl_sha512_256ctx));
779
780
0
  return CURLE_OK;
781
0
}
782
783
#endif /* Local SHA-512/256 code */
784
785
/**
786
 * Compute SHA-512/256 hash for the given data in one function call
787
 * @param[out] output the pointer to put the hash
788
 * @param[in] input the pointer to the data to process
789
 * @param input_size the size of the data pointed by @a input
790
 * @return always #CURLE_OK
791
 */
792
CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input,
793
                           size_t input_size)
794
0
{
795
0
  Curl_sha512_256_ctx ctx;
796
0
  CURLcode result;
797
798
0
  result = Curl_sha512_256_init(&ctx);
799
0
  if(result != CURLE_OK)
800
0
    return result;
801
802
0
  result = Curl_sha512_256_update(&ctx, (const void *)input, input_size);
803
804
0
  if(result != CURLE_OK) {
805
0
    (void)Curl_sha512_256_finish(output, &ctx);
806
0
    return result;
807
0
  }
808
809
0
  return Curl_sha512_256_finish(output, &ctx);
810
0
}
811
812
/* Wrapper function, takes 'unsigned int' as length type, returns void */
813
static void Curl_sha512_256_update_i(void *context,
814
                                     const unsigned char *data,
815
                                     unsigned int length)
816
0
{
817
  /* Hypothetically the function may fail, but assume it does not */
818
0
  (void)Curl_sha512_256_update(context, data, length);
819
0
}
820
821
/* Wrapper function, returns void */
822
static void Curl_sha512_256_finish_v(unsigned char *result, void *context)
823
0
{
824
  /* Hypothetically the function may fail, but assume it does not */
825
0
  (void)Curl_sha512_256_finish(result, context);
826
0
}
827
828
/* Wrapper function, takes 'unsigned int' as length type, returns void */
829
830
const struct HMAC_params Curl_HMAC_SHA512_256[] = {
831
  {
832
    /* Initialize context procedure. */
833
    Curl_sha512_256_init,
834
    /* Update context with data. */
835
    Curl_sha512_256_update_i,
836
    /* Get final result procedure. */
837
    Curl_sha512_256_finish_v,
838
    /* Context structure size. */
839
    sizeof(Curl_sha512_256_ctx),
840
    /* Maximum key length (bytes). */
841
    CURL_SHA512_256_BLOCK_SIZE,
842
    /* Result length (bytes). */
843
    CURL_SHA512_256_DIGEST_SIZE
844
  }
845
};
846
847
#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */