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