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