sha.c revision a6de77de1727d5c40fdfdf841f3e8d13e0fc0140
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* sha.c
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2008, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Redistribution and use in source and binary forms, with or without
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** modification, are permitted provided that the following conditions are met:
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     * Redistributions of source code must retain the above copyright
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**       notice, this list of conditions and the following disclaimer.
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     * Redistributions in binary form must reproduce the above copyright
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**       notice, this list of conditions and the following disclaimer in the
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**       documentation and/or other materials provided with the distribution.
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     * Neither the name of Google Inc. nor the names of its contributors may
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**       be used to endorse or promote products derived from this software
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**       without specific prior written permission.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
16a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
28a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#include <byteswap.h>
29a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#include <endian.h>
30a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#include <memory.h>
31a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mincrypt/sha.h"
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
34a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#if __BYTE_ORDER == __LITTLE_ENDIAN
35a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
36a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker// This version is about 28% faster than the generic version below,
37a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker// but assumes little-endianness.
38a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
39a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror27(uint32_t val) {
40a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 27) | (val << 5);
41a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
42a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror2(uint32_t val) {
43a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 2) | (val << 30);
44a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
45a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror31(uint32_t val) {
46a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 31) | (val << 1);
47a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
48a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
49a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic void SHA1_Transform(SHA_CTX* ctx) {
50a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    uint32_t W[80];
51a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    register uint32_t A, B, C, D, E;
52a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int t;
53a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
54a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    A = ctx->state[0];
55a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ctx->state[1];
56a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    C = ctx->state[2];
57a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    D = ctx->state[3];
58a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E = ctx->state[4];
59a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
60a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F1(A,B,C,D,E,t)                     \
61a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                             \
62a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = bswap_32(ctx->buf.w[t])) +      \
63a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (D^(B&(C^D))) + 0x5A827999;             \
64a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
65a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
66a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (t = 0; t < 15; t += 5) {
67a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(A,B,C,D,E,t + 0);
68a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(E,A,B,C,D,t + 1);
69a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(D,E,A,B,C,t + 2);
70a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(C,D,E,A,B,t + 3);
71a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(B,C,D,E,A,t + 4);
72a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
73a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(A,B,C,D,E,t + 0);  // 16th one, t == 15
74a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
75a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F1
76a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
77a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F1(A,B,C,D,E,t)                                     \
78a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
79a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
80a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (D^(B&(C^D))) + 0x5A827999;                             \
81a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
82a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
83a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(E,A,B,C,D,t + 1);
84a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(D,E,A,B,C,t + 2);
85a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(C,D,E,A,B,t + 3);
86a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(B,C,D,E,A,t + 4);
87a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
88a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F1
89a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
90a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F2(A,B,C,D,E,t)                                     \
91a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
92a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
93a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (B^C^D) + 0x6ED9EBA1;                                   \
94a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
95a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
96a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (t = 20; t < 40; t += 5) {
97a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(A,B,C,D,E,t + 0);
98a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(E,A,B,C,D,t + 1);
99a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(D,E,A,B,C,t + 2);
100a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(C,D,E,A,B,t + 3);
101a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(B,C,D,E,A,t + 4);
102a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
103a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
104a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F2
105a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
106a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F3(A,B,C,D,E,t)                                     \
107a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
108a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
109a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ((B&C)|(D&(B|C))) + 0x8F1BBCDC;                         \
110a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
111a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
112a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (; t < 60; t += 5) {
113a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(A,B,C,D,E,t + 0);
114a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(E,A,B,C,D,t + 1);
115a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(D,E,A,B,C,t + 2);
116a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(C,D,E,A,B,t + 3);
117a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(B,C,D,E,A,t + 4);
118a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
119a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
120a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F3
121a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
122a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F4(A,B,C,D,E,t)                                     \
123a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
124a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
125a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (B^C^D) + 0xCA62C1D6;                                   \
126a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
127a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
128a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (; t < 80; t += 5) {
129a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(A,B,C,D,E,t + 0);
130a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(E,A,B,C,D,t + 1);
131a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(D,E,A,B,C,t + 2);
132a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(C,D,E,A,B,t + 3);
133a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(B,C,D,E,A,t + 4);
134a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
135a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
136a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F4
137a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
138a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[0] += A;
139a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[1] += B;
140a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[2] += C;
141a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[3] += D;
142a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[4] += E;
143a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
144a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
145a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkervoid SHA_update(SHA_CTX* ctx, const void* data, int len) {
146a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int i = ctx->count % sizeof(ctx->buf);
147a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    const uint8_t* p = (const uint8_t*)data;
148a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
149a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->count += len;
150a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
151a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while (len > sizeof(ctx->buf) - i) {
152a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
153a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        len -= sizeof(ctx->buf) - i;
154a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        p += sizeof(ctx->buf) - i;
155a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA1_Transform(ctx);
156a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        i = 0;
157a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
158a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
159a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while (len--) {
160a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ctx->buf.b[i++] = *p++;
161a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        if (i == sizeof(ctx->buf)) {
162a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker            SHA1_Transform(ctx);
163a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker            i = 0;
164a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        }
165a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
166a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
167a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
168a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
169a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerconst uint8_t* SHA_final(SHA_CTX* ctx) {
170a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    uint64_t cnt = ctx->count * 8;
171a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int i;
172a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
173a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_update(ctx, (uint8_t*)"\x80", 1);
174a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
175a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_update(ctx, (uint8_t*)"\0", 1);
176a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
177a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (i = 0; i < 8; ++i) {
178a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        uint8_t tmp = cnt >> ((7 - i) * 8);
179a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_update(ctx, &tmp, 1);
180a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
181a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
182a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (i = 0; i < 5; i++) {
183a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ctx->buf.w[i] = bswap_32(ctx->state[i]);
184a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
185a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
186a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return ctx->buf.b;
187a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
188a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
189a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#else   // __BYTE_ORDER == BIG_ENDIAN
190a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void SHA1_transform(SHA_CTX *ctx) {
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t W[80];
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t A, B, C, D, E;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t *p = ctx->buf;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int t;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(t = 0; t < 16; ++t) {
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp =  *p++ << 24;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++ << 16;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++ << 8;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        W[t] = tmp;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(; t < 80; t++) {
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    A = ctx->state[0];
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    B = ctx->state[1];
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    C = ctx->state[2];
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D = ctx->state[3];
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    E = ctx->state[4];
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(t = 0; t < 80; t++) {
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp = rol(5,A) + E + W[t];
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (t < 20)
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (D^(B&(C^D))) + 0x5A827999;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if ( t < 40)
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (B^C^D) + 0x6ED9EBA1;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if ( t < 60)
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (B^C^D) + 0xCA62C1D6;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        E = D;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D = C;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        C = rol(30,B);
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        B = A;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        A = tmp;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[0] += A;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[1] += B;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[2] += C;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[3] += D;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[4] += E;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid SHA_update(SHA_CTX *ctx, const void *data, int len) {
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i = ctx->count % sizeof(ctx->buf);
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint8_t* p = (const uint8_t*)data;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->count += len;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (len--) {
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ctx->buf[i++] = *p++;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (i == sizeof(ctx->buf)) {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            SHA1_transform(ctx);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            i = 0;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t *SHA_final(SHA_CTX *ctx) {
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t *p = ctx->buf;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint64_t cnt = ctx->count * 8;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_update(ctx, (uint8_t*)"\x80", 1);
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SHA_update(ctx, (uint8_t*)"\0", 1);
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < 8; ++i) {
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint8_t tmp = cnt >> ((7 - i) * 8);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SHA_update(ctx, &tmp, 1);
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < 5; i++) {
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp = ctx->state[i];
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 24;
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 16;
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 8;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 0;
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ctx->buf;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
282a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#endif // endianness
283a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
284a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkervoid SHA_init(SHA_CTX* ctx) {
285a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[0] = 0x67452301;
286a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[1] = 0xEFCDAB89;
287a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[2] = 0x98BADCFE;
288a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[3] = 0x10325476;
289a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[4] = 0xC3D2E1F0;
290a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->count = 0;
291a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
292a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Convenience function */
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t* SHA(const void *data, int len, uint8_t *digest) {
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint8_t *p;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_CTX ctx;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_init(&ctx);
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_update(&ctx, data, len);
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = SHA_final(&ctx);
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        digest[i] = *p++;
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return digest;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
306