sha1.c revision 76d05dc695b06c4e987bb8078f78032441e1430c
1/* 2 * Copyright(C) 2006 Cameron Rich 3 * 4 * This library is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation; either version 2.1 of the License, or 7 * (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this library; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19/** 20 * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995. 21 * This code was originally taken from RFC3174 22 */ 23 24#include <string.h> 25#include "crypto.h" 26 27/* 28 * Define the SHA1 circular left shift macro 29 */ 30#define SHA1CircularShift(bits,word) \ 31 (((word) << (bits)) | ((word) >> (32-(bits)))) 32 33/* ----- static functions ----- */ 34static void SHA1PadMessage(SHA1_CTX *ctx); 35static void SHA1ProcessMessageBlock(SHA1_CTX *ctx); 36 37/** 38 * Initialize the SHA1 context 39 */ 40void SHA1Init(SHA1_CTX *ctx) 41{ 42 ctx->Length_Low = 0; 43 ctx->Length_High = 0; 44 ctx->Message_Block_Index = 0; 45 ctx->Intermediate_Hash[0] = 0x67452301; 46 ctx->Intermediate_Hash[1] = 0xEFCDAB89; 47 ctx->Intermediate_Hash[2] = 0x98BADCFE; 48 ctx->Intermediate_Hash[3] = 0x10325476; 49 ctx->Intermediate_Hash[4] = 0xC3D2E1F0; 50} 51 52/** 53 * Accepts an array of octets as the next portion of the message. 54 */ 55void SHA1Update(SHA1_CTX *ctx, const uint8_t *msg, int len) 56{ 57 while (len--) 58 { 59 ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF); 60 61 ctx->Length_Low += 8; 62 if (ctx->Length_Low == 0) 63 { 64 ctx->Length_High++; 65 } 66 67 if (ctx->Message_Block_Index == 64) 68 { 69 SHA1ProcessMessageBlock(ctx); 70 } 71 72 msg++; 73 } 74} 75 76/** 77 * Return the 160-bit message digest into the user's array 78 */ 79void SHA1Final(SHA1_CTX *ctx, uint8_t *digest) 80{ 81 int i; 82 83 SHA1PadMessage(ctx); 84 memset(ctx->Message_Block, 0, 64); 85 ctx->Length_Low = 0; /* and clear length */ 86 ctx->Length_High = 0; 87 88 for (i = 0; i < SHA1_SIZE; i++) 89 { 90 digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); 91 } 92} 93 94/** 95 * Process the next 512 bits of the message stored in the array. 96 */ 97static void SHA1ProcessMessageBlock(SHA1_CTX *ctx) 98{ 99 const uint32_t K[] = { /* Constants defined in SHA-1 */ 100 0x5A827999, 101 0x6ED9EBA1, 102 0x8F1BBCDC, 103 0xCA62C1D6 104 }; 105 int t; /* Loop counter */ 106 uint32_t temp; /* Temporary word value */ 107 uint32_t W[80]; /* Word sequence */ 108 uint32_t A, B, C, D, E; /* Word buffers */ 109 110 /* 111 * Initialize the first 16 words in the array W 112 */ 113 for (t = 0; t < 16; t++) 114 { 115 W[t] = ctx->Message_Block[t * 4] << 24; 116 W[t] |= ctx->Message_Block[t * 4 + 1] << 16; 117 W[t] |= ctx->Message_Block[t * 4 + 2] << 8; 118 W[t] |= ctx->Message_Block[t * 4 + 3]; 119 } 120 121 for (t = 16; t < 80; t++) 122 { 123 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 124 } 125 126 A = ctx->Intermediate_Hash[0]; 127 B = ctx->Intermediate_Hash[1]; 128 C = ctx->Intermediate_Hash[2]; 129 D = ctx->Intermediate_Hash[3]; 130 E = ctx->Intermediate_Hash[4]; 131 132 for (t = 0; t < 20; t++) 133 { 134 temp = SHA1CircularShift(5,A) + 135 ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 136 E = D; 137 D = C; 138 C = SHA1CircularShift(30,B); 139 140 B = A; 141 A = temp; 142 } 143 144 for (t = 20; t < 40; t++) 145 { 146 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 147 E = D; 148 D = C; 149 C = SHA1CircularShift(30,B); 150 B = A; 151 A = temp; 152 } 153 154 for (t = 40; t < 60; t++) 155 { 156 temp = SHA1CircularShift(5,A) + 157 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 158 E = D; 159 D = C; 160 C = SHA1CircularShift(30,B); 161 B = A; 162 A = temp; 163 } 164 165 for (t = 60; t < 80; t++) 166 { 167 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 168 E = D; 169 D = C; 170 C = SHA1CircularShift(30,B); 171 B = A; 172 A = temp; 173 } 174 175 ctx->Intermediate_Hash[0] += A; 176 ctx->Intermediate_Hash[1] += B; 177 ctx->Intermediate_Hash[2] += C; 178 ctx->Intermediate_Hash[3] += D; 179 ctx->Intermediate_Hash[4] += E; 180 ctx->Message_Block_Index = 0; 181} 182 183/* 184 * According to the standard, the message must be padded to an even 185 * 512 bits. The first padding bit must be a '1'. The last 64 186 * bits represent the length of the original message. All bits in 187 * between should be 0. This function will pad the message 188 * according to those rules by filling the Message_Block array 189 * accordingly. It will also call the ProcessMessageBlock function 190 * provided appropriately. When it returns, it can be assumed that 191 * the message digest has been computed. 192 * 193 * @param ctx [in, out] The SHA1 context 194 */ 195static void SHA1PadMessage(SHA1_CTX *ctx) 196{ 197 /* 198 * Check to see if the current message block is too small to hold 199 * the initial padding bits and length. If so, we will pad the 200 * block, process it, and then continue padding into a second 201 * block. 202 */ 203 if (ctx->Message_Block_Index > 55) 204 { 205 ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; 206 while(ctx->Message_Block_Index < 64) 207 { 208 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 209 } 210 211 SHA1ProcessMessageBlock(ctx); 212 213 while (ctx->Message_Block_Index < 56) 214 { 215 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 216 } 217 } 218 else 219 { 220 ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; 221 while(ctx->Message_Block_Index < 56) 222 { 223 224 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 225 } 226 } 227 228 /* 229 * Store the message length as the last 8 octets 230 */ 231 ctx->Message_Block[56] = ctx->Length_High >> 24; 232 ctx->Message_Block[57] = ctx->Length_High >> 16; 233 ctx->Message_Block[58] = ctx->Length_High >> 8; 234 ctx->Message_Block[59] = ctx->Length_High; 235 ctx->Message_Block[60] = ctx->Length_Low >> 24; 236 ctx->Message_Block[61] = ctx->Length_Low >> 16; 237 ctx->Message_Block[62] = ctx->Length_Low >> 8; 238 ctx->Message_Block[63] = ctx->Length_Low; 239 SHA1ProcessMessageBlock(ctx); 240} 241