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