1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
9 * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
10 *
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at https://curl.se/docs/copyright.html.
14 *
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24#include "curl_setup.h"
25
26#ifndef CURL_DISABLE_CRYPTO_AUTH
27
28#include "warnless.h"
29#include "curl_sha256.h"
30#include "curl_hmac.h"
31
32#if defined(USE_OPENSSL)
33
34#include <openssl/opensslv.h>
35
36#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
37#define USE_OPENSSL_SHA256
38#endif
39
40#endif /* USE_OPENSSL */
41
42#ifdef USE_MBEDTLS
43#include <mbedtls/version.h>
44
45#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
46 (MBEDTLS_VERSION_NUMBER < 0x03000000)
47 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
48#endif
49#endif /* USE_MBEDTLS */
50
51/* Please keep the SSL backend-specific #if branches in this order:
52 *
53 * 1. USE_OPENSSL
54 * 2. USE_GNUTLS
55 * 3. USE_MBEDTLS
56 * 4. USE_COMMON_CRYPTO
57 * 5. USE_WIN32_CRYPTO
58 *
59 * This ensures that the same SSL branch gets activated throughout this source
60 * file even if multiple backends are enabled at the same time.
61 */
62
63#if defined(USE_OPENSSL_SHA256)
64
65/* When OpenSSL is available we use the SHA256-function from OpenSSL */
66#include <openssl/sha.h>
67
68#elif defined(USE_GNUTLS)
69
70#include <nettle/sha.h>
71
72#include "curl_memory.h"
73
74/* The last #include file should be: */
75#include "memdebug.h"
76
77typedef struct sha256_ctx SHA256_CTX;
78
79static void SHA256_Init(SHA256_CTX *ctx)
80{
81 sha256_init(ctx);
82}
83
84static void SHA256_Update(SHA256_CTX *ctx,
85 const unsigned char *data,
86 unsigned int length)
87{
88 sha256_update(ctx, length, data);
89}
90
91static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
92{
93 sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
94}
95
96#elif defined(USE_MBEDTLS)
97
98#include <mbedtls/sha256.h>
99
100#include "curl_memory.h"
101
102/* The last #include file should be: */
103#include "memdebug.h"
104
105typedef mbedtls_sha256_context SHA256_CTX;
106
107static void SHA256_Init(SHA256_CTX *ctx)
108{
109#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
110 (void) mbedtls_sha256_starts(ctx, 0);
111#else
112 (void) mbedtls_sha256_starts_ret(ctx, 0);
113#endif
114}
115
116static void SHA256_Update(SHA256_CTX *ctx,
117 const unsigned char *data,
118 unsigned int length)
119{
120#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
121 (void) mbedtls_sha256_update(ctx, data, length);
122#else
123 (void) mbedtls_sha256_update_ret(ctx, data, length);
124#endif
125}
126
127static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
128{
129#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
130 (void) mbedtls_sha256_finish(ctx, digest);
131#else
132 (void) mbedtls_sha256_finish_ret(ctx, digest);
133#endif
134}
135
136#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
137 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
138 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
139 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
140
141#include <CommonCrypto/CommonDigest.h>
142
143#include "curl_memory.h"
144
145/* The last #include file should be: */
146#include "memdebug.h"
147
148typedef CC_SHA256_CTX SHA256_CTX;
149
150static void SHA256_Init(SHA256_CTX *ctx)
151{
152 (void) CC_SHA256_Init(ctx);
153}
154
155static void SHA256_Update(SHA256_CTX *ctx,
156 const unsigned char *data,
157 unsigned int length)
158{
159 (void) CC_SHA256_Update(ctx, data, length);
160}
161
162static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
163{
164 (void) CC_SHA256_Final(digest, ctx);
165}
166
167#elif defined(USE_WIN32_CRYPTO)
168
169#include <wincrypt.h>
170
171struct sha256_ctx {
172 HCRYPTPROV hCryptProv;
173 HCRYPTHASH hHash;
174};
175typedef struct sha256_ctx SHA256_CTX;
176
177#if !defined(CALG_SHA_256)
178#define CALG_SHA_256 0x0000800c
179#endif
180
181static void SHA256_Init(SHA256_CTX *ctx)
182{
183 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
184 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
185 CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
186 }
187}
188
189static void SHA256_Update(SHA256_CTX *ctx,
190 const unsigned char *data,
191 unsigned int length)
192{
193 CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
194}
195
196static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
197{
198 unsigned long length = 0;
199
200 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
201 if(length == SHA256_DIGEST_LENGTH)
202 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
203
204 if(ctx->hHash)
205 CryptDestroyHash(ctx->hHash);
206
207 if(ctx->hCryptProv)
208 CryptReleaseContext(ctx->hCryptProv, 0);
209}
210
211#else
212
213/* When no other crypto library is available we use this code segment */
214
215/* This is based on SHA256 implementation in LibTomCrypt that was released into
216 * public domain by Tom St Denis. */
217
218#define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
219 (((unsigned long)(a)[1]) << 16) | \
220 (((unsigned long)(a)[2]) << 8) | \
221 ((unsigned long)(a)[3]))
222#define WPA_PUT_BE32(a, val) \
223do { \
224 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
225 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
226 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \
227 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \
228} while(0)
229
230#ifdef HAVE_LONGLONG
231#define WPA_PUT_BE64(a, val) \
232do { \
233 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \
234 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \
235 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \
236 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \
237 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \
238 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \
239 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \
240 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
241} while(0)
242#else
243#define WPA_PUT_BE64(a, val) \
244do { \
245 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \
246 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \
247 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \
248 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \
249 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \
250 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \
251 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \
252 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
253} while(0)
254#endif
255
256struct sha256_state {
257#ifdef HAVE_LONGLONG
258 unsigned long long length;
259#else
260 unsigned __int64 length;
261#endif
262 unsigned long state[8], curlen;
263 unsigned char buf[64];
264};
265typedef struct sha256_state SHA256_CTX;
266
267/* The K array */
268static const unsigned long K[64] = {
269 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
270 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
271 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
272 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
273 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
274 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
275 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
276 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
277 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
278 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
279 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
280 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
281 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
282};
283
284/* Various logical functions */
285#define RORc(x, y) \
286(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
287 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
288#define Ch(x,y,z) (z ^ (x & (y ^ z)))
289#define Maj(x,y,z) (((x | y) & z) | (x & y))
290#define S(x, n) RORc((x), (n))
291#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
292#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
293#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
294#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
295#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
296
297/* Compress 512-bits */
298static int sha256_compress(struct sha256_state *md,
299 unsigned char *buf)
300{
301 unsigned long S[8], W[64];
302 int i;
303
304 /* Copy state into S */
305 for(i = 0; i < 8; i++) {
306 S[i] = md->state[i];
307 }
308 /* copy the state into 512-bits into W[0..15] */
309 for(i = 0; i < 16; i++)
310 W[i] = WPA_GET_BE32(buf + (4 * i));
311 /* fill W[16..63] */
312 for(i = 16; i < 64; i++) {
313 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
314 W[i - 16];
315 }
316
317 /* Compress */
318#define RND(a,b,c,d,e,f,g,h,i) \
319 do { \
320 unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
321 unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
322 d += t0; \
323 h = t0 + t1; \
324 } while(0)
325
326 for(i = 0; i < 64; ++i) {
327 unsigned long t;
328 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
329 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
330 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
331 }
332
333 /* Feedback */
334 for(i = 0; i < 8; i++) {
335 md->state[i] = md->state[i] + S[i];
336 }
337
338 return 0;
339}
340
341/* Initialize the hash state */
342static void SHA256_Init(struct sha256_state *md)
343{
344 md->curlen = 0;
345 md->length = 0;
346 md->state[0] = 0x6A09E667UL;
347 md->state[1] = 0xBB67AE85UL;
348 md->state[2] = 0x3C6EF372UL;
349 md->state[3] = 0xA54FF53AUL;
350 md->state[4] = 0x510E527FUL;
351 md->state[5] = 0x9B05688CUL;
352 md->state[6] = 0x1F83D9ABUL;
353 md->state[7] = 0x5BE0CD19UL;
354}
355
356/*
357 Process a block of memory though the hash
358 @param md The hash state
359 @param in The data to hash
360 @param inlen The length of the data (octets)
361 @return CRYPT_OK if successful
362*/
363static int SHA256_Update(struct sha256_state *md,
364 const unsigned char *in,
365 unsigned long inlen)
366{
367 unsigned long n;
368
369#define block_size 64
370 if(md->curlen > sizeof(md->buf))
371 return -1;
372 while(inlen > 0) {
373 if(md->curlen == 0 && inlen >= block_size) {
374 if(sha256_compress(md, (unsigned char *)in) < 0)
375 return -1;
376 md->length += block_size * 8;
377 in += block_size;
378 inlen -= block_size;
379 }
380 else {
381 n = CURLMIN(inlen, (block_size - md->curlen));
382 memcpy(md->buf + md->curlen, in, n);
383 md->curlen += n;
384 in += n;
385 inlen -= n;
386 if(md->curlen == block_size) {
387 if(sha256_compress(md, md->buf) < 0)
388 return -1;
389 md->length += 8 * block_size;
390 md->curlen = 0;
391 }
392 }
393 }
394
395 return 0;
396}
397
398/*
399 Terminate the hash to get the digest
400 @param md The hash state
401 @param out [out] The destination of the hash (32 bytes)
402 @return CRYPT_OK if successful
403*/
404static int SHA256_Final(unsigned char *out,
405 struct sha256_state *md)
406{
407 int i;
408
409 if(md->curlen >= sizeof(md->buf))
410 return -1;
411
412 /* Increase the length of the message */
413 md->length += md->curlen * 8;
414
415 /* Append the '1' bit */
416 md->buf[md->curlen++] = (unsigned char)0x80;
417
418 /* If the length is currently above 56 bytes we append zeros
419 * then compress. Then we can fall back to padding zeros and length
420 * encoding like normal.
421 */
422 if(md->curlen > 56) {
423 while(md->curlen < 64) {
424 md->buf[md->curlen++] = (unsigned char)0;
425 }
426 sha256_compress(md, md->buf);
427 md->curlen = 0;
428 }
429
430 /* Pad up to 56 bytes of zeroes */
431 while(md->curlen < 56) {
432 md->buf[md->curlen++] = (unsigned char)0;
433 }
434
435 /* Store length */
436 WPA_PUT_BE64(md->buf + 56, md->length);
437 sha256_compress(md, md->buf);
438
439 /* Copy output */
440 for(i = 0; i < 8; i++)
441 WPA_PUT_BE32(out + (4 * i), md->state[i]);
442
443 return 0;
444}
445
446#endif /* CRYPTO LIBS */
447
448/*
449 * Curl_sha256it()
450 *
451 * Generates a SHA256 hash for the given input data.
452 *
453 * Parameters:
454 *
455 * output [in/out] - The output buffer.
456 * input [in] - The input data.
457 * length [in] - The input length.
458 */
459void Curl_sha256it(unsigned char *output, const unsigned char *input,
460 const size_t length)
461{
462 SHA256_CTX ctx;
463
464 SHA256_Init(&ctx);
465 SHA256_Update(&ctx, input, curlx_uztoui(length));
466 SHA256_Final(output, &ctx);
467}
468
469
470const struct HMAC_params Curl_HMAC_SHA256[] = {
471 {
472 /* Hash initialization function. */
473 CURLX_FUNCTION_CAST(HMAC_hinit_func, SHA256_Init),
474 /* Hash update function. */
475 CURLX_FUNCTION_CAST(HMAC_hupdate_func, SHA256_Update),
476 /* Hash computation end function. */
477 CURLX_FUNCTION_CAST(HMAC_hfinal_func, SHA256_Final),
478 /* Size of hash context structure. */
479 sizeof(SHA256_CTX),
480 /* Maximum key length. */
481 64,
482 /* Result size. */
483 32
484 }
485};
486
487
488#endif /* CURL_DISABLE_CRYPTO_AUTH */
489