File indexing completed on 2024-05-12 16:35:44
0001 /************************************************************************* 0002 * This implementation has been taken from the OpenOffice 1.0 and modified 0003 * to use Calligra Sheets data types. 0004 * 0005 * The Initial Developer of the Original Code is: Sun Microsystems, Inc. 0006 * 0007 * Sun has made the contents of this file available subject to the 0008 * terms of GNU Lesser General Public License Version 2.1 as 0009 * specified in sal/rtl/source/digest.c in the OpenOffice package. 0010 * 0011 * 0012 * Sun Microsystems Inc., October, 2000 0013 * 0014 * GNU Lesser General Public License Version 2.1 0015 * ============================================= 0016 * Copyright 2000 by Sun Microsystems, Inc. 0017 * 901 San Antonio Road, Palo Alto, CA 94303, USA 0018 * 0019 * This library is free software; you can redistribute it and/or 0020 * modify it under the terms of the GNU Lesser General Public 0021 * License version 2.1, as published by the Free Software Foundation. 0022 * 0023 * This library is distributed in the hope that it will be useful, 0024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0026 * Lesser General Public License for more details. 0027 * 0028 * You should have received a copy of the GNU Lesser General Public 0029 * License along with this library; if not, write to the Free Software 0030 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 0031 Boston, MA 02110-1301, USA 0032 * 0033 * All Rights Reserved. 0034 * 0035 * Contributor(s): Matthias Huetsch <matthias.huetsch@sun.com> 0036 * 0037 * 0038 ************************************************************************/ 0039 0040 #include "Digest.h" 0041 0042 #include <stdlib.h> 0043 #include <string.h> 0044 0045 #include <KoConfig.h> // WORDS_BIGENDIAN 0046 0047 #include "SheetsDebug.h" 0048 0049 typedef quint8 sal_uInt8; 0050 typedef quint16 sal_uInt16; 0051 typedef quint32 sal_uInt32; 0052 0053 void rtl_freeZeroMemory(void * p, sal_uInt32 n); 0054 void rtl_freeMemory(void * p); 0055 void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes); 0056 void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes); 0057 0058 #ifndef OSL_LOBYTE 0059 # define OSL_LOBYTE(w) ((sal_uInt8)((sal_uInt16)(w) & 0xFF)) 0060 #endif 0061 #ifndef OSL_HIBYTE 0062 # define OSL_HIBYTE(w) ((sal_uInt8)(((sal_uInt16)(w) >> 8) & 0xFF)) 0063 #endif 0064 #ifndef OSL_MAKEWORD 0065 # define OSL_MAKEWORD(bl, bh) ((sal_uInt16)((bl) & 0xFF) | (((sal_uInt16)(bh) & 0xFF) << 8)) 0066 #endif 0067 #ifndef OSL_MAKEDWORD 0068 # define OSL_MAKEDWORD(wl, wh) ((sal_uInt32)((wl) & 0xFFFF) | (((sal_uInt32)(wh) & 0xFFFF) << 16)) 0069 #endif 0070 #ifndef OSL_LOWORD 0071 # define OSL_LOWORD(d) ((sal_uInt16)((sal_uInt32)(d) & 0xFFFF)) 0072 #endif 0073 #ifndef OSL_HIWORD 0074 # define OSL_HIWORD(d) ((sal_uInt16)(((sal_uInt32)(d) >> 16) & 0xFFFF)) 0075 #endif 0076 0077 /** Define macros for swapping between byte orders. 0078 */ 0079 #ifndef OSL_SWAPWORD 0080 # define OSL_SWAPWORD(w) OSL_MAKEWORD(OSL_HIBYTE(w),OSL_LOBYTE(w)) 0081 #endif 0082 #ifndef OSL_SWAPDWORD 0083 # define OSL_SWAPDWORD(d) OSL_MAKEDWORD(OSL_SWAPWORD(OSL_HIWORD(d)),OSL_SWAPWORD(OSL_LOWORD(d))) 0084 #endif 0085 0086 0087 /*======================================================================== 0088 * 0089 * rtlDigest. 0090 * 0091 *======================================================================*/ 0092 /** Digest Handle opaque type. 0093 */ 0094 typedef void* rtlDigest; 0095 0096 /** Digest Algorithm enumeration. 0097 @see rtl_digest_create() 0098 */ 0099 enum __rtl_DigestAlgorithm { 0100 rtl_Digest_AlgorithmMD2, 0101 rtl_Digest_AlgorithmMD5, 0102 rtl_Digest_AlgorithmSHA, 0103 rtl_Digest_AlgorithmSHA1, 0104 0105 rtl_Digest_AlgorithmHMAC_MD5, 0106 rtl_Digest_AlgorithmHMAC_SHA1, 0107 0108 rtl_Digest_AlgorithmInvalid, 0109 rtl_Digest_Algorithm_FORCE_EQUAL_SIZE 0110 }; 0111 0112 /** Digest Algorithm type. 0113 */ 0114 typedef enum __rtl_DigestAlgorithm rtlDigestAlgorithm; 0115 0116 0117 /** Error Code enumeration. 0118 */ 0119 enum __rtl_DigestError { 0120 rtl_Digest_E_None, 0121 rtl_Digest_E_Argument, 0122 rtl_Digest_E_Algorithm, 0123 rtl_Digest_E_BufferSize, 0124 rtl_Digest_E_Memory, 0125 rtl_Digest_E_Unknown, 0126 rtl_Digest_E_FORCE_EQUAL_SIZE 0127 }; 0128 0129 /** Error Code type. 0130 */ 0131 typedef enum __rtl_DigestError rtlDigestError; 0132 0133 typedef rtlDigestError Digest_init_t(void * ctx, const sal_uInt8 * Data, sal_uInt32 DatLen); 0134 0135 typedef void Digest_delete_t(void *ctx); 0136 0137 typedef rtlDigestError Digest_update_t(void * ctx, const void * Data, sal_uInt32 DatLen); 0138 0139 typedef rtlDigestError Digest_get_t(void * ctx, sal_uInt8 * Buffer, sal_uInt32 BufLen); 0140 0141 /*======================================================================== 0142 * 0143 * rtl_digest_SHA1 interface. 0144 * 0145 *======================================================================*/ 0146 #define RTL_DIGEST_LENGTH_SHA1 20 0147 0148 /** Create a SHA1 Digest.handle. 0149 @details The SHA1 digest algorithm is specified in 0150 FIPS PUB 180-1 (Supersedes FIPS PUB 180) 0151 Secure Hash Standard 0152 0153 @see rtl_digest_create() 0154 */ 0155 rtlDigest rtl_digest_createSHA1(void); 0156 0157 0158 /** Destroy a SHA1 Digest.handle. 0159 @see rtl_digest_destroy() 0160 */ 0161 void rtl_digest_destroySHA1(rtlDigest Digest); 0162 0163 0164 /** Update a SHA1 digest with given data. 0165 @see rtl_digest_update() 0166 */ 0167 rtlDigestError rtl_digest_updateSHA1(rtlDigest Digest, const void * pData, uint nDatLen); 0168 0169 0170 /** Finalize a SHA1 digest and retrieve the digest value. 0171 @see rtl_digest_get() 0172 */ 0173 rtlDigestError rtl_digest_getSHA1(rtlDigest Digest, sal_uInt8 * pBuffer, uint nBufLen); 0174 0175 0176 /** Evaluate a SHA1 digest value from given data. 0177 @details This function performs an optimized call sequence on a 0178 single data buffer, avoiding digest creation and destruction. 0179 0180 @see rtl_digest_updateSHA1() 0181 @see rtl_digest_getSHA1() 0182 0183 @param pData [in] data buffer. 0184 @param nDatLen [in] data length. 0185 @param pBuffer [in] digest value buffer. 0186 @param nBufLen [in] digest value length. 0187 0188 @return rtl_Digest_E_None upon success. 0189 */ 0190 rtlDigestError rtl_digest_SHA1(const void * pData, uint nDatLen, 0191 unsigned char * pBuffer, uint nBufLen); 0192 0193 0194 /*======================================================================== 0195 * 0196 * rtlDigest internals. 0197 * 0198 *======================================================================*/ 0199 0200 void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes) 0201 { 0202 memset(Ptr, 0, Bytes); 0203 } 0204 0205 void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes) 0206 { 0207 memcpy(Dst, Src, Bytes); 0208 } 0209 0210 void rtl_freeMemory(void * p) 0211 { 0212 free(p); 0213 } 0214 0215 void rtl_freeZeroMemory(void * p, sal_uInt32 n) 0216 { 0217 if (p) { 0218 memset(p, 0, n); 0219 free(p); 0220 } 0221 } 0222 0223 #define RTL_DIGEST_CREATE(T) ((T*)(malloc(sizeof(T)))) 0224 0225 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n)))) 0226 0227 #define RTL_DIGEST_HTONL(l,c) \ 0228 (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \ 0229 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \ 0230 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \ 0231 *((c)++) = (sal_uInt8)(((l) ) & 0xff)) 0232 0233 #define RTL_DIGEST_LTOC(l,c) \ 0234 (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \ 0235 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \ 0236 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \ 0237 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff)) 0238 0239 typedef struct digest_impl_st { 0240 rtlDigestAlgorithm m_algorithm; 0241 sal_uInt32 m_length; 0242 Digest_init_t *m_init; 0243 Digest_delete_t *m_delete; 0244 Digest_update_t *m_update; 0245 Digest_get_t *m_get; 0246 } Digest_Impl; 0247 0248 /* 0249 * __rtl_digest_swapLong. 0250 */ 0251 static void __rtl_digest_swapLong(sal_uInt32 *pData, sal_uInt32 nDatLen) 0252 { 0253 register sal_uInt32 *X; 0254 register int i, n; 0255 0256 X = pData; 0257 n = nDatLen; 0258 0259 for (i = 0; i < n; ++i) 0260 X[i] = OSL_SWAPDWORD(X[i]); 0261 } 0262 0263 /*======================================================================== 0264 * 0265 * rtlDigest implementation. 0266 * 0267 *======================================================================*/ 0268 /* 0269 * rtl_digest_create. 0270 0271 rtlDigest rtl_digest_create (rtlDigestAlgorithm Algorithm) 0272 { 0273 rtlDigest Digest = (rtlDigest)0; 0274 switch (Algorithm) 0275 { 0276 case rtl_Digest_AlgorithmMD2: 0277 Digest = rtl_digest_createMD2(); 0278 break; 0279 0280 case rtl_Digest_AlgorithmMD5: 0281 Digest = rtl_digest_createMD5(); 0282 break; 0283 0284 case rtl_Digest_AlgorithmSHA: 0285 Digest = rtl_digest_createSHA(); 0286 break; 0287 0288 case rtl_Digest_AlgorithmSHA1: 0289 Digest = rtl_digest_createSHA1(); 0290 break; 0291 0292 case rtl_Digest_AlgorithmHMAC_MD5: 0293 Digest = rtl_digest_createHMAC_MD5(); 0294 break; 0295 0296 case rtl_Digest_AlgorithmHMAC_SHA1: 0297 Digest = rtl_digest_createHMAC_SHA1(); 0298 break; 0299 0300 default: // rtl_Digest_AlgorithmInvalid 0301 break; 0302 } 0303 return Digest; 0304 } 0305 0306 0307 // rtl_digest_queryAlgorithm. 0308 0309 rtlDigestAlgorithm rtl_digest_queryAlgorithm (rtlDigest Digest) 0310 { 0311 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0312 if (pImpl) 0313 return pImpl->m_algorithm; 0314 else 0315 return rtl_Digest_AlgorithmInvalid; 0316 } 0317 0318 // rtl_digest_queryLength. 0319 sal_uInt32 rtl_digest_queryLength (rtlDigest Digest) 0320 { 0321 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0322 if (pImpl) 0323 return pImpl->m_length; 0324 else 0325 return 0; 0326 } 0327 0328 // * rtl_digest_init. 0329 rtlDigestError rtl_digest_init ( 0330 rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen) 0331 { 0332 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0333 if (pImpl) 0334 { 0335 if (pImpl->m_init) 0336 return pImpl->m_init (Digest, pData, nDatLen); 0337 else 0338 return rtl_Digest_E_None; 0339 } 0340 return rtl_Digest_E_Argument; 0341 } 0342 0343 // * rtl_digest_update. 0344 rtlDigestError rtl_digest_update ( 0345 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) 0346 { 0347 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0348 if (pImpl && pImpl->m_update) 0349 return pImpl->m_update (Digest, pData, nDatLen); 0350 else 0351 return rtl_Digest_E_Argument; 0352 } 0353 0354 // * rtl_digest_get. 0355 rtlDigestError rtl_digest_get ( 0356 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) 0357 { 0358 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0359 if (pImpl && pImpl->m_get) 0360 return pImpl->m_get (Digest, pBuffer, nBufLen); 0361 else 0362 return rtl_Digest_E_Argument; 0363 } 0364 0365 // * rtl_digest_destroy. 0366 void rtl_digest_destroy (rtlDigest Digest) 0367 { 0368 Digest_Impl *pImpl = (Digest_Impl *)Digest; 0369 if (pImpl && pImpl->m_delete) 0370 pImpl->m_delete (Digest); 0371 } 0372 */ 0373 0374 /*======================================================================== 0375 * 0376 * rtl_digest_(SHA|SHA1) common internals. 0377 * 0378 *======================================================================*/ 0379 #define DIGEST_CBLOCK_SHA 64 0380 #define DIGEST_LBLOCK_SHA 16 0381 0382 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x); 0383 0384 static sal_uInt32 __rtl_digest_updateSHA_1(sal_uInt32 x); 0385 0386 typedef struct digestSHA_context_st { 0387 DigestSHA_update_t *m_update; 0388 sal_uInt32 m_nDatLen; 0389 sal_uInt32 m_pData[DIGEST_LBLOCK_SHA]; 0390 sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE; 0391 sal_uInt32 m_nL, m_nH; 0392 } DigestContextSHA; 0393 0394 typedef struct digestSHA_impl_st { 0395 Digest_Impl m_digest; 0396 DigestContextSHA m_context; 0397 } DigestSHA_Impl; 0398 0399 static void __rtl_digest_initSHA( 0400 DigestContextSHA *ctx, DigestSHA_update_t *fct); 0401 0402 static void __rtl_digest_updateSHA(DigestContextSHA *ctx); 0403 static void __rtl_digest_endSHA(DigestContextSHA *ctx); 0404 0405 #define K_00_19 (sal_uInt32)0x5a827999L 0406 #define K_20_39 (sal_uInt32)0x6ed9eba1L 0407 #define K_40_59 (sal_uInt32)0x8f1bbcdcL 0408 #define K_60_79 (sal_uInt32)0xca62c1d6L 0409 0410 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) 0411 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) 0412 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) 0413 #define F_60_79(b,c,d) F_20_39(b,c,d) 0414 0415 #define BODY_X(i) \ 0416 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f]) 0417 0418 #define BODY_00_15(u,i,a,b,c,d,e,f) \ 0419 (f) = X[i]; \ 0420 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \ 0421 (b) = RTL_DIGEST_ROTL((b), 30); 0422 0423 #define BODY_16_19(u,i,a,b,c,d,e,f) \ 0424 (f) = BODY_X((i)); \ 0425 (f) = X[(i)&0x0f] = (u)((f)); \ 0426 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \ 0427 (b) = RTL_DIGEST_ROTL((b), 30); 0428 0429 #define BODY_20_39(u,i,a,b,c,d,e,f) \ 0430 (f) = BODY_X((i)); \ 0431 (f) = X[(i)&0x0f] = (u)((f)); \ 0432 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \ 0433 (b) = RTL_DIGEST_ROTL((b), 30); 0434 0435 #define BODY_40_59(u,i,a,b,c,d,e,f) \ 0436 (f) = BODY_X((i)); \ 0437 (f) = X[(i)&0x0f] = (u)((f)); \ 0438 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \ 0439 (b) = RTL_DIGEST_ROTL((b), 30); 0440 0441 #define BODY_60_79(u,i,a,b,c,d,e,f) \ 0442 (f) = BODY_X((i)); \ 0443 (f) = X[(i)&0x0f] = (u)((f)); \ 0444 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \ 0445 (b) = RTL_DIGEST_ROTL((b), 30); 0446 0447 /* 0448 * __rtl_digest_initSHA. 0449 */ 0450 static void __rtl_digest_initSHA( 0451 DigestContextSHA *ctx, DigestSHA_update_t *fct) 0452 { 0453 rtl_zeroMemory(ctx, sizeof(DigestContextSHA)); 0454 ctx->m_update = fct; 0455 0456 ctx->m_nA = (sal_uInt32)0x67452301L; 0457 ctx->m_nB = (sal_uInt32)0xefcdab89L; 0458 ctx->m_nC = (sal_uInt32)0x98badcfeL; 0459 ctx->m_nD = (sal_uInt32)0x10325476L; 0460 ctx->m_nE = (sal_uInt32)0xc3d2e1f0L; 0461 } 0462 0463 /* 0464 * __rtl_digest_updateSHA. 0465 */ 0466 static void __rtl_digest_updateSHA(DigestContextSHA *ctx) 0467 { 0468 register sal_uInt32 A, B, C, D, E, T; 0469 register sal_uInt32 *X; 0470 0471 register DigestSHA_update_t *U; 0472 U = ctx->m_update; 0473 0474 A = ctx->m_nA; 0475 B = ctx->m_nB; 0476 C = ctx->m_nC; 0477 D = ctx->m_nD; 0478 E = ctx->m_nE; 0479 X = ctx->m_pData; 0480 0481 BODY_00_15(U, 0, A, B, C, D, E, T); 0482 BODY_00_15(U, 1, T, A, B, C, D, E); 0483 BODY_00_15(U, 2, E, T, A, B, C, D); 0484 BODY_00_15(U, 3, D, E, T, A, B, C); 0485 BODY_00_15(U, 4, C, D, E, T, A, B); 0486 BODY_00_15(U, 5, B, C, D, E, T, A); 0487 BODY_00_15(U, 6, A, B, C, D, E, T); 0488 BODY_00_15(U, 7, T, A, B, C, D, E); 0489 BODY_00_15(U, 8, E, T, A, B, C, D); 0490 BODY_00_15(U, 9, D, E, T, A, B, C); 0491 BODY_00_15(U, 10, C, D, E, T, A, B); 0492 BODY_00_15(U, 11, B, C, D, E, T, A); 0493 BODY_00_15(U, 12, A, B, C, D, E, T); 0494 BODY_00_15(U, 13, T, A, B, C, D, E); 0495 BODY_00_15(U, 14, E, T, A, B, C, D); 0496 BODY_00_15(U, 15, D, E, T, A, B, C); 0497 BODY_16_19(U, 16, C, D, E, T, A, B); 0498 BODY_16_19(U, 17, B, C, D, E, T, A); 0499 BODY_16_19(U, 18, A, B, C, D, E, T); 0500 BODY_16_19(U, 19, T, A, B, C, D, E); 0501 0502 BODY_20_39(U, 20, E, T, A, B, C, D); 0503 BODY_20_39(U, 21, D, E, T, A, B, C); 0504 BODY_20_39(U, 22, C, D, E, T, A, B); 0505 BODY_20_39(U, 23, B, C, D, E, T, A); 0506 BODY_20_39(U, 24, A, B, C, D, E, T); 0507 BODY_20_39(U, 25, T, A, B, C, D, E); 0508 BODY_20_39(U, 26, E, T, A, B, C, D); 0509 BODY_20_39(U, 27, D, E, T, A, B, C); 0510 BODY_20_39(U, 28, C, D, E, T, A, B); 0511 BODY_20_39(U, 29, B, C, D, E, T, A); 0512 BODY_20_39(U, 30, A, B, C, D, E, T); 0513 BODY_20_39(U, 31, T, A, B, C, D, E); 0514 BODY_20_39(U, 32, E, T, A, B, C, D); 0515 BODY_20_39(U, 33, D, E, T, A, B, C); 0516 BODY_20_39(U, 34, C, D, E, T, A, B); 0517 BODY_20_39(U, 35, B, C, D, E, T, A); 0518 BODY_20_39(U, 36, A, B, C, D, E, T); 0519 BODY_20_39(U, 37, T, A, B, C, D, E); 0520 BODY_20_39(U, 38, E, T, A, B, C, D); 0521 BODY_20_39(U, 39, D, E, T, A, B, C); 0522 0523 BODY_40_59(U, 40, C, D, E, T, A, B); 0524 BODY_40_59(U, 41, B, C, D, E, T, A); 0525 BODY_40_59(U, 42, A, B, C, D, E, T); 0526 BODY_40_59(U, 43, T, A, B, C, D, E); 0527 BODY_40_59(U, 44, E, T, A, B, C, D); 0528 BODY_40_59(U, 45, D, E, T, A, B, C); 0529 BODY_40_59(U, 46, C, D, E, T, A, B); 0530 BODY_40_59(U, 47, B, C, D, E, T, A); 0531 BODY_40_59(U, 48, A, B, C, D, E, T); 0532 BODY_40_59(U, 49, T, A, B, C, D, E); 0533 BODY_40_59(U, 50, E, T, A, B, C, D); 0534 BODY_40_59(U, 51, D, E, T, A, B, C); 0535 BODY_40_59(U, 52, C, D, E, T, A, B); 0536 BODY_40_59(U, 53, B, C, D, E, T, A); 0537 BODY_40_59(U, 54, A, B, C, D, E, T); 0538 BODY_40_59(U, 55, T, A, B, C, D, E); 0539 BODY_40_59(U, 56, E, T, A, B, C, D); 0540 BODY_40_59(U, 57, D, E, T, A, B, C); 0541 BODY_40_59(U, 58, C, D, E, T, A, B); 0542 BODY_40_59(U, 59, B, C, D, E, T, A); 0543 0544 BODY_60_79(U, 60, A, B, C, D, E, T); 0545 BODY_60_79(U, 61, T, A, B, C, D, E); 0546 BODY_60_79(U, 62, E, T, A, B, C, D); 0547 BODY_60_79(U, 63, D, E, T, A, B, C); 0548 BODY_60_79(U, 64, C, D, E, T, A, B); 0549 BODY_60_79(U, 65, B, C, D, E, T, A); 0550 BODY_60_79(U, 66, A, B, C, D, E, T); 0551 BODY_60_79(U, 67, T, A, B, C, D, E); 0552 BODY_60_79(U, 68, E, T, A, B, C, D); 0553 BODY_60_79(U, 69, D, E, T, A, B, C); 0554 BODY_60_79(U, 70, C, D, E, T, A, B); 0555 BODY_60_79(U, 71, B, C, D, E, T, A); 0556 BODY_60_79(U, 72, A, B, C, D, E, T); 0557 BODY_60_79(U, 73, T, A, B, C, D, E); 0558 BODY_60_79(U, 74, E, T, A, B, C, D); 0559 BODY_60_79(U, 75, D, E, T, A, B, C); 0560 BODY_60_79(U, 76, C, D, E, T, A, B); 0561 BODY_60_79(U, 77, B, C, D, E, T, A); 0562 BODY_60_79(U, 78, A, B, C, D, E, T); 0563 BODY_60_79(U, 79, T, A, B, C, D, E); 0564 0565 ctx->m_nA += E; 0566 ctx->m_nB += T; 0567 ctx->m_nC += A; 0568 ctx->m_nD += B; 0569 ctx->m_nE += C; 0570 } 0571 0572 /* 0573 * __rtl_digest_endSHA. 0574 */ 0575 static void __rtl_digest_endSHA(DigestContextSHA *ctx) 0576 { 0577 static const sal_uInt8 end[4] = { 0578 0x80, 0x00, 0x00, 0x00 0579 }; 0580 register const sal_uInt8 *p = end; 0581 0582 register sal_uInt32 *X; 0583 register int i; 0584 0585 X = ctx->m_pData; 0586 i = (ctx->m_nDatLen >> 2); 0587 0588 #ifdef WORDS_BIGENDIAN 0589 __rtl_digest_swapLong(X, i + 1); 0590 #endif 0591 0592 switch (ctx->m_nDatLen & 0x03) { 0593 case 1: X[i] &= 0x000000ff; break; 0594 case 2: X[i] &= 0x0000ffff; break; 0595 case 3: X[i] &= 0x00ffffff; break; 0596 } 0597 0598 switch (ctx->m_nDatLen & 0x03) { 0599 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L; 0600 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L; 0601 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L; 0602 case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L; 0603 } 0604 0605 __rtl_digest_swapLong(X, i + 1); 0606 0607 i += 1; 0608 0609 if (i >= (DIGEST_LBLOCK_SHA - 2)) { 0610 for (; i < DIGEST_LBLOCK_SHA; ++i) 0611 X[i] = 0; 0612 __rtl_digest_updateSHA(ctx); 0613 i = 0; 0614 } 0615 0616 for (; i < (DIGEST_LBLOCK_SHA - 2); ++i) 0617 X[i] = 0; 0618 0619 X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH; 0620 X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL; 0621 0622 __rtl_digest_updateSHA(ctx); 0623 } 0624 0625 /*======================================================================== 0626 * 0627 * rtl_digest_SHA1 internals. 0628 * 0629 *======================================================================*/ 0630 /* 0631 * __rtl_digest_SHA_1. 0632 */ 0633 static const Digest_Impl __rtl_digest_SHA_1 = { rtl_Digest_AlgorithmSHA1, 0634 RTL_DIGEST_LENGTH_SHA1, 0635 0, 0636 rtl_digest_destroySHA1, 0637 rtl_digest_updateSHA1, 0638 rtl_digest_getSHA1 0639 }; 0640 0641 /* 0642 * __rtl_digest_updateSHA_1. 0643 */ 0644 static sal_uInt32 __rtl_digest_updateSHA_1(sal_uInt32 x) 0645 { 0646 return RTL_DIGEST_ROTL(x, 1); 0647 } 0648 0649 /*======================================================================== 0650 * 0651 * rtl_digest_SHA1 implementation. 0652 * 0653 *======================================================================*/ 0654 /* 0655 * rtl_digest_SHA1. 0656 */ 0657 rtlDigestError rtl_digest_SHA1( 0658 const void *pData, sal_uInt32 nDatLen, 0659 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) 0660 { 0661 DigestSHA_Impl digest; 0662 rtlDigestError result; 0663 0664 digest.m_digest = __rtl_digest_SHA_1; 0665 __rtl_digest_initSHA(&(digest.m_context), __rtl_digest_updateSHA_1); 0666 0667 result = rtl_digest_updateSHA1(&digest, pData, nDatLen); 0668 if (result == rtl_Digest_E_None) 0669 result = rtl_digest_getSHA1(&digest, pBuffer, nBufLen); 0670 0671 rtl_zeroMemory(&digest, sizeof(digest)); 0672 return (result); 0673 } 0674 0675 /* 0676 * rtl_digest_createSHA1. 0677 */ 0678 rtlDigest rtl_digest_createSHA1(void) 0679 { 0680 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)0; 0681 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl); 0682 if (pImpl) { 0683 pImpl->m_digest = __rtl_digest_SHA_1; 0684 __rtl_digest_initSHA(&(pImpl->m_context), __rtl_digest_updateSHA_1); 0685 } 0686 return ((rtlDigest)pImpl); 0687 } 0688 0689 /* 0690 * rtl_digest_updateSHA1. 0691 */ 0692 rtlDigestError rtl_digest_updateSHA1( 0693 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) 0694 { 0695 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; 0696 const sal_uInt8 *d = (const sal_uInt8 *)pData; 0697 0698 DigestContextSHA *ctx; 0699 sal_uInt32 len; 0700 0701 if ((pImpl == 0) || (pData == 0)) 0702 return rtl_Digest_E_Argument; 0703 0704 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)) 0705 return rtl_Digest_E_Algorithm; 0706 0707 if (nDatLen == 0) 0708 return rtl_Digest_E_None; 0709 0710 ctx = &(pImpl->m_context); 0711 0712 len = ctx->m_nL + (nDatLen << 3); 0713 if (len < ctx->m_nL) ctx->m_nH += 1; 0714 ctx->m_nH += (nDatLen >> 29); 0715 ctx->m_nL = len; 0716 0717 if (ctx->m_nDatLen) { 0718 sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen; 0719 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen; 0720 0721 if (nDatLen < n) { 0722 rtl_copyMemory(p, d, nDatLen); 0723 ctx->m_nDatLen += nDatLen; 0724 0725 return rtl_Digest_E_None; 0726 } 0727 0728 rtl_copyMemory(p, d, n); 0729 d += n; 0730 nDatLen -= n; 0731 0732 #ifndef WORDS_BIGENDIAN 0733 __rtl_digest_swapLong(ctx->m_pData, DIGEST_LBLOCK_SHA); 0734 #endif 0735 0736 __rtl_digest_updateSHA(ctx); 0737 ctx->m_nDatLen = 0; 0738 } 0739 0740 while (nDatLen >= DIGEST_CBLOCK_SHA) { 0741 rtl_copyMemory(ctx->m_pData, d, DIGEST_CBLOCK_SHA); 0742 d += DIGEST_CBLOCK_SHA; 0743 nDatLen -= DIGEST_CBLOCK_SHA; 0744 0745 #ifndef WORDS_BIGENDIAN 0746 __rtl_digest_swapLong(ctx->m_pData, DIGEST_LBLOCK_SHA); 0747 #endif 0748 0749 __rtl_digest_updateSHA(ctx); 0750 } 0751 0752 rtl_copyMemory(ctx->m_pData, d, nDatLen); 0753 ctx->m_nDatLen = nDatLen; 0754 0755 return rtl_Digest_E_None; 0756 } 0757 0758 /* 0759 * rtl_digest_getSHA1. 0760 */ 0761 rtlDigestError rtl_digest_getSHA1( 0762 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) 0763 { 0764 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; 0765 sal_uInt8 *p = pBuffer; 0766 0767 DigestContextSHA *ctx; 0768 0769 if ((pImpl == 0) || (pBuffer == 0)) 0770 return rtl_Digest_E_Argument; 0771 0772 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)) 0773 return rtl_Digest_E_Algorithm; 0774 0775 if (!(pImpl->m_digest.m_length <= nBufLen)) 0776 return rtl_Digest_E_BufferSize; 0777 0778 ctx = &(pImpl->m_context); 0779 0780 __rtl_digest_endSHA(ctx); 0781 RTL_DIGEST_HTONL(ctx->m_nA, p); 0782 RTL_DIGEST_HTONL(ctx->m_nB, p); 0783 RTL_DIGEST_HTONL(ctx->m_nC, p); 0784 RTL_DIGEST_HTONL(ctx->m_nD, p); 0785 RTL_DIGEST_HTONL(ctx->m_nE, p); 0786 __rtl_digest_initSHA(ctx, __rtl_digest_updateSHA_1); 0787 0788 return rtl_Digest_E_None; 0789 } 0790 0791 /* 0792 * rtl_digest_destroySHA1. 0793 */ 0794 void rtl_digest_destroySHA1(rtlDigest Digest) 0795 { 0796 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; 0797 if (pImpl) { 0798 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1) 0799 rtl_freeZeroMemory(pImpl, sizeof(DigestSHA_Impl)); 0800 else 0801 rtl_freeMemory(pImpl); 0802 } 0803 } 0804 0805 /*======================================================================== 0806 * 0807 * The End. 0808 * 0809 *======================================================================*/ 0810 0811 bool SHA1::getHash(QString const & text, QByteArray & hash) 0812 { 0813 rtlDigest aDigest = rtl_digest_createSHA1(); 0814 rtlDigestError aError = rtl_digest_updateSHA1(aDigest, text.unicode(), text.length() * sizeof(QChar)); 0815 0816 if (aError == rtl_Digest_E_None) { 0817 QByteArray digest; 0818 digest.resize(RTL_DIGEST_LENGTH_SHA1 + 1); 0819 digest.fill('\0', RTL_DIGEST_LENGTH_SHA1); 0820 0821 aError = rtl_digest_getSHA1(aDigest, (unsigned char *) digest.data(), RTL_DIGEST_LENGTH_SHA1); 0822 0823 if (aError != rtl_Digest_E_None) 0824 return false; 0825 0826 hash = digest; 0827 0828 return true; 0829 } 0830 0831 return false; 0832 }