1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_bridges.hxx"
26
27
28 #ifndef TEST
29 #ifndef _SAL_TYPES_H_
30 #include <sal/types.h>
31 #endif
32 #else
33 typedef unsigned int sal_uInt32;
34 #endif
35
36 #include <string.h>
37
38 /*
39 * build a hash for a character buffer using the NIST algorithm
40 */
41
42 class NIST_Hash
43 {
44
45 // helper functions
f1(sal_uInt32 x,sal_uInt32 y,sal_uInt32 z)46 sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
47 {
48 return z ^ ( x & ( y ^ z ) );
49 }
50
f2(sal_uInt32 x,sal_uInt32 y,sal_uInt32 z)51 sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
52 {
53 return x ^ y ^ z;
54 }
55
f3(sal_uInt32 x,sal_uInt32 y,sal_uInt32 z)56 sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
57 {
58 return ( x & y ) + ( z & ( x ^ y ) );
59 }
60
rotl(sal_uInt32 nValue,sal_uInt32 nBits)61 sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
62 {
63 return ( nValue << nBits ) | ( nValue >> (32-nBits) );
64 }
65
expand_nostore(sal_uInt32 index)66 sal_uInt32 expand_nostore( sal_uInt32 index )
67 {
68 return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
69 }
70
expand_store(sal_uInt32 index)71 sal_uInt32 expand_store( sal_uInt32 index )
72 {
73 return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
74 }
75
subRound(sal_uInt32 a,sal_uInt32 & b,sal_uInt32 c,sal_uInt32 d,sal_uInt32 & e,sal_uInt32 constant,sal_uInt32 datum,sal_uInt32 nFunction)76 void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
77 {
78 e += rotl(a,5);
79 switch( nFunction )
80 {
81 case 1: e += f1( b, c, d );break;
82 case 2:
83 case 4: e += f2( b, c, d );break;
84 case 3: e += f3( b, c, d );break;
85 }
86 e += constant + datum;
87 b = rotl( b, 30 );
88 }
89
90 void transform();
91 void final();
92
93 // data members
94 sal_uInt32 data[16];
95 sal_uInt32 hashdata[5];
96 public:
97 NIST_Hash( const char* pString, sal_uInt32 nLen );
98
getHash()99 sal_uInt32 *getHash() { return hashdata; }
100 };
101
transform()102 void NIST_Hash::transform()
103 {
104 // constants
105 const sal_uInt32 K2 = 0x5A827999;
106 const sal_uInt32 K3 = 0x6ED9EBA1;
107 const sal_uInt32 K5 = 0x8F1BBCDC;
108 const sal_uInt32 K10 = 0xCA62C1D6;
109
110 sal_uInt32 a, b, c, d, e;
111 a = hashdata[0];
112 b = hashdata[1];
113 c = hashdata[2];
114 d = hashdata[3];
115 e = hashdata[4];
116
117 subRound( a, b, c, d, e, K2, data[ 0], 1 );
118 subRound( e, a, b, c, d, K2, data[ 1], 1 );
119 subRound( d, e, a, b, c, K2, data[ 2], 1 );
120 subRound( c, d, e, a, b, K2, data[ 3], 1 );
121 subRound( b, c, d, e, a, K2, data[ 4], 1 );
122 subRound( a, b, c, d, e, K2, data[ 5], 1 );
123 subRound( e, a, b, c, d, K2, data[ 6], 1 );
124 subRound( d, e, a, b, c, K2, data[ 7], 1 );
125 subRound( c, d, e, a, b, K2, data[ 8], 1 );
126 subRound( b, c, d, e, a, K2, data[ 9], 1 );
127 subRound( a, b, c, d, e, K2, data[10], 1 );
128 subRound( e, a, b, c, d, K2, data[11], 1 );
129 subRound( d, e, a, b, c, K2, data[12], 1 );
130 subRound( c, d, e, a, b, K2, data[13], 1 );
131 subRound( b, c, d, e, a, K2, data[14], 1 );
132 subRound( a, b, c, d, e, K2, data[15], 1 );
133 subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
134 subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
135 subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
136 subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
137
138 subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
139 subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
140 subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
141 subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
142 subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
143 subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
144 subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
145 subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
146 subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
147 subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
148 subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
149 subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
150 subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
151 subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
152 subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
153 subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
154 subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
155 subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
156 subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
157 subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
158
159 subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
160 subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
161 subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
162 subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
163 subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
164 subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
165 subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
166 subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
167 subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
168 subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
169 subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
170 subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
171 subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
172 subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
173 subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
174 subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
175 subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
176 subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
177 subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
178 subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
179
180 subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
181 subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
182 subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
183 subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
184 subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
185 subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
186 subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
187 subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
188 subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
189 subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
190 subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
191 subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
192 subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
193 subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
194 subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
195 subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
196 subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
197 subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
198 subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
199 subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
200
201 hashdata[0] += a;
202 hashdata[1] += b;
203 hashdata[2] += c;
204 hashdata[3] += d;
205 hashdata[4] += e;
206 }
207
208 #define BLOCKSIZE sizeof( data )
209
NIST_Hash(const char * pString,sal_uInt32 nLen)210 NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
211 {
212 hashdata[0] = 0x67452301;
213 hashdata[1] = 0xefcdab89;
214 hashdata[2] = 0x98badcfe;
215 hashdata[3] = 0x10325476;
216 hashdata[4] = 0xc3d2e1f0;
217
218 sal_uInt32 nBytes = nLen;
219
220 while( nLen >= sizeof( data ) )
221 {
222 memcpy( data, pString, sizeof( data ) );
223 pString += sizeof( data );
224 nLen -= sizeof( data );
225 transform();
226 }
227 memcpy( data, pString, nLen );
228 ((char*)data)[nLen++] = 0x80;
229 if( nLen > sizeof( data ) - 8 )
230 {
231 memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
232 transform();
233 memset( data, 0, sizeof( data ) - 8 );
234 }
235 else
236 memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
237 data[14] = 0;
238 data[15] = nBytes << 3;
239 transform();
240 }
241
242 #ifdef TEST
243 #include <stdio.h>
main(int argc,const char ** argv)244 int main( int argc, const char** argv )
245 {
246 const char* pHash = argc < 2 ? argv[0] : argv[1];
247
248 NIST_Hash aHash( pHash, strlen( pHash ) );
249 sal_uInt32* pBits = aHash.getHash();
250
251 printf( "text : %s\n"
252 "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
253 pHash,
254 pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
255 );
256 return 0;
257 }
258
259 #endif
260