1515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker/* sha256.c
2515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**
3515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** Copyright 2013, The Android Open Source Project
4515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**
5515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** Redistribution and use in source and binary forms, with or without
6515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** modification, are permitted provided that the following conditions are met:
7515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**     * Redistributions of source code must retain the above copyright
8515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**       notice, this list of conditions and the following disclaimer.
9515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**     * Redistributions in binary form must reproduce the above copyright
10515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**       notice, this list of conditions and the following disclaimer in the
11515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**       documentation and/or other materials provided with the distribution.
12515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**     * Neither the name of Google Inc. nor the names of its contributors may
13515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**       be used to endorse or promote products derived from this software
14515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**       without specific prior written permission.
15515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker**
16515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
17515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker*/
27515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
28515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker// Optimized for minimal code size.
29515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
30515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include "mincrypt/sha256.h"
31515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
32515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <stdio.h>
33515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <string.h>
34515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <stdint.h>
35515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
36515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
37515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#define shr(value, bits) ((value) >> (bits))
38515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
39515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerstatic const uint32_t K[64] = {
40515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
41515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
42515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
43515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
44515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
45515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
46515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
47515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
48515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
49515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
50515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
51515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
52515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
53515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
54515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
55515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
56515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
57515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerstatic void SHA256_Transform(SHA256_CTX* ctx) {
58515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    uint32_t W[64];
59515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    uint32_t A, B, C, D, E, F, G, H;
60515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    uint8_t* p = ctx->buf;
61515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    int t;
62515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
63515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    for(t = 0; t < 16; ++t) {
64515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t tmp =  *p++ << 24;
65515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        tmp |= *p++ << 16;
66515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        tmp |= *p++ << 8;
67515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        tmp |= *p++;
68515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        W[t] = tmp;
69515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
70515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
71515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    for(; t < 64; t++) {
72515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t s0 = ror(W[t-15], 7) ^ ror(W[t-15], 18) ^ shr(W[t-15], 3);
73515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t s1 = ror(W[t-2], 17) ^ ror(W[t-2], 19) ^ shr(W[t-2], 10);
74515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        W[t] = W[t-16] + s0 + W[t-7] + s1;
75515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
76515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
77515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    A = ctx->state[0];
78515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    B = ctx->state[1];
79515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    C = ctx->state[2];
80515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    D = ctx->state[3];
81515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    E = ctx->state[4];
82515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    F = ctx->state[5];
83515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    G = ctx->state[6];
84515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    H = ctx->state[7];
85515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
86515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    for(t = 0; t < 64; t++) {
87515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t s0 = ror(A, 2) ^ ror(A, 13) ^ ror(A, 22);
88515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t maj = (A & B) ^ (A & C) ^ (B & C);
89515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t t2 = s0 + maj;
90515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t s1 = ror(E, 6) ^ ror(E, 11) ^ ror(E, 25);
91515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t ch = (E & F) ^ ((~E) & G);
92515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t t1 = H + s1 + ch + K[t] + W[t];
93515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
94515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        H = G;
95515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        G = F;
96515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        F = E;
97515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        E = D + t1;
98515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        D = C;
99515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        C = B;
100515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        B = A;
101515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        A = t1 + t2;
102515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
103515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
104515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[0] += A;
105515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[1] += B;
106515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[2] += C;
107515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[3] += D;
108515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[4] += E;
109515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[5] += F;
110515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[6] += G;
111515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[7] += H;
112515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}
113515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
114515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerstatic const HASH_VTAB SHA256_VTAB = {
115515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_init,
116515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_update,
117515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_final,
118515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_hash,
119515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_DIGEST_SIZE
120515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker};
121515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
122515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkervoid SHA256_init(SHA256_CTX* ctx) {
123515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->f = &SHA256_VTAB;
124515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[0] = 0x6a09e667;
125515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[1] = 0xbb67ae85;
126515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[2] = 0x3c6ef372;
127515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[3] = 0xa54ff53a;
128515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[4] = 0x510e527f;
129515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[5] = 0x9b05688c;
130515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[6] = 0x1f83d9ab;
131515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->state[7] = 0x5be0cd19;
132515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->count = 0;
133515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}
134515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
135515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
136515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkervoid SHA256_update(SHA256_CTX* ctx, const void* data, int len) {
137515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    int i = (int) (ctx->count & 63);
138515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    const uint8_t* p = (const uint8_t*)data;
139515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
140515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    ctx->count += len;
141515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
142515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    while (len--) {
143515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        ctx->buf[i++] = *p++;
144515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        if (i == 64) {
145515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker            SHA256_Transform(ctx);
146515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker            i = 0;
147515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        }
148515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
149515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}
150515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
151515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
152515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerconst uint8_t* SHA256_final(SHA256_CTX* ctx) {
153515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    uint8_t *p = ctx->buf;
154515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    uint64_t cnt = ctx->count * 8;
155515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    int i;
156515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
157515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_update(ctx, (uint8_t*)"\x80", 1);
158515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    while ((ctx->count & 63) != 56) {
159515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        SHA256_update(ctx, (uint8_t*)"\0", 1);
160515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
161515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    for (i = 0; i < 8; ++i) {
162515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8));
163515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        SHA256_update(ctx, &tmp, 1);
164515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
165515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
166515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    for (i = 0; i < 8; i++) {
167515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        uint32_t tmp = ctx->state[i];
168515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        *p++ = tmp >> 24;
169515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        *p++ = tmp >> 16;
170515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        *p++ = tmp >> 8;
171515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker        *p++ = tmp >> 0;
172515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    }
173515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
174515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    return ctx->buf;
175515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}
176515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker
177515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker/* Convenience function */
178515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerconst uint8_t* SHA256_hash(const void* data, int len, uint8_t* digest) {
179515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_CTX ctx;
180515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_init(&ctx);
181515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    SHA256_update(&ctx, data, len);
182515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    memcpy(digest, SHA256_final(&ctx), SHA256_DIGEST_SIZE);
183515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker    return digest;
184515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}
185