• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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