Coverage Report

Created: 2025-08-26 07:09

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