Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencrypt_sha.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2004 Filip Navara 00003 * Based on public domain SHA code by Steve Reid <steve@edmweb.com> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include <advapi32.h> 00021 00022 /* SHA Context Structure Declaration */ 00023 00024 typedef struct { 00025 ULONG Unknown[6]; 00026 ULONG State[5]; 00027 ULONG Count[2]; 00028 UCHAR Buffer[64]; 00029 } SHA_CTX, *PSHA_CTX; 00030 00031 /* SHA1 Helper Macros */ 00032 00033 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 00034 /* FIXME: This definition of DWORD2BE is little endian specific! */ 00035 #define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000); 00036 /* FIXME: This definition of blk0 is little endian specific! */ 00037 #define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF)) 00038 #define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1)) 00039 #define f1(x,y,z) (z^(x&(y^z))) 00040 #define f2(x,y,z) (x^y^z) 00041 #define f3(x,y,z) ((x&y)|(z&(x|y))) 00042 #define f4(x,y,z) (x^y^z) 00043 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 00044 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 00045 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30); 00046 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 00047 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 00048 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 00049 00050 /* Hash a single 512-bit block. This is the core of the algorithm. */ 00051 static void SHA1Transform(ULONG State[5], UCHAR Buffer[64]) 00052 { 00053 ULONG a, b, c, d, e; 00054 ULONG *Block; 00055 00056 Block = (ULONG*)Buffer; 00057 00058 /* Copy Context->State[] to working variables */ 00059 a = State[0]; 00060 b = State[1]; 00061 c = State[2]; 00062 d = State[3]; 00063 e = State[4]; 00064 00065 /* 4 rounds of 20 operations each. Loop unrolled. */ 00066 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 00067 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 00068 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 00069 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 00070 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 00071 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 00072 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 00073 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 00074 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 00075 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 00076 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 00077 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 00078 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 00079 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 00080 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 00081 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 00082 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 00083 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 00084 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 00085 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 00086 00087 /* Add the working variables back into Context->State[] */ 00088 State[0] += a; 00089 State[1] += b; 00090 State[2] += c; 00091 State[3] += d; 00092 State[4] += e; 00093 00094 /* Wipe variables */ 00095 a = b = c = d = e = 0; 00096 } 00097 00098 00099 /****************************************************************************** 00100 * A_SHAInit [ADVAPI32.@] 00101 * 00102 * Initialize a SHA context structure. 00103 * 00104 * PARAMS 00105 * Context [O] SHA context 00106 * 00107 * RETURNS 00108 * Nothing 00109 */ 00110 VOID WINAPI 00111 A_SHAInit(PSHA_CTX Context) 00112 { 00113 /* SHA1 initialization constants */ 00114 Context->State[0] = 0x67452301; 00115 Context->State[1] = 0xEFCDAB89; 00116 Context->State[2] = 0x98BADCFE; 00117 Context->State[3] = 0x10325476; 00118 Context->State[4] = 0xC3D2E1F0; 00119 Context->Count[0] = 00120 Context->Count[1] = 0; 00121 } 00122 00123 /****************************************************************************** 00124 * A_SHAUpdate [ADVAPI32.@] 00125 * 00126 * Update a SHA context with a hashed data from supplied buffer. 00127 * 00128 * PARAMS 00129 * Context [O] SHA context 00130 * Buffer [I] hashed data 00131 * BufferSize [I] hashed data size 00132 * 00133 * RETURNS 00134 * Nothing 00135 */ 00136 VOID WINAPI 00137 A_SHAUpdate(PSHA_CTX Context, const unsigned char *Buffer, UINT BufferSize) 00138 { 00139 ULONG BufferContentSize; 00140 00141 BufferContentSize = Context->Count[1] & 63; 00142 Context->Count[1] += BufferSize; 00143 if (Context->Count[1] < BufferSize) 00144 Context->Count[0]++; 00145 Context->Count[0] += (BufferSize >> 29); 00146 00147 if (BufferContentSize + BufferSize < 64) 00148 { 00149 RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer, 00150 BufferSize); 00151 } 00152 else 00153 { 00154 while (BufferContentSize + BufferSize >= 64) 00155 { 00156 RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, 00157 64 - BufferContentSize); 00158 Buffer += 64 - BufferContentSize; 00159 BufferSize -= 64 - BufferContentSize; 00160 SHA1Transform(Context->State, Context->Buffer); 00161 BufferContentSize = 0; 00162 } 00163 RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, BufferSize); 00164 } 00165 } 00166 00167 /****************************************************************************** 00168 * A_SHAFinal [ADVAPI32.@] 00169 * 00170 * Finalize SHA context and return the resulting hash. 00171 * 00172 * PARAMS 00173 * Context [I/O] SHA context 00174 * Result [O] resulting hash 00175 * 00176 * RETURNS 00177 * Nothing 00178 */ 00179 VOID WINAPI 00180 A_SHAFinal(PSHA_CTX Context, PULONG Result) 00181 { 00182 INT Pad, Index; 00183 UCHAR Buffer[72]; 00184 ULONG *Count; 00185 ULONG BufferContentSize, LengthHi, LengthLo; 00186 00187 BufferContentSize = Context->Count[1] & 63; 00188 if (BufferContentSize >= 56) 00189 Pad = 56 + 64 - BufferContentSize; 00190 else 00191 Pad = 56 - BufferContentSize; 00192 00193 LengthHi = (Context->Count[0] << 3) | (Context->Count[1] >> (32 - 3)); 00194 LengthLo = (Context->Count[1] << 3); 00195 00196 RtlZeroMemory(Buffer + 1, Pad - 1); 00197 Buffer[0] = 0x80; 00198 Count = (ULONG*)(Buffer + Pad); 00199 Count[0] = DWORD2BE(LengthHi); 00200 Count[1] = DWORD2BE(LengthLo); 00201 A_SHAUpdate(Context, Buffer, Pad + 8); 00202 00203 for (Index = 0; Index < 5; Index++) 00204 Result[Index] = DWORD2BE(Context->State[Index]); 00205 00206 A_SHAInit(Context); 00207 } Generated on Sat May 26 2012 04:21:09 for ReactOS by
1.7.6.1
|