Coverage Report

Created: 2025-08-11 09:23

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