1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* sha.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker** Copyright 2013, 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 28515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker// Optimized for minimal code size. 29a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker 30515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include "mincrypt/sha.h" 31a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker 32515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <stdio.h> 33515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <string.h> 34515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker#include <stdint.h> 35a6de77de1727d5c40fdfdf841f3e8d13e0fc0140Doug Zongker 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerstatic void SHA1_Transform(SHA_CTX* ctx) { 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t W[80]; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t A, B, C, D, E; 41515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker uint8_t* p = ctx->buf; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int t; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = 0; t < 16; ++t) { 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = *p++ << 24; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++ << 16; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++ << 8; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp |= *p++; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project W[t] = tmp; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(; t < 80; t++) { 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project A = ctx->state[0]; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project B = ctx->state[1]; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project C = ctx->state[2]; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D = ctx->state[3]; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project E = ctx->state[4]; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = 0; t < 80; t++) { 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = rol(5,A) + E + W[t]; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t < 20) 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (D^(B&(C^D))) + 0x5A827999; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ( t < 40) 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (B^C^D) + 0x6ED9EBA1; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if ( t < 60) 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp += (B^C^D) + 0xCA62C1D6; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project E = D; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D = C; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project C = rol(30,B); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project B = A; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project A = tmp; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[0] += A; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[1] += B; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[2] += C; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[3] += D; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->state[4] += E; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerstatic const HASH_VTAB SHA_VTAB = { 89515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA_init, 90515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA_update, 91515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA_final, 92515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA_hash, 93515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA_DIGEST_SIZE 94515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker}; 95515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker 96515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkervoid SHA_init(SHA_CTX* ctx) { 97515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->f = &SHA_VTAB; 98515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->state[0] = 0x67452301; 99515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->state[1] = 0xEFCDAB89; 100515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->state[2] = 0x98BADCFE; 101515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->state[3] = 0x10325476; 102515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->state[4] = 0xC3D2E1F0; 103515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker ctx->count = 0; 104515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker} 105515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker 106515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker 107515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkervoid SHA_update(SHA_CTX* ctx, const void* data, int len) { 108515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker int i = (int) (ctx->count & 63); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const uint8_t* p = (const uint8_t*)data; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->count += len; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (len--) { 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ctx->buf[i++] = *p++; 115515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker if (i == 64) { 116515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker SHA1_Transform(ctx); 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i = 0; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 121515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker 122515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker 123515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerconst uint8_t* SHA_final(SHA_CTX* ctx) { 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint8_t *p = ctx->buf; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint64_t cnt = ctx->count * 8; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, (uint8_t*)"\x80", 1); 129515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker while ((ctx->count & 63) != 56) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, (uint8_t*)"\0", 1); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < 8; ++i) { 133515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8)); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(ctx, &tmp, 1); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < 5; i++) { 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uint32_t tmp = ctx->state[i]; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 24; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 16; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 8; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = tmp >> 0; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ctx->buf; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Convenience function */ 149515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongkerconst uint8_t* SHA_hash(const void* data, int len, uint8_t* digest) { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_CTX ctx; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_init(&ctx); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SHA_update(&ctx, data, len); 153515e1639ef0ab5e3149fafeffce826cf654d616fDoug Zongker memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return digest; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 156