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