1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_bridges.hxx"
31 
32 
33 #ifndef TEST
34 #ifndef _SAL_TYPES_H_
35 #include <sal/types.h>
36 #endif
37 #else
38 typedef unsigned int sal_uInt32;
39 #endif
40 
41 #include <string.h>
42 
43 /*
44  *	build a hash for a character buffer using the NIST algorithm
45  */
46 
47 class NIST_Hash
48 {
49 
50 	// helper functions
51 	sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
52 	{
53 		return z ^ ( x & ( y ^ z ) );
54 	}
55 
56 	sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
57 	{
58 		return x ^ y ^ z;
59 	}
60 
61 	sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
62 	{
63 		return ( x & y ) + ( z & ( x ^ y ) );
64 	}
65 
66 	sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
67 	{
68 		return ( nValue << nBits ) | ( nValue >> (32-nBits) );
69 	}
70 
71 	sal_uInt32 expand_nostore( sal_uInt32 index )
72 	{
73 		return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
74 	}
75 
76 	sal_uInt32 expand_store( sal_uInt32 index )
77 	{
78 		return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
79 	}
80 
81 	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 )
82 	{
83 		e += rotl(a,5);
84 		switch( nFunction )
85 		{
86 			case 1: e += f1( b, c, d );break;
87 			case 2:
88 			case 4: e += f2( b, c, d );break;
89 			case 3: e += f3( b, c, d );break;
90 		}
91 		e += constant + datum;
92 		b = rotl( b, 30 );
93 	}
94 
95 	void transform();
96 	void final();
97 
98 	// data members
99 	sal_uInt32 data[16];
100 	sal_uInt32 hashdata[5];
101 public:
102 	NIST_Hash( const char* pString, sal_uInt32 nLen );
103 
104 	sal_uInt32 *getHash() { return hashdata; }
105 };
106 
107 void NIST_Hash::transform()
108 {
109 	// constants
110 	const sal_uInt32 K2		= 0x5A827999;
111 	const sal_uInt32 K3		= 0x6ED9EBA1;
112 	const sal_uInt32 K5		= 0x8F1BBCDC;
113 	const sal_uInt32 K10	= 0xCA62C1D6;
114 
115 	sal_uInt32 a, b, c, d, e;
116 	a = hashdata[0];
117 	b = hashdata[1];
118 	c = hashdata[2];
119 	d = hashdata[3];
120 	e = hashdata[4];
121 
122 	subRound( a, b, c, d, e, K2, data[ 0], 1 );
123 	subRound( e, a, b, c, d, K2, data[ 1], 1 );
124 	subRound( d, e, a, b, c, K2, data[ 2], 1 );
125 	subRound( c, d, e, a, b, K2, data[ 3], 1 );
126 	subRound( b, c, d, e, a, K2, data[ 4], 1 );
127 	subRound( a, b, c, d, e, K2, data[ 5], 1 );
128 	subRound( e, a, b, c, d, K2, data[ 6], 1 );
129 	subRound( d, e, a, b, c, K2, data[ 7], 1 );
130 	subRound( c, d, e, a, b, K2, data[ 8], 1 );
131 	subRound( b, c, d, e, a, K2, data[ 9], 1 );
132 	subRound( a, b, c, d, e, K2, data[10], 1 );
133 	subRound( e, a, b, c, d, K2, data[11], 1 );
134 	subRound( d, e, a, b, c, K2, data[12], 1 );
135 	subRound( c, d, e, a, b, K2, data[13], 1 );
136 	subRound( b, c, d, e, a, K2, data[14], 1 );
137 	subRound( a, b, c, d, e, K2, data[15], 1 );
138 	subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
139 	subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
140 	subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
141 	subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
142 
143 	subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
144 	subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
145 	subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
146 	subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
147 	subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
148 	subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
149 	subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
150 	subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
151 	subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
152 	subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
153 	subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
154 	subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
155 	subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
156 	subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
157 	subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
158 	subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
159 	subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
160 	subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
161 	subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
162 	subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
163 
164 	subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
165 	subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
166 	subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
167 	subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
168 	subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
169 	subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
170 	subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
171 	subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
172 	subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
173 	subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
174 	subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
175 	subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
176 	subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
177 	subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
178 	subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
179 	subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
180 	subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
181 	subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
182 	subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
183 	subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
184 
185 	subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
186 	subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
187 	subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
188 	subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
189 	subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
190 	subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
191 	subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
192 	subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
193 	subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
194 	subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
195 	subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
196 	subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
197 	subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
198 	subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
199 	subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
200 	subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
201 	subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
202 	subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
203 	subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
204 	subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
205 
206 	hashdata[0] += a;
207 	hashdata[1] += b;
208 	hashdata[2] += c;
209 	hashdata[3] += d;
210 	hashdata[4] += e;
211 }
212 
213 #define BLOCKSIZE sizeof( data )
214 
215 NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
216 {
217 	hashdata[0] = 0x67452301;
218 	hashdata[1] = 0xefcdab89;
219 	hashdata[2] = 0x98badcfe;
220 	hashdata[3] = 0x10325476;
221 	hashdata[4] = 0xc3d2e1f0;
222 
223 	sal_uInt32 nBytes = nLen;
224 
225 	while( nLen >= sizeof( data ) )
226 	{
227 		memcpy( data, pString, sizeof( data ) );
228 		pString += sizeof( data );
229 		nLen -= sizeof( data );
230 		transform();
231 	}
232 	memcpy( data, pString, nLen );
233 	((char*)data)[nLen++] = 0x80;
234 	if( nLen > sizeof( data ) - 8 )
235 	{
236 		memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
237 		transform();
238 		memset( data, 0, sizeof( data ) - 8 );
239 	}
240 	else
241 		memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
242 	data[14] = 0;
243 	data[15] = nBytes << 3;
244 	transform();
245 }
246 
247 #ifdef TEST
248 #include <stdio.h>
249 int main( int argc, const char** argv )
250 {
251 	const char* pHash = argc < 2 ? argv[0] : argv[1];
252 
253 	NIST_Hash aHash( pHash, strlen( pHash ) );
254 	sal_uInt32* pBits = aHash.getHash();
255 
256 	printf( "text : %s\n"
257 			"bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
258 			pHash,
259 			pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
260 			);
261 	return 0;
262 }
263 
264 #endif
265