Blame crypto/sha/sha256.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <openssl/opensslconf.h>
Packit c4476c
Packit c4476c
#include <stdlib.h>
Packit c4476c
#include <string.h>
Packit c4476c
Packit c4476c
#include <openssl/crypto.h>
Packit c4476c
#include <openssl/sha.h>
Packit c4476c
#include <openssl/opensslv.h>
Packit c4476c
Packit c4476c
int SHA224_Init(SHA256_CTX *c)
Packit c4476c
{
Packit c4476c
# ifdef OPENSSL_FIPS
Packit c4476c
    FIPS_selftest_check();
Packit c4476c
# endif
Packit c4476c
    memset(c, 0, sizeof(*c));
Packit c4476c
    c->h[0] = 0xc1059ed8UL;
Packit c4476c
    c->h[1] = 0x367cd507UL;
Packit c4476c
    c->h[2] = 0x3070dd17UL;
Packit c4476c
    c->h[3] = 0xf70e5939UL;
Packit c4476c
    c->h[4] = 0xffc00b31UL;
Packit c4476c
    c->h[5] = 0x68581511UL;
Packit c4476c
    c->h[6] = 0x64f98fa7UL;
Packit c4476c
    c->h[7] = 0xbefa4fa4UL;
Packit c4476c
    c->md_len = SHA224_DIGEST_LENGTH;
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
int SHA256_Init(SHA256_CTX *c)
Packit c4476c
{
Packit c4476c
# ifdef OPENSSL_FIPS
Packit c4476c
    FIPS_selftest_check();
Packit c4476c
# endif
Packit c4476c
    memset(c, 0, sizeof(*c));
Packit c4476c
    c->h[0] = 0x6a09e667UL;
Packit c4476c
    c->h[1] = 0xbb67ae85UL;
Packit c4476c
    c->h[2] = 0x3c6ef372UL;
Packit c4476c
    c->h[3] = 0xa54ff53aUL;
Packit c4476c
    c->h[4] = 0x510e527fUL;
Packit c4476c
    c->h[5] = 0x9b05688cUL;
Packit c4476c
    c->h[6] = 0x1f83d9abUL;
Packit c4476c
    c->h[7] = 0x5be0cd19UL;
Packit c4476c
    c->md_len = SHA256_DIGEST_LENGTH;
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
Packit c4476c
{
Packit c4476c
    SHA256_CTX c;
Packit c4476c
    static unsigned char m[SHA224_DIGEST_LENGTH];
Packit c4476c
Packit c4476c
    if (md == NULL)
Packit c4476c
        md = m;
Packit c4476c
    SHA224_Init(&c);
Packit c4476c
    SHA256_Update(&c, d, n);
Packit c4476c
    SHA256_Final(md, &c);
Packit c4476c
    OPENSSL_cleanse(&c, sizeof(c));
Packit c4476c
    return md;
Packit c4476c
}
Packit c4476c
Packit c4476c
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
Packit c4476c
{
Packit c4476c
    SHA256_CTX c;
Packit c4476c
    static unsigned char m[SHA256_DIGEST_LENGTH];
Packit c4476c
Packit c4476c
    if (md == NULL)
Packit c4476c
        md = m;
Packit c4476c
    SHA256_Init(&c);
Packit c4476c
    SHA256_Update(&c, d, n);
Packit c4476c
    SHA256_Final(md, &c);
Packit c4476c
    OPENSSL_cleanse(&c, sizeof(c));
Packit c4476c
    return md;
Packit c4476c
}
Packit c4476c
Packit c4476c
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
Packit c4476c
{
Packit c4476c
    return SHA256_Update(c, data, len);
Packit c4476c
}
Packit c4476c
Packit c4476c
int SHA224_Final(unsigned char *md, SHA256_CTX *c)
Packit c4476c
{
Packit c4476c
    return SHA256_Final(md, c);
Packit c4476c
}
Packit c4476c
Packit c4476c
#define DATA_ORDER_IS_BIG_ENDIAN
Packit c4476c
Packit c4476c
#define HASH_LONG               SHA_LONG
Packit c4476c
#define HASH_CTX                SHA256_CTX
Packit c4476c
#define HASH_CBLOCK             SHA_CBLOCK
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
Packit c4476c
 * default: case below covers for it. It's not clear however if it's
Packit c4476c
 * permitted to truncate to amount of bytes not divisible by 4. I bet not,
Packit c4476c
 * but if it is, then default: case shall be extended. For reference.
Packit c4476c
 * Idea behind separate cases for pre-defined lengths is to let the
Packit c4476c
 * compiler decide if it's appropriate to unroll small loops.
Packit c4476c
 */
Packit c4476c
#define HASH_MAKE_STRING(c,s)   do {    \
Packit c4476c
        unsigned long ll;               \
Packit c4476c
        unsigned int  nn;               \
Packit c4476c
        switch ((c)->md_len)            \
Packit c4476c
        {   case SHA224_DIGEST_LENGTH:  \
Packit c4476c
                for (nn=0;nn
Packit c4476c
                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
Packit c4476c
                break;                  \
Packit c4476c
            case SHA256_DIGEST_LENGTH:  \
Packit c4476c
                for (nn=0;nn
Packit c4476c
                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
Packit c4476c
                break;                  \
Packit c4476c
            default:                    \
Packit c4476c
                if ((c)->md_len > SHA256_DIGEST_LENGTH) \
Packit c4476c
                    return 0;                           \
Packit c4476c
                for (nn=0;nn<(c)->md_len/4;nn++)                \
Packit c4476c
                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
Packit c4476c
                break;                  \
Packit c4476c
        }                               \
Packit c4476c
        } while (0)
Packit c4476c
Packit c4476c
#define HASH_UPDATE             SHA256_Update
Packit c4476c
#define HASH_TRANSFORM          SHA256_Transform
Packit c4476c
#define HASH_FINAL              SHA256_Final
Packit c4476c
#define HASH_BLOCK_DATA_ORDER   sha256_block_data_order
Packit c4476c
#ifndef SHA256_ASM
Packit c4476c
static
Packit c4476c
#endif
Packit c4476c
void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
Packit c4476c
Packit c4476c
#include "crypto/md32_common.h"
Packit c4476c
Packit c4476c
#ifndef SHA256_ASM
Packit c4476c
static const SHA_LONG K256[64] = {
Packit c4476c
    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
Packit c4476c
    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
Packit c4476c
    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
Packit c4476c
    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
Packit c4476c
    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
Packit c4476c
    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
Packit c4476c
    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
Packit c4476c
    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
Packit c4476c
    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
Packit c4476c
    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
Packit c4476c
    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
Packit c4476c
    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
Packit c4476c
    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
Packit c4476c
    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
Packit c4476c
    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
Packit c4476c
    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
Packit c4476c
};
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * FIPS specification refers to right rotations, while our ROTATE macro
Packit c4476c
 * is left one. This is why you might notice that rotation coefficients
Packit c4476c
 * differ from those observed in FIPS document by 32-N...
Packit c4476c
 */
Packit c4476c
# define Sigma0(x)       (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
Packit c4476c
# define Sigma1(x)       (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
Packit c4476c
# define sigma0(x)       (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
Packit c4476c
# define sigma1(x)       (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
Packit c4476c
Packit c4476c
# define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
Packit c4476c
# define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
Packit c4476c
Packit c4476c
# ifdef OPENSSL_SMALL_FOOTPRINT
Packit c4476c
Packit c4476c
static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
Packit c4476c
                                    size_t num)
Packit c4476c
{
Packit c4476c
    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
Packit c4476c
    SHA_LONG X[16], l;
Packit c4476c
    int i;
Packit c4476c
    const unsigned char *data = in;
Packit c4476c
Packit c4476c
    while (num--) {
Packit c4476c
Packit c4476c
        a = ctx->h[0];
Packit c4476c
        b = ctx->h[1];
Packit c4476c
        c = ctx->h[2];
Packit c4476c
        d = ctx->h[3];
Packit c4476c
        e = ctx->h[4];
Packit c4476c
        f = ctx->h[5];
Packit c4476c
        g = ctx->h[6];
Packit c4476c
        h = ctx->h[7];
Packit c4476c
Packit c4476c
        for (i = 0; i < 16; i++) {
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[i] = l;
Packit c4476c
            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
Packit c4476c
            T2 = Sigma0(a) + Maj(a, b, c);
Packit c4476c
            h = g;
Packit c4476c
            g = f;
Packit c4476c
            f = e;
Packit c4476c
            e = d + T1;
Packit c4476c
            d = c;
Packit c4476c
            c = b;
Packit c4476c
            b = a;
Packit c4476c
            a = T1 + T2;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        for (; i < 64; i++) {
Packit c4476c
            s0 = X[(i + 1) & 0x0f];
Packit c4476c
            s0 = sigma0(s0);
Packit c4476c
            s1 = X[(i + 14) & 0x0f];
Packit c4476c
            s1 = sigma1(s1);
Packit c4476c
Packit c4476c
            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
Packit c4476c
            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
Packit c4476c
            T2 = Sigma0(a) + Maj(a, b, c);
Packit c4476c
            h = g;
Packit c4476c
            g = f;
Packit c4476c
            f = e;
Packit c4476c
            e = d + T1;
Packit c4476c
            d = c;
Packit c4476c
            c = b;
Packit c4476c
            b = a;
Packit c4476c
            a = T1 + T2;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        ctx->h[0] += a;
Packit c4476c
        ctx->h[1] += b;
Packit c4476c
        ctx->h[2] += c;
Packit c4476c
        ctx->h[3] += d;
Packit c4476c
        ctx->h[4] += e;
Packit c4476c
        ctx->h[5] += f;
Packit c4476c
        ctx->h[6] += g;
Packit c4476c
        ctx->h[7] += h;
Packit c4476c
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
# else
Packit c4476c
Packit c4476c
#  define ROUND_00_15(i,a,b,c,d,e,f,g,h)          do {    \
Packit c4476c
        T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];      \
Packit c4476c
        h = Sigma0(a) + Maj(a,b,c);                     \
Packit c4476c
        d += T1;        h += T1;                } while (0)
Packit c4476c
Packit c4476c
#  define ROUND_16_63(i,a,b,c,d,e,f,g,h,X)        do {    \
Packit c4476c
        s0 = X[(i+1)&0x0f];     s0 = sigma0(s0);        \
Packit c4476c
        s1 = X[(i+14)&0x0f];    s1 = sigma1(s1);        \
Packit c4476c
        T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];    \
Packit c4476c
        ROUND_00_15(i,a,b,c,d,e,f,g,h);         } while (0)
Packit c4476c
Packit c4476c
static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
Packit c4476c
                                    size_t num)
Packit c4476c
{
Packit c4476c
    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
Packit c4476c
    SHA_LONG X[16];
Packit c4476c
    int i;
Packit c4476c
    const unsigned char *data = in;
Packit c4476c
    const union {
Packit c4476c
        long one;
Packit c4476c
        char little;
Packit c4476c
    } is_endian = {
Packit c4476c
        1
Packit c4476c
    };
Packit c4476c
Packit c4476c
    while (num--) {
Packit c4476c
Packit c4476c
        a = ctx->h[0];
Packit c4476c
        b = ctx->h[1];
Packit c4476c
        c = ctx->h[2];
Packit c4476c
        d = ctx->h[3];
Packit c4476c
        e = ctx->h[4];
Packit c4476c
        f = ctx->h[5];
Packit c4476c
        g = ctx->h[6];
Packit c4476c
        h = ctx->h[7];
Packit c4476c
Packit c4476c
        if (!is_endian.little && sizeof(SHA_LONG) == 4
Packit c4476c
            && ((size_t)in % 4) == 0) {
Packit c4476c
            const SHA_LONG *W = (const SHA_LONG *)data;
Packit c4476c
Packit c4476c
            T1 = X[0] = W[0];
Packit c4476c
            ROUND_00_15(0, a, b, c, d, e, f, g, h);
Packit c4476c
            T1 = X[1] = W[1];
Packit c4476c
            ROUND_00_15(1, h, a, b, c, d, e, f, g);
Packit c4476c
            T1 = X[2] = W[2];
Packit c4476c
            ROUND_00_15(2, g, h, a, b, c, d, e, f);
Packit c4476c
            T1 = X[3] = W[3];
Packit c4476c
            ROUND_00_15(3, f, g, h, a, b, c, d, e);
Packit c4476c
            T1 = X[4] = W[4];
Packit c4476c
            ROUND_00_15(4, e, f, g, h, a, b, c, d);
Packit c4476c
            T1 = X[5] = W[5];
Packit c4476c
            ROUND_00_15(5, d, e, f, g, h, a, b, c);
Packit c4476c
            T1 = X[6] = W[6];
Packit c4476c
            ROUND_00_15(6, c, d, e, f, g, h, a, b);
Packit c4476c
            T1 = X[7] = W[7];
Packit c4476c
            ROUND_00_15(7, b, c, d, e, f, g, h, a);
Packit c4476c
            T1 = X[8] = W[8];
Packit c4476c
            ROUND_00_15(8, a, b, c, d, e, f, g, h);
Packit c4476c
            T1 = X[9] = W[9];
Packit c4476c
            ROUND_00_15(9, h, a, b, c, d, e, f, g);
Packit c4476c
            T1 = X[10] = W[10];
Packit c4476c
            ROUND_00_15(10, g, h, a, b, c, d, e, f);
Packit c4476c
            T1 = X[11] = W[11];
Packit c4476c
            ROUND_00_15(11, f, g, h, a, b, c, d, e);
Packit c4476c
            T1 = X[12] = W[12];
Packit c4476c
            ROUND_00_15(12, e, f, g, h, a, b, c, d);
Packit c4476c
            T1 = X[13] = W[13];
Packit c4476c
            ROUND_00_15(13, d, e, f, g, h, a, b, c);
Packit c4476c
            T1 = X[14] = W[14];
Packit c4476c
            ROUND_00_15(14, c, d, e, f, g, h, a, b);
Packit c4476c
            T1 = X[15] = W[15];
Packit c4476c
            ROUND_00_15(15, b, c, d, e, f, g, h, a);
Packit c4476c
Packit c4476c
            data += SHA256_CBLOCK;
Packit c4476c
        } else {
Packit c4476c
            SHA_LONG l;
Packit c4476c
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[0] = l;
Packit c4476c
            ROUND_00_15(0, a, b, c, d, e, f, g, h);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[1] = l;
Packit c4476c
            ROUND_00_15(1, h, a, b, c, d, e, f, g);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[2] = l;
Packit c4476c
            ROUND_00_15(2, g, h, a, b, c, d, e, f);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[3] = l;
Packit c4476c
            ROUND_00_15(3, f, g, h, a, b, c, d, e);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[4] = l;
Packit c4476c
            ROUND_00_15(4, e, f, g, h, a, b, c, d);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[5] = l;
Packit c4476c
            ROUND_00_15(5, d, e, f, g, h, a, b, c);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[6] = l;
Packit c4476c
            ROUND_00_15(6, c, d, e, f, g, h, a, b);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[7] = l;
Packit c4476c
            ROUND_00_15(7, b, c, d, e, f, g, h, a);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[8] = l;
Packit c4476c
            ROUND_00_15(8, a, b, c, d, e, f, g, h);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[9] = l;
Packit c4476c
            ROUND_00_15(9, h, a, b, c, d, e, f, g);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[10] = l;
Packit c4476c
            ROUND_00_15(10, g, h, a, b, c, d, e, f);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[11] = l;
Packit c4476c
            ROUND_00_15(11, f, g, h, a, b, c, d, e);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[12] = l;
Packit c4476c
            ROUND_00_15(12, e, f, g, h, a, b, c, d);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[13] = l;
Packit c4476c
            ROUND_00_15(13, d, e, f, g, h, a, b, c);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[14] = l;
Packit c4476c
            ROUND_00_15(14, c, d, e, f, g, h, a, b);
Packit c4476c
            (void)HOST_c2l(data, l);
Packit c4476c
            T1 = X[15] = l;
Packit c4476c
            ROUND_00_15(15, b, c, d, e, f, g, h, a);
Packit c4476c
        }
Packit c4476c
Packit c4476c
        for (i = 16; i < 64; i += 8) {
Packit c4476c
            ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
Packit c4476c
            ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
Packit c4476c
            ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
Packit c4476c
            ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
Packit c4476c
            ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
Packit c4476c
            ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
Packit c4476c
            ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
Packit c4476c
            ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
Packit c4476c
        }
Packit c4476c
Packit c4476c
        ctx->h[0] += a;
Packit c4476c
        ctx->h[1] += b;
Packit c4476c
        ctx->h[2] += c;
Packit c4476c
        ctx->h[3] += d;
Packit c4476c
        ctx->h[4] += e;
Packit c4476c
        ctx->h[5] += f;
Packit c4476c
        ctx->h[6] += g;
Packit c4476c
        ctx->h[7] += h;
Packit c4476c
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
# endif
Packit c4476c
#endif                         /* SHA256_ASM */