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