KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

854 lines
22KB

  1. /*************************************************************************
  2. * This implementation has been taken from the OpenOffice 1.0 and modified
  3. * to use KSpread data types.
  4. *
  5. * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
  6. *
  7. * Sun has made the contents of this file available subject to the
  8. * terms of GNU Lesser General Public License Version 2.1 as
  9. * specified in sal/rtl/source/digest.c in the OpenOffice package.
  10. *
  11. *
  12. * Sun Microsystems Inc., October, 2000
  13. *
  14. * GNU Lesser General Public License Version 2.1
  15. * =============================================
  16. * Copyright 2000 by Sun Microsystems, Inc.
  17. * 901 San Antonio Road, Palo Alto, CA 94303, USA
  18. *
  19. * This library is free software; you can redistribute it and/or
  20. * modify it under the terms of the GNU Lesser General Public
  21. * License version 2.1, as published by the Free Software Foundation.
  22. *
  23. * This library is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  26. * Lesser General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Lesser General Public
  29. * License along with this library; if not, write to the Free Software
  30. * Foundation, Inc., 51 Franklin Street, Fifth Floor,
  31. * Boston, MA 02110-1301, USA
  32. *
  33. * All Rights Reserved.
  34. *
  35. * Contributor(s): Matthias Huetsch <matthias.huetsch@sun.com>
  36. *
  37. *
  38. ************************************************************************/
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include "../config.h"
  42. #include "digest.h"
  43. #include <kdebug.h>
  44. #include <kmdcodec.h>
  45. typedef unsigned char sal_uInt8;
  46. typedef unsigned short sal_uInt16;
  47. #if SIZEOF_INT == 4
  48. typedef unsigned int sal_uInt32;
  49. #else
  50. typedef unsigned long sal_uInt32;
  51. #endif
  52. void rtl_freeZeroMemory(void * p, sal_uInt32 n);
  53. void rtl_freeMemory(void * p);
  54. void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes);
  55. void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes);
  56. #ifndef OSL_LOBYTE
  57. # define OSL_LOBYTE(w) ((sal_uInt8)((sal_uInt16)(w) & 0xFF))
  58. #endif
  59. #ifndef OSL_HIBYTE
  60. # define OSL_HIBYTE(w) ((sal_uInt8)(((sal_uInt16)(w) >> 8) & 0xFF))
  61. #endif
  62. #ifndef OSL_MAKEWORD
  63. # define OSL_MAKEWORD(bl, bh) ((sal_uInt16)((bl) & 0xFF) | (((sal_uInt16)(bh) & 0xFF) << 8))
  64. #endif
  65. #ifndef OSL_MAKEDWORD
  66. # define OSL_MAKEDWORD(wl, wh) ((sal_uInt32)((wl) & 0xFFFF) | (((sal_uInt32)(wh) & 0xFFFF) << 16))
  67. #endif
  68. #ifndef OSL_LOWORD
  69. # define OSL_LOWORD(d) ((sal_uInt16)((sal_uInt32)(d) & 0xFFFF))
  70. #endif
  71. #ifndef OSL_HIWORD
  72. # define OSL_HIWORD(d) ((sal_uInt16)(((sal_uInt32)(d) >> 16) & 0xFFFF))
  73. #endif
  74. /** Define macros for swapping between byte orders.
  75. */
  76. #ifndef OSL_SWAPWORD
  77. # define OSL_SWAPWORD(w) OSL_MAKEWORD(OSL_HIBYTE(w),OSL_LOBYTE(w))
  78. #endif
  79. #ifndef OSL_SWAPDWORD
  80. # define OSL_SWAPDWORD(d) OSL_MAKEDWORD(OSL_SWAPWORD(OSL_HIWORD(d)),OSL_SWAPWORD(OSL_LOWORD(d)))
  81. #endif
  82. /*========================================================================
  83. *
  84. * rtlDigest.
  85. *
  86. *======================================================================*/
  87. /** Digest Handle opaque type.
  88. */
  89. typedef void* rtlDigest;
  90. /** Digest Algorithm enumeration.
  91. @see rtl_digest_create()
  92. */
  93. enum __rtl_DigestAlgorithm
  94. {
  95. rtl_Digest_AlgorithmMD2,
  96. rtl_Digest_AlgorithmMD5,
  97. rtl_Digest_AlgorithmSHA,
  98. rtl_Digest_AlgorithmSHA1,
  99. rtl_Digest_AlgorithmHMAC_MD5,
  100. rtl_Digest_AlgorithmHMAC_SHA1,
  101. rtl_Digest_AlgorithmInvalid,
  102. rtl_Digest_Algorithm_FORCE_EQUAL_SIZE
  103. };
  104. /** Digest Algorithm type.
  105. */
  106. typedef enum __rtl_DigestAlgorithm rtlDigestAlgorithm;
  107. /** Error Code enumeration.
  108. */
  109. enum __rtl_DigestError
  110. {
  111. rtl_Digest_E_None,
  112. rtl_Digest_E_Argument,
  113. rtl_Digest_E_Algorithm,
  114. rtl_Digest_E_BufferSize,
  115. rtl_Digest_E_Memory,
  116. rtl_Digest_E_Unknown,
  117. rtl_Digest_E_FORCE_EQUAL_SIZE
  118. };
  119. /** Error Code type.
  120. */
  121. typedef enum __rtl_DigestError rtlDigestError;
  122. typedef rtlDigestError Digest_init_t( void * ctx, const sal_uInt8 * Data, sal_uInt32 DatLen );
  123. typedef void Digest_delete_t( void *ctx );
  124. typedef rtlDigestError Digest_update_t( void * ctx, const void * Data, sal_uInt32 DatLen );
  125. typedef rtlDigestError Digest_get_t( void * ctx, sal_uInt8 * Buffer, sal_uInt32 BufLen );
  126. /*========================================================================
  127. *
  128. * rtl_digest_SHA1 interface.
  129. *
  130. *======================================================================*/
  131. #define RTL_DIGEST_LENGTH_SHA1 20
  132. /** Create a SHA1 digest handle.
  133. @descr The SHA1 digest algorithm is specified in
  134. FIPS PUB 180-1 (Supersedes FIPS PUB 180)
  135. Secure Hash Standard
  136. @see rtl_digest_create()
  137. */
  138. rtlDigest rtl_digest_createSHA1 (void);
  139. /** Destroy a SHA1 digest handle.
  140. @see rtl_digest_destroy()
  141. */
  142. void rtl_digest_destroySHA1( rtlDigest Digest );
  143. /** Update a SHA1 digest with given data.
  144. @see rtl_digest_update()
  145. */
  146. rtlDigestError rtl_digest_updateSHA1( rtlDigest Digest, const void * pData, uint nDatLen );
  147. /** Finalize a SHA1 digest and retrieve the digest value.
  148. @see rtl_digest_get()
  149. */
  150. rtlDigestError rtl_digest_getSHA1( rtlDigest Digest, sal_uInt8 * pBuffer, uint nBufLen );
  151. /** Evaluate a SHA1 digest value from given data.
  152. @descr This function performs an optimized call sequence on a
  153. single data buffer, avoiding digest creation and destruction.
  154. @see rtl_digest_updateSHA1()
  155. @see rtl_digest_getSHA1()
  156. @param pData [in] data buffer.
  157. @param nDatLen [in] data length.
  158. @param pBuffer [in] digest value buffer.
  159. @param nBufLen [in] digest value length.
  160. @return rtl_Digest_E_None upon success.
  161. */
  162. rtlDigestError rtl_digest_SHA1( const void * pData, uint nDatLen,
  163. unsigned char * pBuffer, uint nBufLen );
  164. /*========================================================================
  165. *
  166. * rtlDigest internals.
  167. *
  168. *======================================================================*/
  169. void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes)
  170. {
  171. memset(Ptr, 0, Bytes);
  172. }
  173. void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes)
  174. {
  175. memcpy(Dst, Src, Bytes);
  176. }
  177. void rtl_freeMemory (void * p)
  178. {
  179. free(p);
  180. }
  181. void rtl_freeZeroMemory (void * p, sal_uInt32 n)
  182. {
  183. if (p)
  184. {
  185. memset(p, 0, n);
  186. free(p);
  187. }
  188. }
  189. #define RTL_DIGEST_CREATE(T) ((T*)(malloc(sizeof(T))))
  190. #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
  191. #define RTL_DIGEST_HTONL(l,c) \
  192. (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
  193. *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
  194. *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
  195. *((c)++) = (sal_uInt8)(((l) ) & 0xff))
  196. #define RTL_DIGEST_LTOC(l,c) \
  197. (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \
  198. *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
  199. *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
  200. *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
  201. typedef struct digest_impl_st
  202. {
  203. rtlDigestAlgorithm m_algorithm;
  204. sal_uInt32 m_length;
  205. Digest_init_t *m_init;
  206. Digest_delete_t *m_delete;
  207. Digest_update_t *m_update;
  208. Digest_get_t *m_get;
  209. } Digest_Impl;
  210. /*
  211. * __rtl_digest_swapLong.
  212. */
  213. static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
  214. {
  215. register sal_uInt32 *X;
  216. register int i, n;
  217. X = pData;
  218. n = nDatLen;
  219. for (i = 0; i < n; i++)
  220. X[i] = OSL_SWAPDWORD(X[i]);
  221. }
  222. /*========================================================================
  223. *
  224. * rtlDigest implementation.
  225. *
  226. *======================================================================*/
  227. /*
  228. * rtl_digest_create.
  229. rtlDigest rtl_digest_create (rtlDigestAlgorithm Algorithm)
  230. {
  231. rtlDigest Digest = (rtlDigest)NULL;
  232. switch (Algorithm)
  233. {
  234. case rtl_Digest_AlgorithmMD2:
  235. Digest = rtl_digest_createMD2();
  236. break;
  237. case rtl_Digest_AlgorithmMD5:
  238. Digest = rtl_digest_createMD5();
  239. break;
  240. case rtl_Digest_AlgorithmSHA:
  241. Digest = rtl_digest_createSHA();
  242. break;
  243. case rtl_Digest_AlgorithmSHA1:
  244. Digest = rtl_digest_createSHA1();
  245. break;
  246. case rtl_Digest_AlgorithmHMAC_MD5:
  247. Digest = rtl_digest_createHMAC_MD5();
  248. break;
  249. case rtl_Digest_AlgorithmHMAC_SHA1:
  250. Digest = rtl_digest_createHMAC_SHA1();
  251. break;
  252. default: // rtl_Digest_AlgorithmInvalid
  253. break;
  254. }
  255. return Digest;
  256. }
  257. // rtl_digest_queryAlgorithm.
  258. rtlDigestAlgorithm rtl_digest_queryAlgorithm (rtlDigest Digest)
  259. {
  260. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  261. if (pImpl)
  262. return pImpl->m_algorithm;
  263. else
  264. return rtl_Digest_AlgorithmInvalid;
  265. }
  266. // rtl_digest_queryLength.
  267. sal_uInt32 rtl_digest_queryLength (rtlDigest Digest)
  268. {
  269. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  270. if (pImpl)
  271. return pImpl->m_length;
  272. else
  273. return 0;
  274. }
  275. // * rtl_digest_init.
  276. rtlDigestError rtl_digest_init (
  277. rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
  278. {
  279. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  280. if (pImpl)
  281. {
  282. if (pImpl->m_init)
  283. return pImpl->m_init (Digest, pData, nDatLen);
  284. else
  285. return rtl_Digest_E_None;
  286. }
  287. return rtl_Digest_E_Argument;
  288. }
  289. // * rtl_digest_update.
  290. rtlDigestError rtl_digest_update (
  291. rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
  292. {
  293. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  294. if (pImpl && pImpl->m_update)
  295. return pImpl->m_update (Digest, pData, nDatLen);
  296. else
  297. return rtl_Digest_E_Argument;
  298. }
  299. // * rtl_digest_get.
  300. rtlDigestError rtl_digest_get (
  301. rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
  302. {
  303. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  304. if (pImpl && pImpl->m_get)
  305. return pImpl->m_get (Digest, pBuffer, nBufLen);
  306. else
  307. return rtl_Digest_E_Argument;
  308. }
  309. // * rtl_digest_destroy.
  310. void rtl_digest_destroy (rtlDigest Digest)
  311. {
  312. Digest_Impl *pImpl = (Digest_Impl *)Digest;
  313. if (pImpl && pImpl->m_delete)
  314. pImpl->m_delete (Digest);
  315. }
  316. */
  317. /*========================================================================
  318. *
  319. * rtl_digest_(SHA|SHA1) common internals.
  320. *
  321. *======================================================================*/
  322. #define DIGEST_CBLOCK_SHA 64
  323. #define DIGEST_LBLOCK_SHA 16
  324. typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x);
  325. static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x);
  326. typedef struct digestSHA_context_st
  327. {
  328. DigestSHA_update_t *m_update;
  329. sal_uInt32 m_nDatLen;
  330. sal_uInt32 m_pData[DIGEST_LBLOCK_SHA];
  331. sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE;
  332. sal_uInt32 m_nL, m_nH;
  333. } DigestContextSHA;
  334. typedef struct digestSHA_impl_st
  335. {
  336. Digest_Impl m_digest;
  337. DigestContextSHA m_context;
  338. } DigestSHA_Impl;
  339. static void __rtl_digest_initSHA (
  340. DigestContextSHA *ctx, DigestSHA_update_t *fct);
  341. static void __rtl_digest_updateSHA (DigestContextSHA *ctx);
  342. static void __rtl_digest_endSHA (DigestContextSHA *ctx);
  343. #define K_00_19 (sal_uInt32)0x5a827999L
  344. #define K_20_39 (sal_uInt32)0x6ed9eba1L
  345. #define K_40_59 (sal_uInt32)0x8f1bbcdcL
  346. #define K_60_79 (sal_uInt32)0xca62c1d6L
  347. #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
  348. #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
  349. #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  350. #define F_60_79(b,c,d) F_20_39(b,c,d)
  351. #define BODY_X(i) \
  352. (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
  353. #define BODY_00_15(u,i,a,b,c,d,e,f) \
  354. (f) = X[i]; \
  355. (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
  356. (b) = RTL_DIGEST_ROTL((b), 30);
  357. #define BODY_16_19(u,i,a,b,c,d,e,f) \
  358. (f) = BODY_X((i)); \
  359. (f) = X[(i)&0x0f] = (u)((f)); \
  360. (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
  361. (b) = RTL_DIGEST_ROTL((b), 30);
  362. #define BODY_20_39(u,i,a,b,c,d,e,f) \
  363. (f) = BODY_X((i)); \
  364. (f) = X[(i)&0x0f] = (u)((f)); \
  365. (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
  366. (b) = RTL_DIGEST_ROTL((b), 30);
  367. #define BODY_40_59(u,i,a,b,c,d,e,f) \
  368. (f) = BODY_X((i)); \
  369. (f) = X[(i)&0x0f] = (u)((f)); \
  370. (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
  371. (b) = RTL_DIGEST_ROTL((b), 30);
  372. #define BODY_60_79(u,i,a,b,c,d,e,f) \
  373. (f) = BODY_X((i)); \
  374. (f) = X[(i)&0x0f] = (u)((f)); \
  375. (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
  376. (b) = RTL_DIGEST_ROTL((b), 30);
  377. /*
  378. * __rtl_digest_initSHA.
  379. */
  380. static void __rtl_digest_initSHA (
  381. DigestContextSHA *ctx, DigestSHA_update_t *fct)
  382. {
  383. rtl_zeroMemory (ctx, sizeof (DigestContextSHA));
  384. ctx->m_update = fct;
  385. ctx->m_nA = (sal_uInt32)0x67452301L;
  386. ctx->m_nB = (sal_uInt32)0xefcdab89L;
  387. ctx->m_nC = (sal_uInt32)0x98badcfeL;
  388. ctx->m_nD = (sal_uInt32)0x10325476L;
  389. ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
  390. }
  391. /*
  392. * __rtl_digest_updateSHA.
  393. */
  394. static void __rtl_digest_updateSHA (DigestContextSHA *ctx)
  395. {
  396. register sal_uInt32 A, B, C, D, E, T;
  397. register sal_uInt32 *X;
  398. register DigestSHA_update_t *U;
  399. U = ctx->m_update;
  400. A = ctx->m_nA;
  401. B = ctx->m_nB;
  402. C = ctx->m_nC;
  403. D = ctx->m_nD;
  404. E = ctx->m_nE;
  405. X = ctx->m_pData;
  406. BODY_00_15 (U, 0, A, B, C, D, E, T);
  407. BODY_00_15 (U, 1, T, A, B, C, D, E);
  408. BODY_00_15 (U, 2, E, T, A, B, C, D);
  409. BODY_00_15 (U, 3, D, E, T, A, B, C);
  410. BODY_00_15 (U, 4, C, D, E, T, A, B);
  411. BODY_00_15 (U, 5, B, C, D, E, T, A);
  412. BODY_00_15 (U, 6, A, B, C, D, E, T);
  413. BODY_00_15 (U, 7, T, A, B, C, D, E);
  414. BODY_00_15 (U, 8, E, T, A, B, C, D);
  415. BODY_00_15 (U, 9, D, E, T, A, B, C);
  416. BODY_00_15 (U, 10, C, D, E, T, A, B);
  417. BODY_00_15 (U, 11, B, C, D, E, T, A);
  418. BODY_00_15 (U, 12, A, B, C, D, E, T);
  419. BODY_00_15 (U, 13, T, A, B, C, D, E);
  420. BODY_00_15 (U, 14, E, T, A, B, C, D);
  421. BODY_00_15 (U, 15, D, E, T, A, B, C);
  422. BODY_16_19 (U, 16, C, D, E, T, A, B);
  423. BODY_16_19 (U, 17, B, C, D, E, T, A);
  424. BODY_16_19 (U, 18, A, B, C, D, E, T);
  425. BODY_16_19 (U, 19, T, A, B, C, D, E);
  426. BODY_20_39 (U, 20, E, T, A, B, C, D);
  427. BODY_20_39 (U, 21, D, E, T, A, B, C);
  428. BODY_20_39 (U, 22, C, D, E, T, A, B);
  429. BODY_20_39 (U, 23, B, C, D, E, T, A);
  430. BODY_20_39 (U, 24, A, B, C, D, E, T);
  431. BODY_20_39 (U, 25, T, A, B, C, D, E);
  432. BODY_20_39 (U, 26, E, T, A, B, C, D);
  433. BODY_20_39 (U, 27, D, E, T, A, B, C);
  434. BODY_20_39 (U, 28, C, D, E, T, A, B);
  435. BODY_20_39 (U, 29, B, C, D, E, T, A);
  436. BODY_20_39 (U, 30, A, B, C, D, E, T);
  437. BODY_20_39 (U, 31, T, A, B, C, D, E);
  438. BODY_20_39 (U, 32, E, T, A, B, C, D);
  439. BODY_20_39 (U, 33, D, E, T, A, B, C);
  440. BODY_20_39 (U, 34, C, D, E, T, A, B);
  441. BODY_20_39 (U, 35, B, C, D, E, T, A);
  442. BODY_20_39 (U, 36, A, B, C, D, E, T);
  443. BODY_20_39 (U, 37, T, A, B, C, D, E);
  444. BODY_20_39 (U, 38, E, T, A, B, C, D);
  445. BODY_20_39 (U, 39, D, E, T, A, B, C);
  446. BODY_40_59 (U, 40, C, D, E, T, A, B);
  447. BODY_40_59 (U, 41, B, C, D, E, T, A);
  448. BODY_40_59 (U, 42, A, B, C, D, E, T);
  449. BODY_40_59 (U, 43, T, A, B, C, D, E);
  450. BODY_40_59 (U, 44, E, T, A, B, C, D);
  451. BODY_40_59 (U, 45, D, E, T, A, B, C);
  452. BODY_40_59 (U, 46, C, D, E, T, A, B);
  453. BODY_40_59 (U, 47, B, C, D, E, T, A);
  454. BODY_40_59 (U, 48, A, B, C, D, E, T);
  455. BODY_40_59 (U, 49, T, A, B, C, D, E);
  456. BODY_40_59 (U, 50, E, T, A, B, C, D);
  457. BODY_40_59 (U, 51, D, E, T, A, B, C);
  458. BODY_40_59 (U, 52, C, D, E, T, A, B);
  459. BODY_40_59 (U, 53, B, C, D, E, T, A);
  460. BODY_40_59 (U, 54, A, B, C, D, E, T);
  461. BODY_40_59 (U, 55, T, A, B, C, D, E);
  462. BODY_40_59 (U, 56, E, T, A, B, C, D);
  463. BODY_40_59 (U, 57, D, E, T, A, B, C);
  464. BODY_40_59 (U, 58, C, D, E, T, A, B);
  465. BODY_40_59 (U, 59, B, C, D, E, T, A);
  466. BODY_60_79 (U, 60, A, B, C, D, E, T);
  467. BODY_60_79 (U, 61, T, A, B, C, D, E);
  468. BODY_60_79 (U, 62, E, T, A, B, C, D);
  469. BODY_60_79 (U, 63, D, E, T, A, B, C);
  470. BODY_60_79 (U, 64, C, D, E, T, A, B);
  471. BODY_60_79 (U, 65, B, C, D, E, T, A);
  472. BODY_60_79 (U, 66, A, B, C, D, E, T);
  473. BODY_60_79 (U, 67, T, A, B, C, D, E);
  474. BODY_60_79 (U, 68, E, T, A, B, C, D);
  475. BODY_60_79 (U, 69, D, E, T, A, B, C);
  476. BODY_60_79 (U, 70, C, D, E, T, A, B);
  477. BODY_60_79 (U, 71, B, C, D, E, T, A);
  478. BODY_60_79 (U, 72, A, B, C, D, E, T);
  479. BODY_60_79 (U, 73, T, A, B, C, D, E);
  480. BODY_60_79 (U, 74, E, T, A, B, C, D);
  481. BODY_60_79 (U, 75, D, E, T, A, B, C);
  482. BODY_60_79 (U, 76, C, D, E, T, A, B);
  483. BODY_60_79 (U, 77, B, C, D, E, T, A);
  484. BODY_60_79 (U, 78, A, B, C, D, E, T);
  485. BODY_60_79 (U, 79, T, A, B, C, D, E);
  486. ctx->m_nA += E;
  487. ctx->m_nB += T;
  488. ctx->m_nC += A;
  489. ctx->m_nD += B;
  490. ctx->m_nE += C;
  491. }
  492. /*
  493. * __rtl_digest_endSHA.
  494. */
  495. static void __rtl_digest_endSHA (DigestContextSHA *ctx)
  496. {
  497. static const sal_uInt8 end[4] =
  498. {
  499. 0x80, 0x00, 0x00, 0x00
  500. };
  501. register const sal_uInt8 *p = end;
  502. register sal_uInt32 *X;
  503. register int i;
  504. X = ctx->m_pData;
  505. i = (ctx->m_nDatLen >> 2);
  506. #ifdef WORDS_BIGENDIAN
  507. __rtl_digest_swapLong (X, i + 1);
  508. #endif
  509. switch (ctx->m_nDatLen & 0x03)
  510. {
  511. case 1: X[i] &= 0x000000ff; break;
  512. case 2: X[i] &= 0x0000ffff; break;
  513. case 3: X[i] &= 0x00ffffff; break;
  514. }
  515. switch (ctx->m_nDatLen & 0x03)
  516. {
  517. case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
  518. case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
  519. case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
  520. case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
  521. }
  522. __rtl_digest_swapLong (X, i + 1);
  523. i += 1;
  524. if (i >= (DIGEST_LBLOCK_SHA - 2))
  525. {
  526. for (; i < DIGEST_LBLOCK_SHA; i++)
  527. X[i] = 0;
  528. __rtl_digest_updateSHA (ctx);
  529. i = 0;
  530. }
  531. for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
  532. X[i] = 0;
  533. X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
  534. X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
  535. __rtl_digest_updateSHA (ctx);
  536. }
  537. /*========================================================================
  538. *
  539. * rtl_digest_SHA1 internals.
  540. *
  541. *======================================================================*/
  542. /*
  543. * __rtl_digest_SHA_1.
  544. */
  545. static const Digest_Impl __rtl_digest_SHA_1 = { rtl_Digest_AlgorithmSHA1,
  546. RTL_DIGEST_LENGTH_SHA1,
  547. 0,
  548. rtl_digest_destroySHA1,
  549. rtl_digest_updateSHA1,
  550. rtl_digest_getSHA1
  551. };
  552. /*
  553. * __rtl_digest_updateSHA_1.
  554. */
  555. static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
  556. {
  557. return RTL_DIGEST_ROTL (x, 1);
  558. }
  559. /*========================================================================
  560. *
  561. * rtl_digest_SHA1 implementation.
  562. *
  563. *======================================================================*/
  564. /*
  565. * rtl_digest_SHA1.
  566. */
  567. rtlDigestError rtl_digest_SHA1 (
  568. const void *pData, sal_uInt32 nDatLen,
  569. sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
  570. {
  571. DigestSHA_Impl digest;
  572. rtlDigestError result;
  573. digest.m_digest = __rtl_digest_SHA_1;
  574. __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
  575. result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
  576. if (result == rtl_Digest_E_None)
  577. result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
  578. rtl_zeroMemory (&digest, sizeof (digest));
  579. return (result);
  580. }
  581. /*
  582. * rtl_digest_createSHA1.
  583. */
  584. rtlDigest rtl_digest_createSHA1 (void)
  585. {
  586. DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
  587. pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
  588. if (pImpl)
  589. {
  590. pImpl->m_digest = __rtl_digest_SHA_1;
  591. __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
  592. }
  593. return ((rtlDigest)pImpl);
  594. }
  595. /*
  596. * rtl_digest_updateSHA1.
  597. */
  598. rtlDigestError rtl_digest_updateSHA1 (
  599. rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
  600. {
  601. DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
  602. const sal_uInt8 *d = (const sal_uInt8 *)pData;
  603. DigestContextSHA *ctx;
  604. sal_uInt32 len;
  605. if ((pImpl == NULL) || (pData == NULL))
  606. return rtl_Digest_E_Argument;
  607. if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
  608. return rtl_Digest_E_Algorithm;
  609. if (nDatLen == 0)
  610. return rtl_Digest_E_None;
  611. ctx = &(pImpl->m_context);
  612. len = ctx->m_nL + (nDatLen << 3);
  613. if (len < ctx->m_nL) ctx->m_nH += 1;
  614. ctx->m_nH += (nDatLen >> 29);
  615. ctx->m_nL = len;
  616. if (ctx->m_nDatLen)
  617. {
  618. sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
  619. sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
  620. if (nDatLen < n)
  621. {
  622. rtl_copyMemory (p, d, nDatLen);
  623. ctx->m_nDatLen += nDatLen;
  624. return rtl_Digest_E_None;
  625. }
  626. rtl_copyMemory (p, d, n);
  627. d += n;
  628. nDatLen -= n;
  629. #ifndef WORDS_BIGENDIAN
  630. __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
  631. #endif
  632. __rtl_digest_updateSHA (ctx);
  633. ctx->m_nDatLen = 0;
  634. }
  635. while (nDatLen >= DIGEST_CBLOCK_SHA)
  636. {
  637. rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
  638. d += DIGEST_CBLOCK_SHA;
  639. nDatLen -= DIGEST_CBLOCK_SHA;
  640. #ifndef WORDS_BIGENDIAN
  641. __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
  642. #endif
  643. __rtl_digest_updateSHA (ctx);
  644. }
  645. rtl_copyMemory (ctx->m_pData, d, nDatLen);
  646. ctx->m_nDatLen = nDatLen;
  647. return rtl_Digest_E_None;
  648. }
  649. /*
  650. * rtl_digest_getSHA1.
  651. */
  652. rtlDigestError rtl_digest_getSHA1 (
  653. rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
  654. {
  655. DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
  656. sal_uInt8 *p = pBuffer;
  657. DigestContextSHA *ctx;
  658. if ((pImpl == NULL) || (pBuffer == NULL))
  659. return rtl_Digest_E_Argument;
  660. if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
  661. return rtl_Digest_E_Algorithm;
  662. if (!(pImpl->m_digest.m_length <= nBufLen))
  663. return rtl_Digest_E_BufferSize;
  664. ctx = &(pImpl->m_context);
  665. __rtl_digest_endSHA (ctx);
  666. RTL_DIGEST_HTONL (ctx->m_nA, p);
  667. RTL_DIGEST_HTONL (ctx->m_nB, p);
  668. RTL_DIGEST_HTONL (ctx->m_nC, p);
  669. RTL_DIGEST_HTONL (ctx->m_nD, p);
  670. RTL_DIGEST_HTONL (ctx->m_nE, p);
  671. __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
  672. return rtl_Digest_E_None;
  673. }
  674. /*
  675. * rtl_digest_destroySHA1.
  676. */
  677. void rtl_digest_destroySHA1 (rtlDigest Digest)
  678. {
  679. DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
  680. if (pImpl)
  681. {
  682. if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
  683. rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
  684. else
  685. rtl_freeMemory (pImpl);
  686. }
  687. }
  688. /*========================================================================
  689. *
  690. * The End.
  691. *
  692. *======================================================================*/
  693. bool SHA1::getHash( TQString const & text, TQCString & hash )
  694. {
  695. rtlDigest aDigest = rtl_digest_createSHA1();
  696. rtlDigestError aError = rtl_digest_updateSHA1( aDigest, text.tqunicode(), text.length() * sizeof(TQChar) );
  697. if ( aError == rtl_Digest_E_None )
  698. {
  699. TQCString digest;
  700. digest.resize( RTL_DIGEST_LENGTH_SHA1 + 1 );
  701. digest.fill( '\0', RTL_DIGEST_LENGTH_SHA1 );
  702. aError = rtl_digest_getSHA1( aDigest, (unsigned char *) digest.data(), RTL_DIGEST_LENGTH_SHA1 );
  703. if (aError != rtl_Digest_E_None)
  704. return false;
  705. hash = digest;
  706. return true;
  707. }
  708. return false;
  709. }