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