Coverage Report

Created: 2026-02-09 06:05

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