Line data Source code
1 : /* sha1.cpp
2 :
3 : Copyright (c) 2005 Michael D. Leonhard
4 :
5 : http://tamale.net/
6 :
7 : Permission is hereby granted, free of charge, to any person obtaining a copy of
8 : this software and associated documentation files (the "Software"), to deal in
9 : the Software without restriction, including without limitation the rights to
10 : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 : of the Software, and to permit persons to whom the Software is furnished to do
12 : so, subject to the following conditions:
13 :
14 : The above copyright notice and this permission notice shall be included in all
15 : copies or substantial portions of the Software.
16 :
17 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 : SOFTWARE.
24 :
25 : */
26 :
27 : #include <stdio.h>
28 : #include <string.h>
29 : #include <stdlib.h>
30 : #include <assert.h>
31 :
32 : #include "sha1.h"
33 :
34 : // print out memory in hexadecimal
35 0 : void SHA1::hexPrinter( unsigned char* c, int l )
36 : {
37 : assert( c );
38 : assert( l > 0 );
39 0 : while( l > 0 )
40 : {
41 0 : printf( " %02x", *c );
42 0 : l--;
43 0 : c++;
44 : }
45 0 : }
46 :
47 : // circular left bit rotation. MSB wraps around to LSB
48 45799712 : Uint32 SHA1::lrot( Uint32 x, int bits )
49 : {
50 45799712 : return (x<<bits) | (x>>(32 - bits));
51 : };
52 :
53 : // Save a 32-bit unsigned integer to memory, in big-endian order
54 18445 : void SHA1::storeBigEndianUint32( unsigned char* byte, Uint32 num )
55 : {
56 : assert( byte );
57 18445 : byte[0] = (unsigned char)(num>>24);
58 18445 : byte[1] = (unsigned char)(num>>16);
59 18445 : byte[2] = (unsigned char)(num>>8);
60 18445 : byte[3] = (unsigned char)num;
61 18445 : }
62 :
63 :
64 : // Constructor *******************************************************
65 2635 : SHA1::SHA1()
66 : {
67 : // make sure that the data type is the right size
68 : assert( sizeof( Uint32 ) * 5 == 20 );
69 :
70 : // initialize
71 2635 : H0 = 0x67452301;
72 2635 : H1 = 0xefcdab89;
73 2635 : H2 = 0x98badcfe;
74 2635 : H3 = 0x10325476;
75 2635 : H4 = 0xc3d2e1f0;
76 2635 : unprocessedBytes = 0;
77 2635 : size = 0;
78 2635 : }
79 :
80 : // Destructor ********************************************************
81 5270 : SHA1::~SHA1()
82 : {
83 : // erase data
84 2635 : H0 = H1 = H2 = H3 = H4 = 0;
85 2635 : for( int c = 0; c < 64; c++ ) bytes[c] = 0;
86 2635 : unprocessedBytes = size = 0;
87 2635 : }
88 :
89 : // process ***********************************************************
90 204463 : void SHA1::process()
91 : {
92 : assert( unprocessedBytes == 64 );
93 : //printf( "process: " ); hexPrinter( bytes, 64 ); printf( "\n" );
94 : int t;
95 : Uint32 a, b, c, d, e, K, f, W[80];
96 : // starting values
97 204463 : a = H0;
98 204463 : b = H1;
99 204463 : c = H2;
100 204463 : d = H3;
101 204463 : e = H4;
102 : // copy and expand the message block
103 3475871 : for( t = 0; t < 16; t++ ) W[t] = (bytes[t*4] << 24)
104 3271408 : +(bytes[t*4 + 1] << 16)
105 3271408 : +(bytes[t*4 + 2] << 8)
106 3271408 : + bytes[t*4 + 3];
107 13290095 : for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 );
108 :
109 : /* main loop */
110 : Uint32 temp;
111 16561503 : for( t = 0; t < 80; t++ )
112 : {
113 16357040 : if( t < 20 ) {
114 4089260 : K = 0x5a827999;
115 4089260 : f = (b & c) | ((b ^ 0xFFFFFFFF) & d);//TODO: try using ~
116 12267780 : } else if( t < 40 ) {
117 4089260 : K = 0x6ed9eba1;
118 4089260 : f = b ^ c ^ d;
119 8178520 : } else if( t < 60 ) {
120 4089260 : K = 0x8f1bbcdc;
121 4089260 : f = (b & c) | (b & d) | (c & d);
122 : } else {
123 4089260 : K = 0xca62c1d6;
124 4089260 : f = b ^ c ^ d;
125 : }
126 16357040 : temp = lrot(a,5) + f + e + W[t] + K;
127 16357040 : e = d;
128 16357040 : d = c;
129 16357040 : c = lrot(b,30);
130 16357040 : b = a;
131 16357040 : a = temp;
132 : //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e );
133 : }
134 : /* add variables */
135 204463 : H0 += a;
136 204463 : H1 += b;
137 204463 : H2 += c;
138 204463 : H3 += d;
139 204463 : H4 += e;
140 : //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 );
141 : /* all bytes have been processed */
142 204463 : unprocessedBytes = 0;
143 204463 : }
144 :
145 : // addBytes **********************************************************
146 8150 : void SHA1::addBytes( const char* data, int num )
147 : {
148 : assert( data );
149 : assert( num >= 0 );
150 : // add these bytes to the running total
151 8150 : size += num;
152 : // repeat until all data is processed
153 427474 : while( num > 0 )
154 : {
155 : // number of bytes required to complete block
156 209662 : int needed = 64 - unprocessedBytes;
157 : assert( needed > 0 );
158 : // number of bytes to copy (use smaller of two)
159 209662 : int toCopy = (num < needed) ? num : needed;
160 : // Copy the bytes
161 209662 : memcpy( bytes + unprocessedBytes, data, toCopy );
162 : // Bytes have been copied
163 209662 : num -= toCopy;
164 209662 : data += toCopy;
165 209662 : unprocessedBytes += toCopy;
166 :
167 : // there is a full block
168 209662 : if( unprocessedBytes == 64 ) process();
169 : }
170 8150 : }
171 :
172 : // digest ************************************************************
173 2635 : unsigned char* SHA1::getDigest()
174 : {
175 : // save the message size
176 2635 : Uint32 totalBitsL = size << 3;
177 2635 : Uint32 totalBitsH = size >> 29;
178 : // add 0x80 to the message
179 2635 : addBytes( "\x80", 1 );
180 :
181 : unsigned char footer[64] = {
182 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
183 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 2635 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
186 : // block has no room for 8-byte filesize, so finish it
187 2635 : if( unprocessedBytes > 56 )
188 245 : addBytes( (char*)footer, 64 - unprocessedBytes);
189 : assert( unprocessedBytes <= 56 );
190 : // how many zeros do we need
191 2635 : int neededZeros = 56 - unprocessedBytes;
192 : // store file size (in bits) in big-endian format
193 2635 : storeBigEndianUint32( footer + neededZeros , totalBitsH );
194 2635 : storeBigEndianUint32( footer + neededZeros + 4, totalBitsL );
195 : // finish the final block
196 2635 : addBytes( (char*)footer, neededZeros + 8 );
197 : // allocate memory for the digest bytes
198 2635 : unsigned char* digest = (unsigned char*)malloc( 20 );
199 : // copy the digest bytes
200 2635 : storeBigEndianUint32( digest, H0 );
201 2635 : storeBigEndianUint32( digest + 4, H1 );
202 2635 : storeBigEndianUint32( digest + 8, H2 );
203 2635 : storeBigEndianUint32( digest + 12, H3 );
204 2635 : storeBigEndianUint32( digest + 16, H4 );
205 : // return the digest
206 2635 : return digest;
207 : }
|