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