1160814Ssimon/* crypto/sha/sha256.c */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright (c) 2004 The OpenSSL Project. All rights reserved 4160814Ssimon * according to the OpenSSL license [found in ../../LICENSE]. 5160814Ssimon * ==================================================================== 6160814Ssimon */ 7160814Ssimon#include <openssl/opensslconf.h> 8160814Ssimon#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) 9160814Ssimon 10296341Sdelphij# include <stdlib.h> 11296341Sdelphij# include <string.h> 12160814Ssimon 13296341Sdelphij# include <openssl/crypto.h> 14296341Sdelphij# include <openssl/sha.h> 15296341Sdelphij# include <openssl/opensslv.h> 16160814Ssimon 17296341Sdelphijconst char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; 18160814Ssimon 19238405Sjkimfips_md_init_ctx(SHA224, SHA256) 20296341Sdelphij{ 21296341Sdelphij memset(c, 0, sizeof(*c)); 22296341Sdelphij c->h[0] = 0xc1059ed8UL; 23296341Sdelphij c->h[1] = 0x367cd507UL; 24296341Sdelphij c->h[2] = 0x3070dd17UL; 25296341Sdelphij c->h[3] = 0xf70e5939UL; 26296341Sdelphij c->h[4] = 0xffc00b31UL; 27296341Sdelphij c->h[5] = 0x68581511UL; 28296341Sdelphij c->h[6] = 0x64f98fa7UL; 29296341Sdelphij c->h[7] = 0xbefa4fa4UL; 30296341Sdelphij c->md_len = SHA224_DIGEST_LENGTH; 31296341Sdelphij return 1; 32296341Sdelphij} 33160814Ssimon 34238405Sjkimfips_md_init(SHA256) 35296341Sdelphij{ 36296341Sdelphij memset(c, 0, sizeof(*c)); 37296341Sdelphij c->h[0] = 0x6a09e667UL; 38296341Sdelphij c->h[1] = 0xbb67ae85UL; 39296341Sdelphij c->h[2] = 0x3c6ef372UL; 40296341Sdelphij c->h[3] = 0xa54ff53aUL; 41296341Sdelphij c->h[4] = 0x510e527fUL; 42296341Sdelphij c->h[5] = 0x9b05688cUL; 43296341Sdelphij c->h[6] = 0x1f83d9abUL; 44296341Sdelphij c->h[7] = 0x5be0cd19UL; 45296341Sdelphij c->md_len = SHA256_DIGEST_LENGTH; 46296341Sdelphij return 1; 47296341Sdelphij} 48160814Ssimon 49160814Ssimonunsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) 50296341Sdelphij{ 51296341Sdelphij SHA256_CTX c; 52296341Sdelphij static unsigned char m[SHA224_DIGEST_LENGTH]; 53160814Ssimon 54296341Sdelphij if (md == NULL) 55296341Sdelphij md = m; 56296341Sdelphij SHA224_Init(&c); 57296341Sdelphij SHA256_Update(&c, d, n); 58296341Sdelphij SHA256_Final(md, &c); 59296341Sdelphij OPENSSL_cleanse(&c, sizeof(c)); 60296341Sdelphij return (md); 61296341Sdelphij} 62160814Ssimon 63160814Ssimonunsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) 64296341Sdelphij{ 65296341Sdelphij SHA256_CTX c; 66296341Sdelphij static unsigned char m[SHA256_DIGEST_LENGTH]; 67160814Ssimon 68296341Sdelphij if (md == NULL) 69296341Sdelphij md = m; 70296341Sdelphij SHA256_Init(&c); 71296341Sdelphij SHA256_Update(&c, d, n); 72296341Sdelphij SHA256_Final(md, &c); 73296341Sdelphij OPENSSL_cleanse(&c, sizeof(c)); 74296341Sdelphij return (md); 75296341Sdelphij} 76160814Ssimon 77160814Ssimonint SHA224_Update(SHA256_CTX *c, const void *data, size_t len) 78296341Sdelphij{ 79296341Sdelphij return SHA256_Update(c, data, len); 80296341Sdelphij} 81160814Ssimon 82296341Sdelphijint SHA224_Final(unsigned char *md, SHA256_CTX *c) 83296341Sdelphij{ 84296341Sdelphij return SHA256_Final(md, c); 85296341Sdelphij} 86160814Ssimon 87296341Sdelphij# define DATA_ORDER_IS_BIG_ENDIAN 88296341Sdelphij 89296341Sdelphij# define HASH_LONG SHA_LONG 90296341Sdelphij# define HASH_CTX SHA256_CTX 91296341Sdelphij# define HASH_CBLOCK SHA_CBLOCK 92160814Ssimon/* 93160814Ssimon * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." 94160814Ssimon * default: case below covers for it. It's not clear however if it's 95160814Ssimon * permitted to truncate to amount of bytes not divisible by 4. I bet not, 96160814Ssimon * but if it is, then default: case shall be extended. For reference. 97160814Ssimon * Idea behind separate cases for pre-defined lenghts is to let the 98160814Ssimon * compiler decide if it's appropriate to unroll small loops. 99160814Ssimon */ 100296341Sdelphij# define HASH_MAKE_STRING(c,s) do { \ 101296341Sdelphij unsigned long ll; \ 102296341Sdelphij unsigned int nn; \ 103296341Sdelphij switch ((c)->md_len) \ 104296341Sdelphij { case SHA224_DIGEST_LENGTH: \ 105296341Sdelphij for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \ 106296341Sdelphij { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ 107296341Sdelphij break; \ 108296341Sdelphij case SHA256_DIGEST_LENGTH: \ 109296341Sdelphij for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \ 110296341Sdelphij { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ 111296341Sdelphij break; \ 112296341Sdelphij default: \ 113296341Sdelphij if ((c)->md_len > SHA256_DIGEST_LENGTH) \ 114296341Sdelphij return 0; \ 115296341Sdelphij for (nn=0;nn<(c)->md_len/4;nn++) \ 116296341Sdelphij { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ 117296341Sdelphij break; \ 118296341Sdelphij } \ 119296341Sdelphij } while (0) 120160814Ssimon 121296341Sdelphij# define HASH_UPDATE SHA256_Update 122296341Sdelphij# define HASH_TRANSFORM SHA256_Transform 123296341Sdelphij# define HASH_FINAL SHA256_Final 124296341Sdelphij# define HASH_BLOCK_DATA_ORDER sha256_block_data_order 125296341Sdelphij# ifndef SHA256_ASM 126194206Ssimonstatic 127296341Sdelphij# endif 128296341Sdelphijvoid sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); 129160814Ssimon 130296341Sdelphij# include "md32_common.h" 131160814Ssimon 132296341Sdelphij# ifndef SHA256_ASM 133160814Ssimonstatic const SHA_LONG K256[64] = { 134296341Sdelphij 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 135296341Sdelphij 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 136296341Sdelphij 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 137296341Sdelphij 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 138296341Sdelphij 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 139296341Sdelphij 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 140296341Sdelphij 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 141296341Sdelphij 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 142296341Sdelphij 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 143296341Sdelphij 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 144296341Sdelphij 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 145296341Sdelphij 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 146296341Sdelphij 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 147296341Sdelphij 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 148296341Sdelphij 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 149296341Sdelphij 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 150296341Sdelphij}; 151160814Ssimon 152160814Ssimon/* 153160814Ssimon * FIPS specification refers to right rotations, while our ROTATE macro 154160814Ssimon * is left one. This is why you might notice that rotation coefficients 155160814Ssimon * differ from those observed in FIPS document by 32-N... 156160814Ssimon */ 157296341Sdelphij# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) 158296341Sdelphij# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) 159296341Sdelphij# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) 160296341Sdelphij# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) 161160814Ssimon 162296341Sdelphij# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 163296341Sdelphij# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 164160814Ssimon 165296341Sdelphij# ifdef OPENSSL_SMALL_FOOTPRINT 166160814Ssimon 167296341Sdelphijstatic void sha256_block_data_order(SHA256_CTX *ctx, const void *in, 168296341Sdelphij size_t num) 169296341Sdelphij{ 170296341Sdelphij unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2; 171296341Sdelphij SHA_LONG X[16], l; 172296341Sdelphij int i; 173296341Sdelphij const unsigned char *data = in; 174160814Ssimon 175296341Sdelphij while (num--) { 176160814Ssimon 177296341Sdelphij a = ctx->h[0]; 178296341Sdelphij b = ctx->h[1]; 179296341Sdelphij c = ctx->h[2]; 180296341Sdelphij d = ctx->h[3]; 181296341Sdelphij e = ctx->h[4]; 182296341Sdelphij f = ctx->h[5]; 183296341Sdelphij g = ctx->h[6]; 184296341Sdelphij h = ctx->h[7]; 185160814Ssimon 186296341Sdelphij for (i = 0; i < 16; i++) { 187296341Sdelphij HOST_c2l(data, l); 188296341Sdelphij T1 = X[i] = l; 189296341Sdelphij T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; 190296341Sdelphij T2 = Sigma0(a) + Maj(a, b, c); 191296341Sdelphij h = g; 192296341Sdelphij g = f; 193296341Sdelphij f = e; 194296341Sdelphij e = d + T1; 195296341Sdelphij d = c; 196296341Sdelphij c = b; 197296341Sdelphij b = a; 198296341Sdelphij a = T1 + T2; 199296341Sdelphij } 200160814Ssimon 201296341Sdelphij for (; i < 64; i++) { 202296341Sdelphij s0 = X[(i + 1) & 0x0f]; 203296341Sdelphij s0 = sigma0(s0); 204296341Sdelphij s1 = X[(i + 14) & 0x0f]; 205296341Sdelphij s1 = sigma1(s1); 206160814Ssimon 207296341Sdelphij T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; 208296341Sdelphij T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; 209296341Sdelphij T2 = Sigma0(a) + Maj(a, b, c); 210296341Sdelphij h = g; 211296341Sdelphij g = f; 212296341Sdelphij f = e; 213296341Sdelphij e = d + T1; 214296341Sdelphij d = c; 215296341Sdelphij c = b; 216296341Sdelphij b = a; 217296341Sdelphij a = T1 + T2; 218296341Sdelphij } 219160814Ssimon 220296341Sdelphij ctx->h[0] += a; 221296341Sdelphij ctx->h[1] += b; 222296341Sdelphij ctx->h[2] += c; 223296341Sdelphij ctx->h[3] += d; 224296341Sdelphij ctx->h[4] += e; 225296341Sdelphij ctx->h[5] += f; 226296341Sdelphij ctx->h[6] += g; 227296341Sdelphij ctx->h[7] += h; 228160814Ssimon 229296341Sdelphij } 230160814Ssimon} 231160814Ssimon 232296341Sdelphij# else 233160814Ssimon 234296341Sdelphij# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ 235296341Sdelphij T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ 236296341Sdelphij h = Sigma0(a) + Maj(a,b,c); \ 237296341Sdelphij d += T1; h += T1; } while (0) 238160814Ssimon 239296341Sdelphij# define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ 240296341Sdelphij s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ 241296341Sdelphij s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ 242296341Sdelphij T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ 243296341Sdelphij ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) 244160814Ssimon 245296341Sdelphijstatic void sha256_block_data_order(SHA256_CTX *ctx, const void *in, 246296341Sdelphij size_t num) 247296341Sdelphij{ 248296341Sdelphij unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1; 249296341Sdelphij SHA_LONG X[16]; 250296341Sdelphij int i; 251296341Sdelphij const unsigned char *data = in; 252296341Sdelphij const union { 253296341Sdelphij long one; 254296341Sdelphij char little; 255296341Sdelphij } is_endian = { 256296341Sdelphij 1 257296341Sdelphij }; 258160814Ssimon 259296341Sdelphij while (num--) { 260160814Ssimon 261296341Sdelphij a = ctx->h[0]; 262296341Sdelphij b = ctx->h[1]; 263296341Sdelphij c = ctx->h[2]; 264296341Sdelphij d = ctx->h[3]; 265296341Sdelphij e = ctx->h[4]; 266296341Sdelphij f = ctx->h[5]; 267296341Sdelphij g = ctx->h[6]; 268296341Sdelphij h = ctx->h[7]; 269160814Ssimon 270296341Sdelphij if (!is_endian.little && sizeof(SHA_LONG) == 4 271296341Sdelphij && ((size_t)in % 4) == 0) { 272296341Sdelphij const SHA_LONG *W = (const SHA_LONG *)data; 273160814Ssimon 274296341Sdelphij T1 = X[0] = W[0]; 275296341Sdelphij ROUND_00_15(0, a, b, c, d, e, f, g, h); 276296341Sdelphij T1 = X[1] = W[1]; 277296341Sdelphij ROUND_00_15(1, h, a, b, c, d, e, f, g); 278296341Sdelphij T1 = X[2] = W[2]; 279296341Sdelphij ROUND_00_15(2, g, h, a, b, c, d, e, f); 280296341Sdelphij T1 = X[3] = W[3]; 281296341Sdelphij ROUND_00_15(3, f, g, h, a, b, c, d, e); 282296341Sdelphij T1 = X[4] = W[4]; 283296341Sdelphij ROUND_00_15(4, e, f, g, h, a, b, c, d); 284296341Sdelphij T1 = X[5] = W[5]; 285296341Sdelphij ROUND_00_15(5, d, e, f, g, h, a, b, c); 286296341Sdelphij T1 = X[6] = W[6]; 287296341Sdelphij ROUND_00_15(6, c, d, e, f, g, h, a, b); 288296341Sdelphij T1 = X[7] = W[7]; 289296341Sdelphij ROUND_00_15(7, b, c, d, e, f, g, h, a); 290296341Sdelphij T1 = X[8] = W[8]; 291296341Sdelphij ROUND_00_15(8, a, b, c, d, e, f, g, h); 292296341Sdelphij T1 = X[9] = W[9]; 293296341Sdelphij ROUND_00_15(9, h, a, b, c, d, e, f, g); 294296341Sdelphij T1 = X[10] = W[10]; 295296341Sdelphij ROUND_00_15(10, g, h, a, b, c, d, e, f); 296296341Sdelphij T1 = X[11] = W[11]; 297296341Sdelphij ROUND_00_15(11, f, g, h, a, b, c, d, e); 298296341Sdelphij T1 = X[12] = W[12]; 299296341Sdelphij ROUND_00_15(12, e, f, g, h, a, b, c, d); 300296341Sdelphij T1 = X[13] = W[13]; 301296341Sdelphij ROUND_00_15(13, d, e, f, g, h, a, b, c); 302296341Sdelphij T1 = X[14] = W[14]; 303296341Sdelphij ROUND_00_15(14, c, d, e, f, g, h, a, b); 304296341Sdelphij T1 = X[15] = W[15]; 305296341Sdelphij ROUND_00_15(15, b, c, d, e, f, g, h, a); 306160814Ssimon 307296341Sdelphij data += SHA256_CBLOCK; 308296341Sdelphij } else { 309296341Sdelphij SHA_LONG l; 310160814Ssimon 311296341Sdelphij HOST_c2l(data, l); 312296341Sdelphij T1 = X[0] = l; 313296341Sdelphij ROUND_00_15(0, a, b, c, d, e, f, g, h); 314296341Sdelphij HOST_c2l(data, l); 315296341Sdelphij T1 = X[1] = l; 316296341Sdelphij ROUND_00_15(1, h, a, b, c, d, e, f, g); 317296341Sdelphij HOST_c2l(data, l); 318296341Sdelphij T1 = X[2] = l; 319296341Sdelphij ROUND_00_15(2, g, h, a, b, c, d, e, f); 320296341Sdelphij HOST_c2l(data, l); 321296341Sdelphij T1 = X[3] = l; 322296341Sdelphij ROUND_00_15(3, f, g, h, a, b, c, d, e); 323296341Sdelphij HOST_c2l(data, l); 324296341Sdelphij T1 = X[4] = l; 325296341Sdelphij ROUND_00_15(4, e, f, g, h, a, b, c, d); 326296341Sdelphij HOST_c2l(data, l); 327296341Sdelphij T1 = X[5] = l; 328296341Sdelphij ROUND_00_15(5, d, e, f, g, h, a, b, c); 329296341Sdelphij HOST_c2l(data, l); 330296341Sdelphij T1 = X[6] = l; 331296341Sdelphij ROUND_00_15(6, c, d, e, f, g, h, a, b); 332296341Sdelphij HOST_c2l(data, l); 333296341Sdelphij T1 = X[7] = l; 334296341Sdelphij ROUND_00_15(7, b, c, d, e, f, g, h, a); 335296341Sdelphij HOST_c2l(data, l); 336296341Sdelphij T1 = X[8] = l; 337296341Sdelphij ROUND_00_15(8, a, b, c, d, e, f, g, h); 338296341Sdelphij HOST_c2l(data, l); 339296341Sdelphij T1 = X[9] = l; 340296341Sdelphij ROUND_00_15(9, h, a, b, c, d, e, f, g); 341296341Sdelphij HOST_c2l(data, l); 342296341Sdelphij T1 = X[10] = l; 343296341Sdelphij ROUND_00_15(10, g, h, a, b, c, d, e, f); 344296341Sdelphij HOST_c2l(data, l); 345296341Sdelphij T1 = X[11] = l; 346296341Sdelphij ROUND_00_15(11, f, g, h, a, b, c, d, e); 347296341Sdelphij HOST_c2l(data, l); 348296341Sdelphij T1 = X[12] = l; 349296341Sdelphij ROUND_00_15(12, e, f, g, h, a, b, c, d); 350296341Sdelphij HOST_c2l(data, l); 351296341Sdelphij T1 = X[13] = l; 352296341Sdelphij ROUND_00_15(13, d, e, f, g, h, a, b, c); 353296341Sdelphij HOST_c2l(data, l); 354296341Sdelphij T1 = X[14] = l; 355296341Sdelphij ROUND_00_15(14, c, d, e, f, g, h, a, b); 356296341Sdelphij HOST_c2l(data, l); 357296341Sdelphij T1 = X[15] = l; 358296341Sdelphij ROUND_00_15(15, b, c, d, e, f, g, h, a); 359296341Sdelphij } 360160814Ssimon 361296341Sdelphij for (i = 16; i < 64; i += 8) { 362296341Sdelphij ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); 363296341Sdelphij ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); 364296341Sdelphij ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); 365296341Sdelphij ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); 366296341Sdelphij ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); 367296341Sdelphij ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); 368296341Sdelphij ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); 369296341Sdelphij ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); 370296341Sdelphij } 371160814Ssimon 372296341Sdelphij ctx->h[0] += a; 373296341Sdelphij ctx->h[1] += b; 374296341Sdelphij ctx->h[2] += c; 375296341Sdelphij ctx->h[3] += d; 376296341Sdelphij ctx->h[4] += e; 377296341Sdelphij ctx->h[5] += f; 378296341Sdelphij ctx->h[6] += g; 379296341Sdelphij ctx->h[7] += h; 380160814Ssimon 381296341Sdelphij } 382296341Sdelphij} 383160814Ssimon 384296341Sdelphij# endif 385296341Sdelphij# endif /* SHA256_ASM */ 386160814Ssimon 387296341Sdelphij#endif /* OPENSSL_NO_SHA256 */ 388