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