sha.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
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** 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 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 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 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, 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 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 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void SHA1_transform(SHA_CTX *ctx) { 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t W[80]; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t A, B, C, D, E; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint8_t *p = ctx->buf; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int t; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = 0; t < 16; ++t) { 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = *p++ << 24; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++ << 16; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++ << 8; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project W[t] = tmp; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(; t < 80; t++) { 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project A = ctx->state[0]; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project B = ctx->state[1]; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project C = ctx->state[2]; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D = ctx->state[3]; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project E = ctx->state[4]; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = 0; t < 80; t++) { 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = rol(5,A) + E + W[t]; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t < 20) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (D^(B&(C^D))) + 0x5A827999; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ( t < 40) 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (B^C^D) + 0x6ED9EBA1; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ( t < 60) 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (B^C^D) + 0xCA62C1D6; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project E = D; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D = C; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project C = rol(30,B); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project B = A; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project A = tmp; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[0] += A; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[1] += B; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[2] += C; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[3] += D; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[4] += E; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid SHA_init(SHA_CTX *ctx) { 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[0] = 0x67452301; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[1] = 0xEFCDAB89; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[2] = 0x98BADCFE; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[3] = 0x10325476; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[4] = 0xC3D2E1F0; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->count = 0; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid SHA_update(SHA_CTX *ctx, const void *data, int len) { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i = ctx->count % sizeof(ctx->buf); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const uint8_t* p = (const uint8_t*)data; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->count += len; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (len--) { 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->buf[i++] = *p++; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i == sizeof(ctx->buf)) { 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA1_transform(ctx); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i = 0; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t *SHA_final(SHA_CTX *ctx) { 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint8_t *p = ctx->buf; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint64_t cnt = ctx->count * 8; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, (uint8_t*)"\x80", 1); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, (uint8_t*)"\0", 1); 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < 8; ++i) { 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint8_t tmp = cnt >> ((7 - i) * 8); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, &tmp, 1); 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < 5; i++) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = ctx->state[i]; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 24; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 16; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 8; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 0; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ctx->buf; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Convenience function */ 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst uint8_t* SHA(const void *data, int len, uint8_t *digest) { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const uint8_t *p; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_CTX ctx; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_init(&ctx); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, data, len); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = SHA_final(&ctx); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < SHA_DIGEST_SIZE; ++i) { 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project digest[i] = *p++; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return digest; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 143