1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin (at) gmail.com> 9 * 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. 13 * 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. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23 #include "curl_setup.h" 24 25 #ifndef CURL_DISABLE_CRYPTO_AUTH 26 27 #include "warnless.h" 28 #include "curl_sha256.h" 29 30 #if defined(USE_OPENSSL) 31 32 /* When OpenSSL is available we use the SHA256-function from OpenSSL */ 33 #include <openssl/sha.h> 34 35 #else 36 37 /* When no other crypto library is available we use this code segment */ 38 39 /* ===== start - public domain SHA256 implementation ===== */ 40 /* This is based on SHA256 implementation in LibTomCrypt that was released into 41 * public domain by Tom St Denis. */ 42 43 #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \ 44 (((unsigned long)(a)[1]) << 16) | \ 45 (((unsigned long)(a)[2]) << 8) | \ 46 ((unsigned long)(a)[3])) 47 #define WPA_PUT_BE32(a, val) \ 48 do { \ 49 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \ 50 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \ 51 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \ 52 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \ 53 } while(0) 54 55 #ifdef HAVE_LONGLONG 56 #define WPA_PUT_BE64(a, val) \ 57 do { \ 58 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \ 59 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \ 60 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \ 61 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \ 62 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \ 63 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \ 64 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \ 65 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \ 66 } while(0) 67 #else 68 #define WPA_PUT_BE64(a, val) \ 69 do { \ 70 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \ 71 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \ 72 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \ 73 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \ 74 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \ 75 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \ 76 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \ 77 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \ 78 } while(0) 79 #endif 80 81 typedef struct sha256_state { 82 #ifdef HAVE_LONGLONG 83 unsigned long long length; 84 #else 85 unsigned __int64 length; 86 #endif 87 unsigned long state[8], curlen; 88 unsigned char buf[64]; 89 } SHA256_CTX; 90 /* the K array */ 91 static const unsigned long K[64] = { 92 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 93 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 94 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 95 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 96 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 97 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 98 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 99 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 100 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 101 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 102 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 103 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 104 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 105 }; 106 /* Various logical functions */ 107 #define RORc(x, y) \ 108 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \ 109 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL) 110 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 111 #define Maj(x,y,z) (((x | y) & z) | (x & y)) 112 #define S(x, n) RORc((x), (n)) 113 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) 114 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 115 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 116 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 117 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 118 #ifndef MIN 119 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 120 #endif 121 /* compress 512-bits */ 122 static int sha256_compress(struct sha256_state *md, 123 unsigned char *buf) 124 { 125 unsigned long S[8], W[64], t0, t1; 126 unsigned long t; 127 int i; 128 /* copy state into S */ 129 for(i = 0; i < 8; i++) { 130 S[i] = md->state[i]; 131 } 132 /* copy the state into 512-bits into W[0..15] */ 133 for(i = 0; i < 16; i++) 134 W[i] = WPA_GET_BE32(buf + (4 * i)); 135 /* fill W[16..63] */ 136 for(i = 16; i < 64; i++) { 137 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + 138 W[i - 16]; 139 } 140 /* Compress */ 141 #define RND(a,b,c,d,e,f,g,h,i) \ 142 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 143 t1 = Sigma0(a) + Maj(a, b, c); \ 144 d += t0; \ 145 h = t0 + t1; 146 for(i = 0; i < 64; ++i) { 147 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); 148 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 149 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; 150 } 151 /* feedback */ 152 for(i = 0; i < 8; i++) { 153 md->state[i] = md->state[i] + S[i]; 154 } 155 return 0; 156 } 157 /* Initialize the hash state */ 158 static void SHA256_Init(struct sha256_state *md) 159 { 160 md->curlen = 0; 161 md->length = 0; 162 md->state[0] = 0x6A09E667UL; 163 md->state[1] = 0xBB67AE85UL; 164 md->state[2] = 0x3C6EF372UL; 165 md->state[3] = 0xA54FF53AUL; 166 md->state[4] = 0x510E527FUL; 167 md->state[5] = 0x9B05688CUL; 168 md->state[6] = 0x1F83D9ABUL; 169 md->state[7] = 0x5BE0CD19UL; 170 } 171 /** 172 Process a block of memory though the hash 173 @param md The hash state 174 @param in The data to hash 175 @param inlen The length of the data (octets) 176 @return CRYPT_OK if successful 177 */ 178 static int SHA256_Update(struct sha256_state *md, 179 const unsigned char *in, 180 unsigned long inlen) 181 { 182 unsigned long n; 183 #define block_size 64 184 if(md->curlen > sizeof(md->buf)) 185 return -1; 186 while(inlen > 0) { 187 if(md->curlen == 0 && inlen >= block_size) { 188 if(sha256_compress(md, (unsigned char *)in) < 0) 189 return -1; 190 md->length += block_size * 8; 191 in += block_size; 192 inlen -= block_size; 193 } 194 else { 195 n = MIN(inlen, (block_size - md->curlen)); 196 memcpy(md->buf + md->curlen, in, n); 197 md->curlen += n; 198 in += n; 199 inlen -= n; 200 if(md->curlen == block_size) { 201 if(sha256_compress(md, md->buf) < 0) 202 return -1; 203 md->length += 8 * block_size; 204 md->curlen = 0; 205 } 206 } 207 } 208 return 0; 209 } 210 /** 211 Terminate the hash to get the digest 212 @param md The hash state 213 @param out [out] The destination of the hash (32 bytes) 214 @return CRYPT_OK if successful 215 */ 216 static int SHA256_Final(unsigned char *out, 217 struct sha256_state *md) 218 { 219 int i; 220 if(md->curlen >= sizeof(md->buf)) 221 return -1; 222 /* increase the length of the message */ 223 md->length += md->curlen * 8; 224 /* append the '1' bit */ 225 md->buf[md->curlen++] = (unsigned char)0x80; 226 /* if the length is currently above 56 bytes we append zeros 227 * then compress. Then we can fall back to padding zeros and length 228 * encoding like normal. 229 */ 230 if(md->curlen > 56) { 231 while(md->curlen < 64) { 232 md->buf[md->curlen++] = (unsigned char)0; 233 } 234 sha256_compress(md, md->buf); 235 md->curlen = 0; 236 } 237 /* pad upto 56 bytes of zeroes */ 238 while(md->curlen < 56) { 239 md->buf[md->curlen++] = (unsigned char)0; 240 } 241 /* store length */ 242 WPA_PUT_BE64(md->buf + 56, md->length); 243 sha256_compress(md, md->buf); 244 /* copy output */ 245 for(i = 0; i < 8; i++) 246 WPA_PUT_BE32(out + (4 * i), md->state[i]); 247 return 0; 248 } 249 /* ===== end - public domain SHA256 implementation ===== */ 250 251 #endif 252 253 void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */ 254 const unsigned char *input) 255 { 256 SHA256_CTX ctx; 257 SHA256_Init(&ctx); 258 SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input))); 259 SHA256_Final(outbuffer, &ctx); 260 } 261 262 #endif /* CURL_DISABLE_CRYPTO_AUTH */ 263