Coverage Report

Created: 2025-12-14 06:23

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