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
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mincrypt/sha.h"
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3090b06ac786f859895ac503cf42759c2706205700Doug Zongker// Some machines lack byteswap.h and endian.h.  These have to use the
3190b06ac786f859895ac503cf42759c2706205700Doug Zongker// slower code, even if they're little-endian.
3290b06ac786f859895ac503cf42759c2706205700Doug Zongker
3390b06ac786f859895ac503cf42759c2706205700Doug Zongker#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
3490b06ac786f859895ac503cf42759c2706205700Doug Zongker
3590b06ac786f859895ac503cf42759c2706205700Doug Zongker#include <byteswap.h>
3690b06ac786f859895ac503cf42759c2706205700Doug Zongker#include <memory.h>
37a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
38a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker// This version is about 28% faster than the generic version below,
39a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker// but assumes little-endianness.
40a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
41a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror27(uint32_t val) {
42a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 27) | (val << 5);
43a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
44a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror2(uint32_t val) {
45a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 2) | (val << 30);
46a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
47a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic inline uint32_t ror31(uint32_t val) {
48a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return (val >> 31) | (val << 1);
49a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
50a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
51a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerstatic void SHA1_Transform(SHA_CTX* ctx) {
52a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    uint32_t W[80];
53a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    register uint32_t A, B, C, D, E;
54a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int t;
55a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
56a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    A = ctx->state[0];
57a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ctx->state[1];
58a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    C = ctx->state[2];
59a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    D = ctx->state[3];
60a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E = ctx->state[4];
61a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
62a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F1(A,B,C,D,E,t)                     \
63a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                             \
64a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = bswap_32(ctx->buf.w[t])) +      \
65a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (D^(B&(C^D))) + 0x5A827999;             \
66a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
67a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
68a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (t = 0; t < 15; t += 5) {
69a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(A,B,C,D,E,t + 0);
70a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(E,A,B,C,D,t + 1);
71a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(D,E,A,B,C,t + 2);
72a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(C,D,E,A,B,t + 3);
73a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F1(B,C,D,E,A,t + 4);
74a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
75a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(A,B,C,D,E,t + 0);  // 16th one, t == 15
76a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
77a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F1
78a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
79a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F1(A,B,C,D,E,t)                                     \
80a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
81a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
82a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (D^(B&(C^D))) + 0x5A827999;                             \
83a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
84a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
85a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(E,A,B,C,D,t + 1);
86a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(D,E,A,B,C,t + 2);
87a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(C,D,E,A,B,t + 3);
88a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_F1(B,C,D,E,A,t + 4);
89a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
90a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F1
91a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
92a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F2(A,B,C,D,E,t)                                     \
93a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
94a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
95a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (B^C^D) + 0x6ED9EBA1;                                   \
96a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
97a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
98a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (t = 20; t < 40; t += 5) {
99a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(A,B,C,D,E,t + 0);
100a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(E,A,B,C,D,t + 1);
101a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(D,E,A,B,C,t + 2);
102a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(C,D,E,A,B,t + 3);
103a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F2(B,C,D,E,A,t + 4);
104a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
105a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
106a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F2
107a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
108a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F3(A,B,C,D,E,t)                                     \
109a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
110a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
111a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ((B&C)|(D&(B|C))) + 0x8F1BBCDC;                         \
112a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
113a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
114a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (; t < 60; t += 5) {
115a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(A,B,C,D,E,t + 0);
116a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(E,A,B,C,D,t + 1);
117a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(D,E,A,B,C,t + 2);
118a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(C,D,E,A,B,t + 3);
119a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F3(B,C,D,E,A,t + 4);
120a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
121a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
122a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F3
123a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
124a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#define SHA_F4(A,B,C,D,E,t)                                     \
125a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    E += ror27(A) +                                             \
126a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
127a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        (B^C^D) + 0xCA62C1D6;                                   \
128a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    B = ror2(B);
129a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
130a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (; t < 80; t += 5) {
131a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(A,B,C,D,E,t + 0);
132a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(E,A,B,C,D,t + 1);
133a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(D,E,A,B,C,t + 2);
134a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(C,D,E,A,B,t + 3);
135a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_F4(B,C,D,E,A,t + 4);
136a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
137a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
138a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#undef SHA_F4
139a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
140a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[0] += A;
141a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[1] += B;
142a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[2] += C;
143a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[3] += D;
144a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[4] += E;
145a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
146a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
147a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkervoid SHA_update(SHA_CTX* ctx, const void* data, int len) {
148a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int i = ctx->count % sizeof(ctx->buf);
149a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    const uint8_t* p = (const uint8_t*)data;
150a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
151a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->count += len;
152a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
153a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while (len > sizeof(ctx->buf) - i) {
154a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
155a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        len -= sizeof(ctx->buf) - i;
156a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        p += sizeof(ctx->buf) - i;
157a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA1_Transform(ctx);
158a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        i = 0;
159a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
160a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
161a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while (len--) {
162a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ctx->buf.b[i++] = *p++;
163a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        if (i == sizeof(ctx->buf)) {
164a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker            SHA1_Transform(ctx);
165a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker            i = 0;
166a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        }
167a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
168a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
169a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
170a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
171a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkerconst uint8_t* SHA_final(SHA_CTX* ctx) {
172a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    uint64_t cnt = ctx->count * 8;
173a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    int i;
174a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
175a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    SHA_update(ctx, (uint8_t*)"\x80", 1);
176a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
177a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_update(ctx, (uint8_t*)"\0", 1);
178a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
179a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (i = 0; i < 8; ++i) {
180a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        uint8_t tmp = cnt >> ((7 - i) * 8);
181a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        SHA_update(ctx, &tmp, 1);
182a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
183a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
184a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    for (i = 0; i < 5; i++) {
185a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker        ctx->buf.w[i] = bswap_32(ctx->state[i]);
186a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    }
187a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
188a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    return ctx->buf.b;
189a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
190a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
19190b06ac786f859895ac503cf42759c2706205700Doug Zongker#else   // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
192a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void SHA1_transform(SHA_CTX *ctx) {
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t W[80];
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t A, B, C, D, E;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t *p = ctx->buf;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int t;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(t = 0; t < 16; ++t) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp =  *p++ << 24;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++ << 16;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++ << 8;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp |= *p++;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        W[t] = tmp;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(; t < 80; t++) {
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    A = ctx->state[0];
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    B = ctx->state[1];
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    C = ctx->state[2];
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D = ctx->state[3];
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    E = ctx->state[4];
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(t = 0; t < 80; t++) {
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp = rol(5,A) + E + W[t];
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (t < 20)
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (D^(B&(C^D))) + 0x5A827999;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if ( t < 40)
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (B^C^D) + 0x6ED9EBA1;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if ( t < 60)
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            tmp += (B^C^D) + 0xCA62C1D6;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        E = D;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D = C;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        C = rol(30,B);
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        B = A;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        A = tmp;
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[0] += A;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[1] += B;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[2] += C;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[3] += D;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->state[4] += E;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid SHA_update(SHA_CTX *ctx, const void *data, int len) {
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i = ctx->count % sizeof(ctx->buf);
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint8_t* p = (const uint8_t*)data;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ctx->count += len;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (len--) {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ctx->buf[i++] = *p++;
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (i == sizeof(ctx->buf)) {
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            SHA1_transform(ctx);
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            i = 0;
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t *SHA_final(SHA_CTX *ctx) {
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t *p = ctx->buf;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint64_t cnt = ctx->count * 8;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_update(ctx, (uint8_t*)"\x80", 1);
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SHA_update(ctx, (uint8_t*)"\0", 1);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < 8; ++i) {
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint8_t tmp = cnt >> ((7 - i) * 8);
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SHA_update(ctx, &tmp, 1);
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < 5; i++) {
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t tmp = ctx->state[i];
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 24;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 16;
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 8;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *p++ = tmp >> 0;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ctx->buf;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
284a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker#endif // endianness
285a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
286a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongkervoid SHA_init(SHA_CTX* ctx) {
287a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[0] = 0x67452301;
288a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[1] = 0xEFCDAB89;
289a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[2] = 0x98BADCFE;
290a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[3] = 0x10325476;
291a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->state[4] = 0xC3D2E1F0;
292a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker    ctx->count = 0;
293a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker}
294a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Convenience function */
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t* SHA(const void *data, int len, uint8_t *digest) {
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint8_t *p;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_CTX ctx;
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_init(&ctx);
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SHA_update(&ctx, data, len);
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = SHA_final(&ctx);
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        digest[i] = *p++;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return digest;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
308