sha256.c (8506B)
1 #include "sha256.h" 2 #include <stdint.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 #define READ_BUFFER (1*1024*1024) 7 8 uint32_t k[64] = { 9 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 10 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 11 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 12 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 13 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 14 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 15 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 16 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 17 }; 18 19 20 21 void sha256_transform(SHA256_CTX *ctx, uint8_t data[]) 22 { 23 uint32_t a,b,c,d,e,f,g,h,i,j,t1,t2,m[64]; 24 25 for (i=0,j=0; i < 16; ++i, j += 4) 26 m[i] = (data[j] << 24) | (data[j+1] << 16) | (data[j+2] << 8) | (data[j+3]); 27 for ( ; i < 64; ++i) 28 m[i] = SIG1(m[i-2]) + m[i-7] + SIG0(m[i-15]) + m[i-16]; 29 30 a = ctx->state[0]; 31 b = ctx->state[1]; 32 c = ctx->state[2]; 33 d = ctx->state[3]; 34 e = ctx->state[4]; 35 f = ctx->state[5]; 36 g = ctx->state[6]; 37 h = ctx->state[7]; 38 39 for (i = 0; i < 64; ++i) { 40 t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 41 t2 = EP0(a) + MAJ(a,b,c); 42 h = g; 43 g = f; 44 f = e; 45 e = d + t1; 46 d = c; 47 c = b; 48 b = a; 49 a = t1 + t2; 50 } 51 52 ctx->state[0] += a; 53 ctx->state[1] += b; 54 ctx->state[2] += c; 55 ctx->state[3] += d; 56 ctx->state[4] += e; 57 ctx->state[5] += f; 58 ctx->state[6] += g; 59 ctx->state[7] += h; 60 } 61 62 void sha256_init(SHA256_CTX *ctx) 63 { 64 ctx->datalen = 0; 65 ctx->bitlen[0] = 0; 66 ctx->bitlen[1] = 0; 67 ctx->state[0] = 0x6a09e667; 68 ctx->state[1] = 0xbb67ae85; 69 ctx->state[2] = 0x3c6ef372; 70 ctx->state[3] = 0xa54ff53a; 71 ctx->state[4] = 0x510e527f; 72 ctx->state[5] = 0x9b05688c; 73 ctx->state[6] = 0x1f83d9ab; 74 ctx->state[7] = 0x5be0cd19; 75 } 76 77 void sha256_update(SHA256_CTX *ctx, uint8_t data[], uint32_t len) 78 { 79 uint32_t i; 80 81 for (i=0; i < len; ++i) { 82 ctx->data[ctx->datalen] = data[i]; 83 ctx->datalen++; 84 if (ctx->datalen == 64) { 85 sha256_transform(ctx,ctx->data); 86 DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],512); 87 ctx->datalen = 0; 88 } 89 } 90 } 91 92 void sha256_final(SHA256_CTX *ctx, uint8_t hash[]) 93 { 94 uint32_t i; 95 96 i = ctx->datalen; 97 98 // Pad whatever data is left in the buffer. 99 if (ctx->datalen < 56) { 100 ctx->data[i++] = 0x80; 101 while (i < 56) 102 ctx->data[i++] = 0x00; 103 } 104 else { 105 ctx->data[i++] = 0x80; 106 while (i < 64) 107 ctx->data[i++] = 0x00; 108 sha256_transform(ctx,ctx->data); 109 memset(ctx->data,0,56); 110 } 111 112 // Append to the padding the total message's length in bits and transform. 113 DBL_INT_ADD(ctx->bitlen[0],ctx->bitlen[1],ctx->datalen * 8); 114 ctx->data[63] = ctx->bitlen[0]; 115 ctx->data[62] = ctx->bitlen[0] >> 8; 116 ctx->data[61] = ctx->bitlen[0] >> 16; 117 ctx->data[60] = ctx->bitlen[0] >> 24; 118 ctx->data[59] = ctx->bitlen[1]; 119 ctx->data[58] = ctx->bitlen[1] >> 8; 120 ctx->data[57] = ctx->bitlen[1] >> 16; 121 ctx->data[56] = ctx->bitlen[1] >> 24; 122 sha256_transform(ctx,ctx->data); 123 124 // Since this implementation uses little endian byte ordering and SHA uses big endian, 125 // reverse all the bytes when copying the final state to the output hash. 126 for (i=0; i < 4; ++i) { 127 hash[i] = (ctx->state[0] >> (24-i*8)) & 0x000000ff; 128 hash[i+4] = (ctx->state[1] >> (24-i*8)) & 0x000000ff; 129 hash[i+8] = (ctx->state[2] >> (24-i*8)) & 0x000000ff; 130 hash[i+12] = (ctx->state[3] >> (24-i*8)) & 0x000000ff; 131 hash[i+16] = (ctx->state[4] >> (24-i*8)) & 0x000000ff; 132 hash[i+20] = (ctx->state[5] >> (24-i*8)) & 0x000000ff; 133 hash[i+24] = (ctx->state[6] >> (24-i*8)) & 0x000000ff; 134 hash[i+28] = (ctx->state[7] >> (24-i*8)) & 0x000000ff; 135 } 136 } 137 138 139 /** 140 * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) 141 * @key: Key for HMAC operations 142 * @key_len: Length of the key in bytes 143 * @num_elem: Number of elements in the data vector 144 * @addr: Pointers to the data areas 145 * @len: Lengths of the data blocks 146 * @mac: Buffer for the hash (32 bytes) 147 */ 148 void hmac_sha256_vector( uint8_t *key, size_t key_len, size_t num_elem, 149 uint8_t *addr[], size_t *len, uint8_t *mac) 150 { 151 unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ 152 unsigned char tk[32]; 153 uint8_t *_addr[6]; 154 size_t _len[6], i; 155 156 if (num_elem > 5) { 157 /* 158 * Fixed limit on the number of fragments to avoid having to 159 * allocate memory (which could fail). 160 */ 161 return; 162 } 163 164 /* if key is longer than 64 bytes reset it to key = SHA256(key) */ 165 if (key_len > 64) { 166 sha256_vector(1, &key, &key_len, tk); 167 key = tk; 168 key_len = 32; 169 } 170 171 /* the HMAC_SHA256 transform looks like: 172 * 173 * SHA256(K XOR opad, SHA256(K XOR ipad, text)) 174 * 175 * where K is an n byte key 176 * ipad is the byte 0x36 repeated 64 times 177 * opad is the byte 0x5c repeated 64 times 178 * and text is the data being protected */ 179 180 /* start out by storing key in ipad */ 181 memset(k_pad, 0, sizeof(k_pad)); 182 memcpy(k_pad, key, key_len); 183 /* XOR key with ipad values */ 184 for (i = 0; i < 64; i++) 185 k_pad[i] ^= 0x36; 186 187 /* perform inner SHA256 */ 188 _addr[0] = k_pad; 189 _len[0] = 64; 190 for (i = 0; i < num_elem; i++) { 191 _addr[i + 1] = addr[i]; 192 _len[i + 1] = len[i]; 193 } 194 sha256_vector(1 + num_elem, _addr, _len, mac); 195 196 // NOTE: SCE HACK - they removed the clearing of the pad in their version. 197 //memset(k_pad, 0, sizeof(k_pad)); 198 //memcpy(k_pad, key, key_len); 199 /* XOR key with opad values */ 200 for (i = 0; i < 64; i++) 201 // NOTE: SCE HACK - they changed the normal 0x5C value to 0x6A 202 k_pad[i] ^= 0x6A; 203 204 /* perform outer SHA256 */ 205 _addr[0] = k_pad; 206 _len[0] = 64; 207 _addr[1] = mac; 208 _len[1] = SHA256_MAC_LEN; 209 sha256_vector(2, _addr, _len, mac); 210 } 211 212 213 /** 214 * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) 215 * @key: Key for HMAC operations 216 * @key_len: Length of the key in bytes 217 * @data: Pointers to the data area 218 * @data_len: Length of the data area 219 * @mac: Buffer for the hash (20 bytes) 220 */ 221 void hmac_sha256( uint8_t *key, size_t key_len, uint8_t *data, 222 size_t data_len, uint8_t *mac) 223 { 224 hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); 225 } 226 227 228 /** 229 * sha256_vector - SHA256 hash for data vector 230 * @num_elem: Number of elements in the data vector 231 * @addr: Pointers to the data areas 232 * @len: Lengths of the data blocks 233 * @mac: Buffer for the hash 234 */ 235 void sha256_vector(size_t num_elem, uint8_t *addr[], size_t *len, 236 uint8_t *mac) 237 { 238 SHA256_CTX ctx; 239 size_t i; 240 241 sha256_init(&ctx); 242 for (i = 0; i < num_elem; i++) 243 sha256_update(&ctx, addr[i], len[i]); 244 sha256_final(&ctx, mac); 245 } 246 247 uint32_t sha256_32_vector(size_t num_elem, uint8_t *addr[], size_t *len) 248 { 249 uint8_t hash[32]; 250 251 sha256_vector(num_elem, addr, len, hash); 252 253 // swap to little endian 254 return (hash[0] << 24) | (hash[1] << 16) | (hash[2] << 8) | hash[3]; 255 } 256 257 int sha256_file(const char *file, uint8_t *mac) 258 { 259 size_t read = 0; 260 SHA256_CTX ctx; 261 FILE *fp = fopen(file, "rb"); 262 263 if (!fp) 264 return -1; 265 266 uint8_t *data = malloc(READ_BUFFER); 267 268 sha256_init(&ctx); 269 270 while ((read = fread(data, 1, READ_BUFFER, fp)) > 0) { 271 sha256_update(&ctx, data, read); 272 } 273 274 sha256_final(&ctx, mac); 275 free(data); 276 fclose(fp); 277 return 0; 278 } 279 280 int sha256_32_file(const char *file, uint32_t *nid) 281 { 282 uint8_t hash[32]; 283 uint8_t *hash_ptr = hash; 284 285 if (sha256_file(file, hash) < 0) 286 { 287 fprintf(stderr, "error: could not calculate SHA256 of '%s'\n", file); 288 // TODO: handle better, cleanup tree 289 return -1; 290 } 291 292 size_t len = 32; 293 *nid = sha256_32_vector(1, &hash_ptr, &len); 294 return 0; 295 }