]> git.stg.codes - ssmd.git/blob - 3rdparty/snmp++/src/sha.cpp
Initial adding
[ssmd.git] / 3rdparty / snmp++ / src / sha.cpp
1 /*_############################################################################
2   _## 
3   _##  sha.cpp  
4   _##
5   _##  SNMP++v3.2.25
6   _##  -----------------------------------------------
7   _##  Copyright (c) 2001-2010 Jochen Katz, Frank Fock
8   _##
9   _##  This software is based on SNMP++2.6 from Hewlett Packard:
10   _##  
11   _##    Copyright (c) 1996
12   _##    Hewlett-Packard Company
13   _##  
14   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15   _##  Permission to use, copy, modify, distribute and/or sell this software 
16   _##  and/or its documentation is hereby granted without fee. User agrees 
17   _##  to display the above copyright notice and this license notice in all 
18   _##  copies of the software and any documentation of the software. User 
19   _##  agrees to assume all liability for the use of the software; 
20   _##  Hewlett-Packard and Jochen Katz make no representations about the 
21   _##  suitability of this software for any purpose. It is provided 
22   _##  "AS-IS" without warranty of any kind, either express or implied. User 
23   _##  hereby grants a royalty-free license to any and all derivatives based
24   _##  upon this software code base. 
25   _##  
26   _##  Stuttgart, Germany, Thu Sep  2 00:07:47 CEST 2010 
27   _##  
28   _##########################################################################*/
29 char sha_cpp_version[]="#(@) SNMP++ $Id: sha.cpp 1549 2009-06-26 19:42:55Z katz $";
30
31 #include "snmp_pp/sha.h"
32
33 #if !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
34
35 /*****************************************************************
36  * SHS.c  -  Secure Hash Standard (draft) FIPS 180-1             *
37  *                                                               *
38  * Copyright (C) 1994  Uri Blumenthal, uri@watson.ibm.com        *
39  * Copyright (C) 1994  IBM T. J. Watson esearch Center           *
40  *                                                               *
41  * Feel free to use this code,  as long as you acknowledge the   *
42  * ownership by U. Blumenthal and IBM Corp.  and agree to hold   *
43  * both harmless in case of ANY problem you may have with this   *
44  * code.                                                         *
45  *****************************************************************/
46
47 #if !(defined (CPU) && CPU == PPC603)
48 #include <memory.h>
49 #else
50 #include <string.h>
51 #endif
52 #include <stdio.h>
53
54 #ifdef SNMP_PP_NAMESPACE
55 namespace Snmp_pp {
56 #endif
57
58 #define K1 0x5A827999
59 #define K2 0x6ED9EBA1
60 #define K3 0x8F1BBCDC
61 #define K4 0xCA62C1D6
62
63 #define F1(B, C, D) ((B & C) | (~B & D))
64 #define F2(B, C, D) (B ^ C ^ D)
65 #define F3(B, C, D) ((B & C) | (B & D) | (C & D))
66 #define F4(B, C, D) (B ^ C ^ D)
67
68 #define ROL(A, K) ((A << K) | (A >> (32 - K)))
69
70 #if !defined(i386) && !defined(_IBMR2)
71 static int msb_flag = 0;    /* ENDIAN-ness of CPU    */
72 #endif
73
74 static void SHATransform(SHA_CTX *ctx, const unsigned char *X)
75 {
76   unsigned /* long */ int a, b, c, d, e, temp = 0;
77   unsigned /* long */ int W[80]; /* Work array for SHS    */
78   int i;
79
80 #ifdef _IBMR2
81     unsigned long int *p = (unsigned long int *)X;
82     memcpy((char *)&W[0], p, 64);
83 #else
84 #ifndef i386
85   unsigned long int *p = (unsigned long int *)X;
86   if (msb_flag)
87     memcpy((char *)&W[0], p, 64);
88   else
89 #endif /* ~i386 */
90     for (i = 0; i < 64; i += 4)
91       W[(i/4)] = X[i+3] | (X[i+2] << 8) |
92         (X[i+1] << 16) | (X[i] << 24);
93 #endif /* _IBMR2 */
94
95   for (i = 16; i < 80; i++)
96     W[i] = ROL((W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]), 1);
97
98   a = ctx->h[0];
99   b = ctx->h[1];
100   c = ctx->h[2];
101   d = ctx->h[3];
102   e = ctx->h[4];
103
104   for (i =  0; i <= 19; i++) {
105     temp = ROL(a, 5) + F1(b, c, d) + e + K1 + W[i];
106     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
107   }
108
109   for (i = 20; i <= 39; i++) {
110     temp = ROL(a, 5) + F2(b, c, d) + e + K2 + W[i];
111     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
112   }
113
114   for (i = 40; i <= 59; i++) {
115     temp = ROL(a, 5) + F3(b, c, d) + e + K3 + W[i];
116     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
117   }
118
119   for (i = 60; i <= 79; i++) {
120     temp = ROL(a, 5) + F4(b, c, d) + e + K4 + W[i];
121     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
122   }
123
124   ctx->h[0] += a;
125   ctx->h[1] += b;
126   ctx->h[2] += c;
127   ctx->h[3] += d;
128   ctx->h[4] += e;
129 }
130
131
132 void SHAInit(SHA_CTX *ctx)
133 {
134 #if !defined(i386) && !defined(_IBMR2)
135   union z_test {
136     unsigned char ch[4];
137     unsigned long ll;
138   } z_t;
139 #endif
140   /* Zero the SHS Context */
141   memset((char *)ctx, 0, sizeof(*ctx));
142
143   /* Prime the SHS with "magic" init constants */
144   ctx->h[0] = 0x67452301;
145   ctx->h[1] = 0xEFCDAB89;
146   ctx->h[2] = 0x98BADCFE;
147   ctx->h[3] = 0x10325476;
148   ctx->h[4] = 0xC3D2E1F0;
149
150 #if !defined(i386) && !defined(_IBMR2)
151   /* Determine the ENDIAN-ness of the CPU */
152   z_t.ll = 0;
153
154   z_t.ch[0] = 0x01;
155
156   if (z_t.ll == 0x01000000)
157     msb_flag = 1;
158   else {
159     if (z_t.ll == 0x00000001)
160       msb_flag = 0;
161     else
162       printf("ENDIAN-ness is SCREWED! (%0#lx)\n", z_t.ll);
163   }
164 #endif /* ~_IBMR2 & ~i386 */
165 }
166
167
168 void SHAUpdate(SHA_CTX *ctx, const unsigned char *buf, unsigned int lenBuf)
169 {
170   /* Do we have any bytes? */
171   if (lenBuf == 0) return;
172
173   /* Calculate buf len in bits and update the len count */
174   ctx->count[0] += (lenBuf << 3);
175   if (ctx->count[0] < (lenBuf << 3))
176     ctx->count[1] += 1;
177   ctx->count[1] += (lenBuf >> 29);
178
179   /* Fill the hash working buffer for the first run, if  */
180   /* we have enough data...                              */
181   int i = 64 - ctx->index;  /* either fill it up to 64 bytes */
182   if ((int)lenBuf < i) i = lenBuf; /* or put the whole data...*/
183
184   lenBuf -= i;  /* Reflect the data we'll put in the buf */
185
186   /* Physically put the data in the hash workbuf */
187   memcpy((char *)&(ctx->X[ctx->index]), buf, i);
188   buf += i; ctx->index += i;
189
190   /* Adjust the buf index */
191   if (ctx->index == 64)
192     ctx->index = 0;
193
194   /* Let's see whether we're equal to 64 bytes in buf  */
195   if (ctx->index == 0)
196     SHATransform(ctx, ctx->X);
197
198   /* Process full 64-byte blocks */
199   while(lenBuf >= 64) {
200     lenBuf -= 64;
201     SHATransform(ctx, buf);
202     buf += 64;
203   }
204
205   /* Put the rest of data in the hash buf for next run */
206   if (lenBuf > 0) {
207     memcpy(ctx->X, buf, lenBuf);
208     ctx->index = lenBuf;
209   }
210 }
211
212
213 void SHAFinal(unsigned char *digest, SHA_CTX *ctx)
214 {
215   int i;
216   unsigned long int c0, c1;
217   unsigned char truelen[8];
218   static unsigned char padding[64] = {
219     0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /*  8 */
220     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 16 */
221     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 24 */
222     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 32 */
223     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 40 */
224     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 48 */
225     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 56 */
226     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /* 64 */
227                                         
228   /* Store the message length to append after */
229   /* padding is done... */
230
231 #ifdef _IBMR2
232     memcpy(truelen, (char *) &(ctx->count[1]), 4);
233     memcpy(&truelen[4], (char *) &(ctx->count[0]), 4);
234 #else
235 #ifndef i386
236   if (msb_flag) {
237     memcpy(truelen, (char *) &(ctx->count[1]), 4);
238     memcpy(&truelen[4], (char *) &(ctx->count[0]), 4);
239   } else
240 #endif /* ~i386 */
241   {
242     c0 = ctx->count[0]; c1 = ctx->count[1];
243     for (i = 7; i >=0; i--) {
244       truelen[i] = (unsigned char) (c0 & 0xff);
245       c0 = (c0 >> 8) | (((c1 >> 8) & 0xff) << 24);
246       c1 = (c1 >> 8);
247     }
248   }
249 #endif /* _IBMR2 */
250
251   /* How many padding bytes do we need? */
252   i = (ctx->count[0] >> 3) & 0x3f;  /* # of bytes mod 64 */
253   if (i >= 56) i = 120 - i; /* # of padding bytes needed */
254   else i = 56 - i;
255
256
257   SHAUpdate(ctx, padding, i);   /* Append the padding */
258   SHAUpdate(ctx, truelen, 8);   /* Append the length  */
259
260 #ifdef _IBMR2
261     memcpy(digest, (char *)&ctx->h[0], 20);
262 #else
263 #ifndef i386
264   if (msb_flag)
265     memcpy(digest, (char *)&ctx->h[0], 20);
266   else
267 #endif /* ~i386 */
268     for (i = 0; i < 4; i++) {
269       digest[3-i]  = (unsigned char) (ctx->h[0] & 0xff);
270       ctx->h[0] >>= 8;
271       digest[7-i]  = (unsigned char) (ctx->h[1] & 0xff);
272       ctx->h[1] >>= 8;
273       digest[11-i] = (unsigned char) (ctx->h[2] & 0xff);
274       ctx->h[2] >>= 8;
275       digest[15-i] = (unsigned char) (ctx->h[3] & 0xff);
276       ctx->h[3] >>= 8;
277       digest[19-i] = (unsigned char) (ctx->h[4] & 0xff);
278       ctx->h[4] >>= 8;
279     }
280 #endif /* _IBMR2 */
281 }
282
283 #ifdef SNMP_PP_NAMESPACE
284 }; // end of namespace Snmp_pp
285 #endif 
286
287 #endif // !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)