Coverage Report

Created: 2026-04-12 06:56

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