quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

curl_sha512_256.c (30617B)


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