[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / sha1.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // 
5 //
6 //
7 // ===========================================================================
8 // File: sha1.cpp
9 // 
10 // ===========================================================================
11 /*++
12
13 Abstract:
14
15     SHA-1 implementation
16
17 Revision History:
18
19 --*/
20
21 /*
22        File sha1.cpp    <STRIP>Version 03 August 2000.</STRIP>
23                    
24                      
25       This implements the SHA-1 hash function.  
26       For algorithmic background see (for example)
27
28
29            Alfred J. Menezes et al
30            Handbook of Applied Cryptography
31            The CRC Press Series on Discrete Mathematics
32                    and its Applications
33            CRC Press LLC, 1997
34            ISBN 0-8495-8523-7
35            QA76.9A25M643
36
37        Also see FIPS 180-1 - Secure Hash Standard, 
38        1993 May 11 and 1995 April 17, by the U.S.
39        National Institute of Standards and Technology (NIST).
40
41 */
42
43 #include "common.h"
44 #include "sha1.h"
45 #include "contract.h"
46
47 typedef const DWORD DWORDC;
48 #define ROTATE32L(x,n) _rotl(x,n)
49 #define SHAVE32(x)     (DWORD)(x)
50
51 static void SHA1_block(SHA1_CTX *ctx)
52 /*
53      Update the SHA-1 hash from a fresh 64 bytes of data.
54 */
55
56     static DWORDC sha1_round1 = 0x5A827999u; 
57     static DWORDC sha1_round2 = 0x6ED9EBA1u;
58     static DWORDC sha1_round3 = 0x8F1BBCDCu;
59     static DWORDC sha1_round4 = 0xCA62C1D6u;
60     
61     DWORD a = ctx->partial_hash[0], b = ctx->partial_hash[1]; 
62     DWORD c = ctx->partial_hash[2], d = ctx->partial_hash[3];
63     DWORD e = ctx->partial_hash[4];
64     DWORD  msg80[80]; 
65     int i;
66     BOOL OK = TRUE;
67
68     // OACR note:
69     // Loop conditions are using (i <= limit - increment) instead of (i < limit) to satisfy OACR. When the increment is greater
70     // than 1, OACR incorrectly thinks that the max value of 'i' is (limit - 1).
71
72     for (i = 0; i < 16; i++) {   // Copy to local array, zero original
73                                   // Extend length to 80
74         DWORDC datval = ctx->awaiting_data[i];
75         ctx->awaiting_data[i] = 0;
76         msg80[i] = datval;
77     }
78
79     for (i = 16; i <= 80 - 2; i += 2) {
80         DWORDC temp1 =    msg80[i-3] ^ msg80[i-8] 
81                         ^ msg80[i-14] ^ msg80[i-16];
82         DWORDC temp2 =    msg80[i-2] ^ msg80[i-7] 
83                         ^ msg80[i-13] ^ msg80[i-15];
84         msg80[i  ] = ROTATE32L(temp1, 1);
85         msg80[i+1] = ROTATE32L(temp2, 1);
86     }
87   
88 #define ROUND1(B, C, D) ((D ^ (B & (C ^ D))) + sha1_round1)
89                         //  Equivalent to (B & C) | (~B & D).
90                         //  (check cases B = 0 and B = 1)
91 #define ROUND2(B, C, D) ((B ^ C ^ D) + sha1_round2)
92
93 #define ROUND3(B, C, D) (((C & (B | D)) | (B & D)) + sha1_round3)
94
95 #define ROUND4(B, C, D) ((B ^ C ^ D) + sha1_round4)
96
97 // Round 1
98     for (i = 0; i <= 20 - 5; i += 5) { 
99         e += ROTATE32L(a, 5) + ROUND1(b, c, d) + msg80[i];
100         b = ROTATE32L(b, 30);
101
102         d += ROTATE32L(e, 5) + ROUND1(a, b, c) + msg80[i+1];
103         a = ROTATE32L(a, 30);
104
105         c += ROTATE32L(d, 5) + ROUND1(e, a, b) + msg80[i+2];
106         e = ROTATE32L(e, 30);
107
108         b += ROTATE32L(c, 5) + ROUND1(d, e, a) + msg80[i+3];
109         d = ROTATE32L(d, 30);
110
111         a += ROTATE32L(b, 5) + ROUND1(c, d, e) + msg80[i+4];
112         c = ROTATE32L(c, 30);
113 #if 0
114         printf("i = %ld %08lx %08lx %08lx %08lx %08lx\n", 
115             i, a, b, c, d, e);
116 #endif
117     } // for i
118
119 // Round 2
120     for (i = 20; i <= 40 - 5; i += 5) { 
121         e += ROTATE32L(a, 5) + ROUND2(b, c, d) + msg80[i];
122         b = ROTATE32L(b, 30);
123
124         d += ROTATE32L(e, 5) + ROUND2(a, b, c) + msg80[i+1];
125         a = ROTATE32L(a, 30);
126
127         c += ROTATE32L(d, 5) + ROUND2(e, a, b) + msg80[i+2];
128         e = ROTATE32L(e, 30);
129
130         b += ROTATE32L(c, 5) + ROUND2(d, e, a) + msg80[i+3];
131         d = ROTATE32L(d, 30);
132
133         a += ROTATE32L(b, 5) + ROUND2(c, d, e) + msg80[i+4];
134         c = ROTATE32L(c, 30);
135     } // for i
136
137 // Round 3
138     for (i = 40; i <= 60 - 5; i += 5) { 
139         e += ROTATE32L(a, 5) + ROUND3(b, c, d) + msg80[i];
140         b = ROTATE32L(b, 30);
141
142         d += ROTATE32L(e, 5) + ROUND3(a, b, c) + msg80[i+1];
143         a = ROTATE32L(a, 30);
144
145         c += ROTATE32L(d, 5) + ROUND3(e, a, b) + msg80[i+2];
146         e = ROTATE32L(e, 30);
147
148         b += ROTATE32L(c, 5) + ROUND3(d, e, a) + msg80[i+3];
149         d = ROTATE32L(d, 30);
150
151         a += ROTATE32L(b, 5) + ROUND3(c, d, e) + msg80[i+4];
152         c = ROTATE32L(c, 30);
153     } // for i
154
155 // Round 4
156     for (i = 60; i <= 80 - 5; i += 5) { 
157         e += ROTATE32L(a, 5) + ROUND4(b, c, d) + msg80[i];
158         b = ROTATE32L(b, 30);
159
160         d += ROTATE32L(e, 5) + ROUND4(a, b, c) + msg80[i+1];
161         a = ROTATE32L(a, 30);
162
163         c += ROTATE32L(d, 5) + ROUND4(e, a, b) + msg80[i+2];
164         e = ROTATE32L(e, 30);
165
166         b += ROTATE32L(c, 5) + ROUND4(d, e, a) + msg80[i+3];
167         d = ROTATE32L(d, 30);
168
169         a += ROTATE32L(b, 5) + ROUND4(c, d, e) + msg80[i+4];
170         c = ROTATE32L(c, 30);
171     } // for i
172
173 #undef ROUND1
174 #undef ROUND2
175 #undef ROUND3
176 #undef ROUND4
177
178     ctx->partial_hash[0] += a;
179     ctx->partial_hash[1] += b;
180     ctx->partial_hash[2] += c;
181     ctx->partial_hash[3] += d;
182     ctx->partial_hash[4] += e;
183 #if 0
184     for (i = 0; i < 16; i++) {
185         printf("%8lx ", msg16[i]);
186         if ((i & 7) == 7) printf("\n");
187     }
188     printf("a, b, c, d, e = %08lx %08lx %08lx %08lx %08lx\n", 
189         a, b, c, d, e);
190     printf("Partial hash = %08lx %08lx %08lx %08lx %08lx\n",
191         (long)ctx->partial_hash[0], (long)ctx->partial_hash[1],
192         (long)ctx->partial_hash[2], (long)ctx->partial_hash[3],
193         (long)ctx->partial_hash[4]);
194 #endif 
195 } // end SHA1_block
196
197
198 void SHA1Hash::SHA1Init(SHA1_CTX *ctx)
199 {
200     CONTRACTL {
201         NOTHROW;
202         GC_NOTRIGGER;
203         MODE_ANY;
204     } CONTRACTL_END;
205     
206     ctx->nbit_total[0] = ctx->nbit_total[1] = 0;
207     
208     for (DWORD i = 0; i != 16; i++) {
209         ctx->awaiting_data[i] = 0;
210     }
211    
212      /* 
213          Initialize hash variables.
214          
215      */
216
217     ctx->partial_hash[0] = 0x67452301u;
218     ctx->partial_hash[1] = 0xefcdab89u;
219     ctx->partial_hash[2] = ~ctx->partial_hash[0];
220     ctx->partial_hash[3] = ~ctx->partial_hash[1];
221     ctx->partial_hash[4] = 0xc3d2e1f0u;
222
223
224
225 void SHA1Hash::SHA1Update(
226         SHA1_CTX *  ctx,        // IN/OUT
227         const BYTE *    msg,    // IN
228         DWORD           nbyte)  // IN
229 /*
230     Append data to a partially hashed SHA-1 message.
231 */
232 {
233     CONTRACTL {
234         NOTHROW;
235         GC_NOTRIGGER;
236         MODE_ANY;
237     } CONTRACTL_END;
238     
239     const BYTE *fresh_data = msg;
240     DWORD nbyte_left = nbyte;
241     DWORD nbit_occupied = ctx->nbit_total[0] & 511;
242     DWORD *awaiting_data;
243     DWORDC nbitnew_low = SHAVE32(8*nbyte);
244
245
246     _ASSERTE((nbit_occupied & 7) == 0);   // Partial bytes not implemented
247     
248     ctx->nbit_total[0] += nbitnew_low;
249     ctx->nbit_total[1] += (nbyte >> 29) 
250            + (SHAVE32(ctx->nbit_total[0]) < nbitnew_low);
251
252         /* Advance to word boundary in waiting_data */
253     
254     if ((nbit_occupied & 31) != 0) {
255         awaiting_data = ctx->awaiting_data + nbit_occupied/32;
256
257         while ((nbit_occupied & 31) != 0 && nbyte_left != 0) {
258             nbit_occupied += 8;
259             *awaiting_data |= (DWORD)*fresh_data++ 
260                      << ((-(int)nbit_occupied) & 31);
261             nbyte_left--;            // Start at most significant byte
262         }
263     } // if nbit_occupied
264
265              /* Transfer 4 bytes at a time */
266
267     do {
268         DWORDC nword_occupied = nbit_occupied/32;
269         DWORD nwcopy = min(nbyte_left/4, 16 - nword_occupied);
270         _ASSERTE (nbit_occupied <= 512);
271         _ASSERTE ((nbit_occupied & 31) == 0 || nbyte_left == 0);
272         awaiting_data = ctx->awaiting_data + nword_occupied;
273         nbyte_left -= 4*nwcopy;
274         nbit_occupied += 32*nwcopy;
275
276         while (nwcopy != 0) {
277             DWORDC byte0 = (DWORD)fresh_data[0];
278             DWORDC byte1 = (DWORD)fresh_data[1];
279             DWORDC byte2 = (DWORD)fresh_data[2];
280             DWORDC byte3 = (DWORD)fresh_data[3];
281             *awaiting_data++ = byte3 | (byte2 << 8)
282                         | (byte1 << 16) | (byte0 << 24);
283                              /* Big endian */
284             fresh_data += 4;
285             nwcopy--;
286         } 
287
288         if (nbit_occupied == 512) {
289             SHA1_block(ctx);
290             nbit_occupied = 0;
291             awaiting_data -= 16;
292             _ASSERTE(awaiting_data == ctx->awaiting_data);
293         }
294     } while (nbyte_left >= 4); 
295
296     _ASSERTE (ctx->awaiting_data + nbit_occupied/32
297                        == awaiting_data);
298
299     while (nbyte_left != 0) {
300         DWORDC new_byte = (DWORD)*fresh_data++;
301
302         _ASSERTE((nbit_occupied & 31) <= 16);
303         nbit_occupied += 8;
304         *awaiting_data |= new_byte << ((-(int)nbit_occupied) & 31);
305         nbyte_left--;
306     }
307     
308     _ASSERTE (nbit_occupied == (ctx->nbit_total[0] & 511));
309 } // end SHA1Update
310
311
312
313 void SHA1Hash::SHA1Final(
314         SHA1_CTX *  ctx,            // IN/OUT
315         BYTE *          digest)     // OUT
316 /*
317         Finish a SHA-1 hash.
318 */
319 {
320     CONTRACTL {
321         NOTHROW;
322         GC_NOTRIGGER;
323         MODE_ANY;
324     } CONTRACTL_END;
325     
326     DWORDC nbit0 = ctx->nbit_total[0];
327     DWORDC nbit1 = ctx->nbit_total[1];
328     DWORD  nbit_occupied = nbit0 & 511;
329     DWORD i;
330
331     _ASSERTE((nbit_occupied & 7) == 0);
332
333     ctx->awaiting_data[nbit_occupied/32] 
334          |= (DWORD)0x80 << ((-8-nbit_occupied) & 31);
335                           // Append a 1 bit
336     nbit_occupied += 8;
337
338
339     // Append zero bits until length (in bits) is 448 mod 512.
340     // Then append the length, in bits.
341     // Here we assume the buffer was zeroed earlier.
342
343     if (nbit_occupied > 448) {   // If fewer than 64 bits left
344         SHA1_block(ctx);
345         nbit_occupied = 0;
346     }
347     ctx->awaiting_data[14] = nbit1;
348     ctx->awaiting_data[15] = nbit0;
349     SHA1_block(ctx);
350
351          /* Copy final digest to user-supplied byte array */
352
353     for (i = 0; i != 5; i++) {
354         DWORDC dwi = ctx->partial_hash[i];
355         digest[4*i + 0] = (BYTE)((dwi >> 24) & 255);
356         digest[4*i + 1] = (BYTE)((dwi >> 16) & 255);
357         digest[4*i + 2] = (BYTE)((dwi >>  8) & 255);
358         digest[4*i + 3] = (BYTE)(dwi         & 255);  // Big-endian
359     }
360 } // end SHA1Final
361
362 SHA1Hash::SHA1Hash()
363 {
364     CONTRACTL {
365         NOTHROW;
366         GC_NOTRIGGER;
367         MODE_ANY;
368     } CONTRACTL_END;
369
370     m_fFinalized = FALSE;
371     SHA1Init(&m_Context);
372 }
373     
374 void SHA1Hash::AddData(BYTE *pbData, DWORD cbData)
375 {
376     CONTRACTL {
377         NOTHROW;
378         GC_NOTRIGGER;
379         MODE_ANY;
380     } CONTRACTL_END;
381     
382     if (m_fFinalized)
383         return;
384         
385     SHA1Update(&m_Context, pbData, cbData);
386 }
387
388 // Retrieve a pointer to the final hash.
389 BYTE *SHA1Hash::GetHash()
390 {
391     CONTRACTL {
392         NOTHROW;
393         GC_NOTRIGGER;
394         MODE_ANY;
395     } CONTRACTL_END;
396
397     if (m_fFinalized)
398         return m_Value;
399
400     SHA1Final(&m_Context, m_Value);
401      
402     m_fFinalized = TRUE;
403
404     return m_Value;
405 }
406