1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_CRYPTO_AUTH
28 #include "curl_sha256.h"
30 #if defined(USE_OPENSSL)
32 #include <openssl/opensslv.h>
34 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
35 #define USE_OPENSSL_SHA256
40 #ifdef USE_OPENSSL_SHA256
41 /* When OpenSSL is available we use the SHA256-function from OpenSSL */
42 #include <openssl/sha.h>
45 /* When no other crypto library is available we use this code segment */
47 /* ===== start - public domain SHA256 implementation ===== */
48 /* This is based on SHA256 implementation in LibTomCrypt that was released into
49 * public domain by Tom St Denis. */
51 #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
52 (((unsigned long)(a)[1]) << 16) | \
53 (((unsigned long)(a)[2]) << 8) | \
54 ((unsigned long)(a)[3]))
55 #define WPA_PUT_BE32(a, val) \
57 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
58 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
59 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \
60 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \
64 #define WPA_PUT_BE64(a, val) \
66 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \
67 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \
68 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \
69 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \
70 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \
71 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \
72 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \
73 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
76 #define WPA_PUT_BE64(a, val) \
78 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \
79 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \
80 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \
81 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \
82 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \
83 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \
84 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \
85 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
89 typedef struct sha256_state {
91 unsigned long long length;
93 unsigned __int64 length;
95 unsigned long state[8], curlen;
96 unsigned char buf[64];
99 static const unsigned long K[64] = {
100 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
101 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
102 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
103 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
104 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
105 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
106 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
107 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
108 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
109 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
110 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
111 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
112 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
114 /* Various logical functions */
116 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
117 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
118 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
119 #define Maj(x,y,z) (((x | y) & z) | (x & y))
120 #define S(x, n) RORc((x), (n))
121 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
122 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
123 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
124 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
125 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
127 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
129 /* compress 512-bits */
130 static int sha256_compress(struct sha256_state *md,
133 unsigned long S[8], W[64], t0, t1;
136 /* copy state into S */
137 for(i = 0; i < 8; i++) {
140 /* copy the state into 512-bits into W[0..15] */
141 for(i = 0; i < 16; i++)
142 W[i] = WPA_GET_BE32(buf + (4 * i));
144 for(i = 16; i < 64; i++) {
145 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
149 #define RND(a,b,c,d,e,f,g,h,i) \
150 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
151 t1 = Sigma0(a) + Maj(a, b, c); \
154 for(i = 0; i < 64; ++i) {
155 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
156 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
157 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
160 for(i = 0; i < 8; i++) {
161 md->state[i] = md->state[i] + S[i];
165 /* Initialize the hash state */
166 static void SHA256_Init(struct sha256_state *md)
170 md->state[0] = 0x6A09E667UL;
171 md->state[1] = 0xBB67AE85UL;
172 md->state[2] = 0x3C6EF372UL;
173 md->state[3] = 0xA54FF53AUL;
174 md->state[4] = 0x510E527FUL;
175 md->state[5] = 0x9B05688CUL;
176 md->state[6] = 0x1F83D9ABUL;
177 md->state[7] = 0x5BE0CD19UL;
180 Process a block of memory though the hash
181 @param md The hash state
182 @param in The data to hash
183 @param inlen The length of the data (octets)
184 @return CRYPT_OK if successful
186 static int SHA256_Update(struct sha256_state *md,
187 const unsigned char *in,
191 #define block_size 64
192 if(md->curlen > sizeof(md->buf))
195 if(md->curlen == 0 && inlen >= block_size) {
196 if(sha256_compress(md, (unsigned char *)in) < 0)
198 md->length += block_size * 8;
203 n = MIN(inlen, (block_size - md->curlen));
204 memcpy(md->buf + md->curlen, in, n);
208 if(md->curlen == block_size) {
209 if(sha256_compress(md, md->buf) < 0)
211 md->length += 8 * block_size;
219 Terminate the hash to get the digest
220 @param md The hash state
221 @param out [out] The destination of the hash (32 bytes)
222 @return CRYPT_OK if successful
224 static int SHA256_Final(unsigned char *out,
225 struct sha256_state *md)
228 if(md->curlen >= sizeof(md->buf))
230 /* increase the length of the message */
231 md->length += md->curlen * 8;
232 /* append the '1' bit */
233 md->buf[md->curlen++] = (unsigned char)0x80;
234 /* if the length is currently above 56 bytes we append zeros
235 * then compress. Then we can fall back to padding zeros and length
236 * encoding like normal.
238 if(md->curlen > 56) {
239 while(md->curlen < 64) {
240 md->buf[md->curlen++] = (unsigned char)0;
242 sha256_compress(md, md->buf);
245 /* pad up to 56 bytes of zeroes */
246 while(md->curlen < 56) {
247 md->buf[md->curlen++] = (unsigned char)0;
250 WPA_PUT_BE64(md->buf + 56, md->length);
251 sha256_compress(md, md->buf);
253 for(i = 0; i < 8; i++)
254 WPA_PUT_BE32(out + (4 * i), md->state[i]);
257 /* ===== end - public domain SHA256 implementation ===== */
261 void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
262 const unsigned char *input)
266 SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
267 SHA256_Final(outbuffer, &ctx);
270 #endif /* CURL_DISABLE_CRYPTO_AUTH */