Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sha1.c
00001 /* 00002 * Copyright (c) 2007, Cameron Rich 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * * Neither the name of the axTLS project nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00025 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00026 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00031 /** 00032 * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995. 00033 * This code was originally taken from RFC3174 00034 */ 00035 00036 #include <string.h> 00037 #include "os_port.h" 00038 #include "crypto.h " 00039 00040 /* 00041 * Define the SHA1 circular left shift macro 00042 */ 00043 #define SHA1CircularShift(bits,word) \ 00044 (((word) << (bits)) | ((word) >> (32-(bits)))) 00045 00046 /* ----- static functions ----- */ 00047 static void SHA1PadMessage(SHA1_CTX *ctx); 00048 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx); 00049 00050 /** 00051 * Initialize the SHA1 context 00052 */ 00053 void SHA1_Init(SHA1_CTX *ctx) 00054 { 00055 ctx->Length_Low = 0; 00056 ctx->Length_High = 0; 00057 ctx->Message_Block_Index = 0; 00058 ctx->Intermediate_Hash[0] = 0x67452301; 00059 ctx->Intermediate_Hash[1] = 0xEFCDAB89; 00060 ctx->Intermediate_Hash[2] = 0x98BADCFE; 00061 ctx->Intermediate_Hash[3] = 0x10325476; 00062 ctx->Intermediate_Hash[4] = 0xC3D2E1F0; 00063 } 00064 00065 /** 00066 * Accepts an array of octets as the next portion of the message. 00067 */ 00068 void SHA1_Update(SHA1_CTX *ctx, const uint8_t *msg, int len) 00069 { 00070 while (len--) 00071 { 00072 ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF); 00073 ctx->Length_Low += 8; 00074 00075 if (ctx->Length_Low == 0) 00076 ctx->Length_High++; 00077 00078 if (ctx->Message_Block_Index == 64) 00079 SHA1ProcessMessageBlock(ctx); 00080 00081 msg++; 00082 } 00083 } 00084 00085 /** 00086 * Return the 160-bit message digest into the user's array 00087 */ 00088 void SHA1_Final(uint8_t *digest, SHA1_CTX *ctx) 00089 { 00090 int i; 00091 00092 SHA1PadMessage(ctx); 00093 memset(ctx->Message_Block, 0, 64); 00094 ctx->Length_Low = 0; /* and clear length */ 00095 ctx->Length_High = 0; 00096 00097 for (i = 0; i < SHA1_SIZE; i++) 00098 { 00099 digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ); 00100 } 00101 } 00102 00103 /** 00104 * Process the next 512 bits of the message stored in the array. 00105 */ 00106 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx) 00107 { 00108 const uint32_t K[] = { /* Constants defined in SHA-1 */ 00109 0x5A827999, 00110 0x6ED9EBA1, 00111 0x8F1BBCDC, 00112 0xCA62C1D6 00113 }; 00114 int t; /* Loop counter */ 00115 uint32_t temp; /* Temporary word value */ 00116 uint32_t W[80]; /* Word sequence */ 00117 uint32_t A, B, C, D, E; /* Word buffers */ 00118 00119 /* 00120 * Initialize the first 16 words in the array W 00121 */ 00122 for (t = 0; t < 16; t++) 00123 { 00124 W[t] = ctx->Message_Block[t * 4] << 24; 00125 W[t] |= ctx->Message_Block[t * 4 + 1] << 16; 00126 W[t] |= ctx->Message_Block[t * 4 + 2] << 8; 00127 W[t] |= ctx->Message_Block[t * 4 + 3]; 00128 } 00129 00130 for (t = 16; t < 80; t++) 00131 { 00132 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); 00133 } 00134 00135 A = ctx->Intermediate_Hash[0]; 00136 B = ctx->Intermediate_Hash[1]; 00137 C = ctx->Intermediate_Hash[2]; 00138 D = ctx->Intermediate_Hash[3]; 00139 E = ctx->Intermediate_Hash[4]; 00140 00141 for (t = 0; t < 20; t++) 00142 { 00143 temp = SHA1CircularShift(5,A) + 00144 ((B & C) | ((~B) & D)) + E + W[t] + K[0]; 00145 E = D; 00146 D = C; 00147 C = SHA1CircularShift(30,B); 00148 00149 B = A; 00150 A = temp; 00151 } 00152 00153 for (t = 20; t < 40; t++) 00154 { 00155 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; 00156 E = D; 00157 D = C; 00158 C = SHA1CircularShift(30,B); 00159 B = A; 00160 A = temp; 00161 } 00162 00163 for (t = 40; t < 60; t++) 00164 { 00165 temp = SHA1CircularShift(5,A) + 00166 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; 00167 E = D; 00168 D = C; 00169 C = SHA1CircularShift(30,B); 00170 B = A; 00171 A = temp; 00172 } 00173 00174 for (t = 60; t < 80; t++) 00175 { 00176 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; 00177 E = D; 00178 D = C; 00179 C = SHA1CircularShift(30,B); 00180 B = A; 00181 A = temp; 00182 } 00183 00184 ctx->Intermediate_Hash[0] += A; 00185 ctx->Intermediate_Hash[1] += B; 00186 ctx->Intermediate_Hash[2] += C; 00187 ctx->Intermediate_Hash[3] += D; 00188 ctx->Intermediate_Hash[4] += E; 00189 ctx->Message_Block_Index = 0; 00190 } 00191 00192 /* 00193 * According to the standard, the message must be padded to an even 00194 * 512 bits. The first padding bit must be a '1'. The last 64 00195 * bits represent the length of the original message. All bits in 00196 * between should be 0. This function will pad the message 00197 * according to those rules by filling the Message_Block array 00198 * accordingly. It will also call the ProcessMessageBlock function 00199 * provided appropriately. When it returns, it can be assumed that 00200 * the message digest has been computed. 00201 * 00202 * @param ctx [in, out] The SHA1 context 00203 */ 00204 static void SHA1PadMessage(SHA1_CTX *ctx) 00205 { 00206 /* 00207 * Check to see if the current message block is too small to hold 00208 * the initial padding bits and length. If so, we will pad the 00209 * block, process it, and then continue padding into a second 00210 * block. 00211 */ 00212 if (ctx->Message_Block_Index > 55) 00213 { 00214 ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; 00215 while(ctx->Message_Block_Index < 64) 00216 { 00217 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 00218 } 00219 00220 SHA1ProcessMessageBlock(ctx); 00221 00222 while (ctx->Message_Block_Index < 56) 00223 { 00224 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 00225 } 00226 } 00227 else 00228 { 00229 ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; 00230 while(ctx->Message_Block_Index < 56) 00231 { 00232 00233 ctx->Message_Block[ctx->Message_Block_Index++] = 0; 00234 } 00235 } 00236 00237 /* 00238 * Store the message length as the last 8 octets 00239 */ 00240 ctx->Message_Block[56] = ctx->Length_High >> 24; 00241 ctx->Message_Block[57] = ctx->Length_High >> 16; 00242 ctx->Message_Block[58] = ctx->Length_High >> 8; 00243 ctx->Message_Block[59] = ctx->Length_High; 00244 ctx->Message_Block[60] = ctx->Length_Low >> 24; 00245 ctx->Message_Block[61] = ctx->Length_Low >> 16; 00246 ctx->Message_Block[62] = ctx->Length_Low >> 8; 00247 ctx->Message_Block[63] = ctx->Length_Low; 00248 SHA1ProcessMessageBlock(ctx); 00249 }
Generated on Tue Jul 12 2022 18:48:01 by
1.7.2