bump product version to 4.1.6.2
[LibreOffice.git] / sal / rtl / digest.cxx
blobe7cd52834f77e8b9bce4fd66a646024ac57e9092
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #include <sal/types.h>
23 #include <sal/macros.h>
24 #include <osl/endian.h>
25 #include <rtl/alloc.h>
26 #include <rtl/digest.h>
28 /*========================================================================
30 * rtlDigest internals.
32 *======================================================================*/
33 #define RTL_DIGEST_CREATE(T) ((T*)(rtl_allocateZeroMemory(sizeof(T))))
35 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
37 #define RTL_DIGEST_HTONL(l,c) \
38 (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
39 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
40 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
41 *((c)++) = (sal_uInt8)(((l) ) & 0xff))
43 #define RTL_DIGEST_LTOC(l,c) \
44 (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \
45 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
46 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
47 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
49 typedef rtlDigestError (SAL_CALL Digest_init_t) (
50 void *ctx, const sal_uInt8 *Data, sal_uInt32 DatLen);
52 typedef void (SAL_CALL Digest_delete_t) (void *ctx);
54 typedef rtlDigestError (SAL_CALL Digest_update_t) (
55 void *ctx, const void *Data, sal_uInt32 DatLen);
57 typedef rtlDigestError (SAL_CALL Digest_get_t) (
58 void *ctx, sal_uInt8 *Buffer, sal_uInt32 BufLen);
60 struct Digest_Impl
62 rtlDigestAlgorithm m_algorithm;
63 sal_uInt32 m_length;
65 Digest_init_t *m_init;
66 Digest_delete_t *m_delete;
67 Digest_update_t *m_update;
68 Digest_get_t *m_get;
72 * __rtl_digest_swapLong.
74 static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
76 sal_uInt32 *X;
77 int i, n;
79 X = pData;
80 n = nDatLen;
82 for (i = 0; i < n; i++)
83 X[i] = OSL_SWAPDWORD(X[i]);
86 /*========================================================================
88 * rtlDigest implementation.
90 *======================================================================*/
92 * rtl_digest_create.
94 rtlDigest SAL_CALL rtl_digest_create (rtlDigestAlgorithm Algorithm)
95 SAL_THROW_EXTERN_C()
97 rtlDigest Digest = (rtlDigest)NULL;
98 switch (Algorithm)
100 case rtl_Digest_AlgorithmMD2:
101 Digest = rtl_digest_createMD2();
102 break;
104 case rtl_Digest_AlgorithmMD5:
105 Digest = rtl_digest_createMD5();
106 break;
108 case rtl_Digest_AlgorithmSHA:
109 Digest = rtl_digest_createSHA();
110 break;
112 case rtl_Digest_AlgorithmSHA1:
113 Digest = rtl_digest_createSHA1();
114 break;
116 case rtl_Digest_AlgorithmHMAC_MD5:
117 Digest = rtl_digest_createHMAC_MD5();
118 break;
120 case rtl_Digest_AlgorithmHMAC_SHA1:
121 Digest = rtl_digest_createHMAC_SHA1();
122 break;
124 default: /* rtl_Digest_AlgorithmInvalid */
125 break;
127 return Digest;
131 * rtl_digest_queryAlgorithm.
133 rtlDigestAlgorithm SAL_CALL rtl_digest_queryAlgorithm (rtlDigest Digest)
134 SAL_THROW_EXTERN_C()
136 Digest_Impl *pImpl = (Digest_Impl *)Digest;
137 if (pImpl)
138 return pImpl->m_algorithm;
139 else
140 return rtl_Digest_AlgorithmInvalid;
144 * rtl_digest_queryLength.
146 sal_uInt32 SAL_CALL rtl_digest_queryLength (rtlDigest Digest)
147 SAL_THROW_EXTERN_C()
149 Digest_Impl *pImpl = (Digest_Impl *)Digest;
150 if (pImpl)
151 return pImpl->m_length;
152 else
153 return 0;
157 * rtl_digest_init.
159 rtlDigestError SAL_CALL rtl_digest_init (
160 rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
161 SAL_THROW_EXTERN_C()
163 Digest_Impl *pImpl = (Digest_Impl *)Digest;
164 if (pImpl)
166 if (pImpl->m_init)
167 return pImpl->m_init (Digest, pData, nDatLen);
168 else
169 return rtl_Digest_E_None;
171 return rtl_Digest_E_Argument;
175 * rtl_digest_update.
177 rtlDigestError SAL_CALL rtl_digest_update (
178 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
179 SAL_THROW_EXTERN_C()
181 Digest_Impl *pImpl = (Digest_Impl *)Digest;
182 if (pImpl && pImpl->m_update)
183 return pImpl->m_update (Digest, pData, nDatLen);
184 else
185 return rtl_Digest_E_Argument;
189 * rtl_digest_get.
191 rtlDigestError SAL_CALL rtl_digest_get (
192 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
193 SAL_THROW_EXTERN_C()
195 Digest_Impl *pImpl = (Digest_Impl *)Digest;
196 if (pImpl && pImpl->m_get)
197 return pImpl->m_get (Digest, pBuffer, nBufLen);
198 else
199 return rtl_Digest_E_Argument;
203 * rtl_digest_destroy.
205 void SAL_CALL rtl_digest_destroy (rtlDigest Digest) SAL_THROW_EXTERN_C()
207 Digest_Impl *pImpl = (Digest_Impl *)Digest;
208 if (pImpl && pImpl->m_delete)
209 pImpl->m_delete (Digest);
212 /*========================================================================
214 * rtl_digest_MD2 internals.
216 *======================================================================*/
217 #define DIGEST_CBLOCK_MD2 16
218 #define DIGEST_LBLOCK_MD2 16
220 struct DigestContextMD2
222 sal_uInt32 m_nDatLen;
223 sal_uInt8 m_pData[DIGEST_CBLOCK_MD2];
224 sal_uInt32 m_state[DIGEST_LBLOCK_MD2];
225 sal_uInt32 m_chksum[DIGEST_LBLOCK_MD2];
228 struct DigestMD2_Impl
230 Digest_Impl m_digest;
231 DigestContextMD2 m_context;
234 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx);
235 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx);
236 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx);
238 static const sal_uInt32 S[256] =
240 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
241 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
242 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
243 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
244 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
245 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
246 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
247 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
248 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
249 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
250 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
251 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
252 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
253 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
254 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
255 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
256 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
257 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
258 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
259 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
260 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
261 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
262 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
263 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
264 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
265 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
266 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
267 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
268 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
269 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
270 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
271 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
275 * __rtl_digest_MD2.
277 static const Digest_Impl __rtl_digest_MD2 =
279 rtl_Digest_AlgorithmMD2,
280 RTL_DIGEST_LENGTH_MD2,
282 NULL,
283 rtl_digest_destroyMD2,
284 rtl_digest_updateMD2,
285 rtl_digest_getMD2
289 * __rtl_digest_initMD2.
291 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx)
293 memset (ctx, 0, sizeof (DigestContextMD2));
297 * __rtl_digest_updateMD2.
299 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx)
301 sal_uInt8 *X;
302 sal_uInt32 *sp1, *sp2;
303 sal_uInt32 i, k, t;
305 sal_uInt32 state[48];
307 X = ctx->m_pData;
308 sp1 = ctx->m_state;
309 sp2 = ctx->m_chksum;
311 k = sp2[DIGEST_LBLOCK_MD2 - 1];
312 for (i = 0; i < 16; i++)
314 state[i + 0] = sp1[i];
315 state[i + 16] = t = X[i];
316 state[i + 32] = t ^ sp1[i];
317 k = sp2[i] ^= S[t^k];
320 t = 0;
321 for (i = 0; i < 18; i++)
323 for (k = 0; k < 48; k += 8)
325 t = state[k + 0] ^= S[t];
326 t = state[k + 1] ^= S[t];
327 t = state[k + 2] ^= S[t];
328 t = state[k + 3] ^= S[t];
329 t = state[k + 4] ^= S[t];
330 t = state[k + 5] ^= S[t];
331 t = state[k + 6] ^= S[t];
332 t = state[k + 7] ^= S[t];
334 t = ((t + i) & 0xff);
337 memcpy (sp1, state, 16 * sizeof(sal_uInt32));
338 memset (state, 0, 48 * sizeof(sal_uInt32));
342 * __rtl_digest_endMD2.
344 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx)
346 sal_uInt8 *X;
347 sal_uInt32 *C;
348 sal_uInt32 i, n;
350 X = ctx->m_pData;
351 C = ctx->m_chksum;
352 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
354 for (i = ctx->m_nDatLen; i < DIGEST_CBLOCK_MD2; i++)
355 X[i] = (sal_uInt8)(n & 0xff);
356 __rtl_digest_updateMD2 (ctx);
358 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
359 X[i] = (sal_uInt8)(C[i] & 0xff);
360 __rtl_digest_updateMD2 (ctx);
363 /*========================================================================
365 * rtl_digest_MD2 implementation.
367 *======================================================================*/
369 * rtl_digest_MD2.
371 rtlDigestError SAL_CALL rtl_digest_MD2 (
372 const void *pData, sal_uInt32 nDatLen,
373 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
375 DigestMD2_Impl digest;
376 rtlDigestError result;
378 digest.m_digest = __rtl_digest_MD2;
379 __rtl_digest_initMD2 (&(digest.m_context));
381 result = rtl_digest_updateMD2 (&digest, pData, nDatLen);
382 if (result == rtl_Digest_E_None)
383 result = rtl_digest_getMD2 (&digest, pBuffer, nBufLen);
385 memset (&digest, 0, sizeof (digest));
386 return (result);
390 * rtl_digest_createMD2.
392 rtlDigest SAL_CALL rtl_digest_createMD2() SAL_THROW_EXTERN_C()
394 DigestMD2_Impl *pImpl = (DigestMD2_Impl*)NULL;
395 pImpl = RTL_DIGEST_CREATE(DigestMD2_Impl);
396 if (pImpl)
398 pImpl->m_digest = __rtl_digest_MD2;
399 __rtl_digest_initMD2 (&(pImpl->m_context));
401 return ((rtlDigest)pImpl);
405 * rtl_digest_updateMD2.
407 rtlDigestError SAL_CALL rtl_digest_updateMD2 (
408 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
409 SAL_THROW_EXTERN_C()
411 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
412 const sal_uInt8 *d = (const sal_uInt8 *)pData;
414 DigestContextMD2 *ctx;
416 if ((pImpl == NULL) || (pData == NULL))
417 return rtl_Digest_E_Argument;
419 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
420 return rtl_Digest_E_Algorithm;
422 if (nDatLen == 0)
423 return rtl_Digest_E_None;
425 ctx = &(pImpl->m_context);
427 if (ctx->m_nDatLen)
429 sal_uInt8 *p = ctx->m_pData + ctx->m_nDatLen;
430 sal_uInt32 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
432 if (nDatLen < n)
434 memcpy (p, d, nDatLen);
435 ctx->m_nDatLen += nDatLen;
437 return rtl_Digest_E_None;
440 memcpy (p, d, n);
441 d += n;
442 nDatLen -= n;
444 __rtl_digest_updateMD2 (ctx);
445 ctx->m_nDatLen = 0;
448 while (nDatLen >= DIGEST_CBLOCK_MD2)
450 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_MD2);
451 d += DIGEST_CBLOCK_MD2;
452 nDatLen -= DIGEST_CBLOCK_MD2;
454 __rtl_digest_updateMD2 (ctx);
457 memcpy (ctx->m_pData, d, nDatLen);
458 ctx->m_nDatLen = nDatLen;
460 return rtl_Digest_E_None;
464 * rtl_digest_getMD2.
466 rtlDigestError SAL_CALL rtl_digest_getMD2 (
467 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
468 SAL_THROW_EXTERN_C()
470 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
471 sal_uInt32 i;
473 DigestContextMD2 *ctx;
475 if ((pImpl == NULL) || (pBuffer == NULL))
476 return rtl_Digest_E_Argument;
478 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
479 return rtl_Digest_E_Algorithm;
481 if (!(pImpl->m_digest.m_length <= nBufLen))
482 return rtl_Digest_E_BufferSize;
484 ctx = &(pImpl->m_context);
486 __rtl_digest_endMD2 (ctx);
487 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
488 pBuffer[i] = (sal_uInt8)(ctx->m_state[i] & 0xff);
489 __rtl_digest_initMD2 (ctx);
491 return rtl_Digest_E_None;
495 * rtl_digest_destroyMD2.
497 void SAL_CALL rtl_digest_destroyMD2 (rtlDigest Digest) SAL_THROW_EXTERN_C()
499 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
500 if (pImpl)
502 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2)
503 rtl_freeZeroMemory (pImpl, sizeof (DigestMD2_Impl));
504 else
505 rtl_freeMemory (pImpl);
509 /*========================================================================
511 * rtl_digest_MD5 internals.
513 *======================================================================*/
514 #define DIGEST_CBLOCK_MD5 64
515 #define DIGEST_LBLOCK_MD5 16
517 struct DigestContextMD5
519 sal_uInt32 m_nDatLen;
520 sal_uInt32 m_pData[DIGEST_LBLOCK_MD5];
521 sal_uInt32 m_nA, m_nB, m_nC, m_nD;
522 sal_uInt32 m_nL, m_nH;
525 struct DigestMD5_Impl
527 Digest_Impl m_digest;
528 DigestContextMD5 m_context;
531 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx);
532 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx);
533 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx);
535 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
536 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
537 #define H(x,y,z) ((x) ^ (y) ^ (z))
538 #define I(x,y,z) (((x) | (~(z))) ^ (y))
540 #define R0(a,b,c,d,k,s,t) { \
541 a += ((k) + (t) + F((b), (c), (d))); \
542 a = RTL_DIGEST_ROTL(a, s); \
543 a += b; }
545 #define R1(a,b,c,d,k,s,t) { \
546 a += ((k) + (t) + G((b), (c), (d))); \
547 a = RTL_DIGEST_ROTL(a, s); \
548 a += b; }
550 #define R2(a,b,c,d,k,s,t) { \
551 a += ((k) + (t) + H((b), (c), (d))); \
552 a = RTL_DIGEST_ROTL(a, s); \
553 a += b; }
555 #define R3(a,b,c,d,k,s,t) { \
556 a += ((k) + (t) + I((b), (c), (d))); \
557 a = RTL_DIGEST_ROTL(a, s); \
558 a += b; }
561 * __rtl_digest_MD5.
563 static const Digest_Impl __rtl_digest_MD5 =
565 rtl_Digest_AlgorithmMD5,
566 RTL_DIGEST_LENGTH_MD5,
568 NULL,
569 rtl_digest_destroyMD5,
570 rtl_digest_updateMD5,
571 rtl_digest_getMD5
575 * __rtl_digest_initMD5.
577 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx)
579 memset (ctx, 0, sizeof (DigestContextMD5));
581 ctx->m_nA = (sal_uInt32)0x67452301L;
582 ctx->m_nB = (sal_uInt32)0xefcdab89L;
583 ctx->m_nC = (sal_uInt32)0x98badcfeL;
584 ctx->m_nD = (sal_uInt32)0x10325476L;
588 * __rtl_digest_updateMD5.
590 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx)
592 sal_uInt32 A, B, C, D;
593 sal_uInt32 *X;
595 A = ctx->m_nA;
596 B = ctx->m_nB;
597 C = ctx->m_nC;
598 D = ctx->m_nD;
599 X = ctx->m_pData;
601 R0 (A, B, C, D, X[ 0], 7, 0xd76aa478L);
602 R0 (D, A, B, C, X[ 1], 12, 0xe8c7b756L);
603 R0 (C, D, A, B, X[ 2], 17, 0x242070dbL);
604 R0 (B, C, D, A, X[ 3], 22, 0xc1bdceeeL);
605 R0 (A, B, C, D, X[ 4], 7, 0xf57c0fafL);
606 R0 (D, A, B, C, X[ 5], 12, 0x4787c62aL);
607 R0 (C, D, A, B, X[ 6], 17, 0xa8304613L);
608 R0 (B, C, D, A, X[ 7], 22, 0xfd469501L);
609 R0 (A, B, C, D, X[ 8], 7, 0x698098d8L);
610 R0 (D, A, B, C, X[ 9], 12, 0x8b44f7afL);
611 R0 (C, D, A, B, X[10], 17, 0xffff5bb1L);
612 R0 (B, C, D, A, X[11], 22, 0x895cd7beL);
613 R0 (A, B, C, D, X[12], 7, 0x6b901122L);
614 R0 (D, A, B, C, X[13], 12, 0xfd987193L);
615 R0 (C, D, A, B, X[14], 17, 0xa679438eL);
616 R0 (B, C, D, A, X[15], 22, 0x49b40821L);
618 R1 (A, B, C, D, X[ 1], 5, 0xf61e2562L);
619 R1 (D, A, B, C, X[ 6], 9, 0xc040b340L);
620 R1 (C, D, A, B, X[11], 14, 0x265e5a51L);
621 R1 (B, C, D, A, X[ 0], 20, 0xe9b6c7aaL);
622 R1 (A, B, C, D, X[ 5], 5, 0xd62f105dL);
623 R1 (D, A, B, C, X[10], 9, 0x02441453L);
624 R1 (C, D, A, B, X[15], 14, 0xd8a1e681L);
625 R1 (B, C, D, A, X[ 4], 20, 0xe7d3fbc8L);
626 R1 (A, B, C, D, X[ 9], 5, 0x21e1cde6L);
627 R1 (D, A, B, C, X[14], 9, 0xc33707d6L);
628 R1 (C, D, A, B, X[ 3], 14, 0xf4d50d87L);
629 R1 (B, C, D, A, X[ 8], 20, 0x455a14edL);
630 R1 (A, B, C, D, X[13], 5, 0xa9e3e905L);
631 R1 (D, A, B, C, X[ 2], 9, 0xfcefa3f8L);
632 R1 (C, D, A, B, X[ 7], 14, 0x676f02d9L);
633 R1 (B, C, D, A, X[12], 20, 0x8d2a4c8aL);
635 R2 (A, B, C, D, X[ 5], 4, 0xfffa3942L);
636 R2 (D, A, B, C, X[ 8], 11, 0x8771f681L);
637 R2 (C, D, A, B, X[11], 16, 0x6d9d6122L);
638 R2 (B, C, D, A, X[14], 23, 0xfde5380cL);
639 R2 (A, B, C, D, X[ 1], 4, 0xa4beea44L);
640 R2 (D, A, B, C, X[ 4], 11, 0x4bdecfa9L);
641 R2 (C, D, A, B, X[ 7], 16, 0xf6bb4b60L);
642 R2 (B, C, D, A, X[10], 23, 0xbebfbc70L);
643 R2 (A, B, C, D, X[13], 4, 0x289b7ec6L);
644 R2 (D, A, B, C, X[ 0], 11, 0xeaa127faL);
645 R2 (C, D, A, B, X[ 3], 16, 0xd4ef3085L);
646 R2 (B, C, D, A, X[ 6], 23, 0x04881d05L);
647 R2 (A, B, C, D, X[ 9], 4, 0xd9d4d039L);
648 R2 (D, A, B, C, X[12], 11, 0xe6db99e5L);
649 R2 (C, D, A, B, X[15], 16, 0x1fa27cf8L);
650 R2 (B, C, D, A, X[ 2], 23, 0xc4ac5665L);
652 R3 (A, B, C, D, X[ 0], 6, 0xf4292244L);
653 R3 (D, A, B, C, X[ 7], 10, 0x432aff97L);
654 R3 (C, D, A, B, X[14], 15, 0xab9423a7L);
655 R3 (B, C, D, A, X[ 5], 21, 0xfc93a039L);
656 R3 (A, B, C, D, X[12], 6, 0x655b59c3L);
657 R3 (D, A, B, C, X[ 3], 10, 0x8f0ccc92L);
658 R3 (C, D, A, B, X[10], 15, 0xffeff47dL);
659 R3 (B, C, D, A, X[ 1], 21, 0x85845dd1L);
660 R3 (A, B, C, D, X[ 8], 6, 0x6fa87e4fL);
661 R3 (D, A, B, C, X[15], 10, 0xfe2ce6e0L);
662 R3 (C, D, A, B, X[ 6], 15, 0xa3014314L);
663 R3 (B, C, D, A, X[13], 21, 0x4e0811a1L);
664 R3 (A, B, C, D, X[ 4], 6, 0xf7537e82L);
665 R3 (D, A, B, C, X[11], 10, 0xbd3af235L);
666 R3 (C, D, A, B, X[ 2], 15, 0x2ad7d2bbL);
667 R3 (B, C, D, A, X[ 9], 21, 0xeb86d391L);
669 ctx->m_nA += A;
670 ctx->m_nB += B;
671 ctx->m_nC += C;
672 ctx->m_nD += D;
676 * __rtl_digest_endMD5.
678 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx)
680 static const sal_uInt8 end[4] =
682 0x80, 0x00, 0x00, 0x00
684 const sal_uInt8 *p = end;
686 sal_uInt32 *X;
687 int i;
689 X = ctx->m_pData;
690 i = (ctx->m_nDatLen >> 2);
692 #ifdef OSL_BIGENDIAN
693 __rtl_digest_swapLong (X, i + 1);
694 #endif /* OSL_BIGENDIAN */
696 switch (ctx->m_nDatLen & 0x03)
698 case 1: X[i] &= 0x000000ff; break;
699 case 2: X[i] &= 0x0000ffff; break;
700 case 3: X[i] &= 0x00ffffff; break;
703 switch (ctx->m_nDatLen & 0x03)
705 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
706 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
707 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
708 case 3: X[i] |= ((sal_uInt32)(*p)) << 24L;
711 i += 1;
713 if (i >= (DIGEST_LBLOCK_MD5 - 2))
715 for (; i < DIGEST_LBLOCK_MD5; i++)
716 X[i] = 0;
717 __rtl_digest_updateMD5 (ctx);
718 i = 0;
721 for (; i < (DIGEST_LBLOCK_MD5 - 2); i++)
722 X[i] = 0;
724 X[DIGEST_LBLOCK_MD5 - 2] = ctx->m_nL;
725 X[DIGEST_LBLOCK_MD5 - 1] = ctx->m_nH;
727 __rtl_digest_updateMD5 (ctx);
730 /*========================================================================
732 * rtl_digest_MD5 implementation.
734 *======================================================================*/
736 * rtl_digest_MD5.
738 rtlDigestError SAL_CALL rtl_digest_MD5 (
739 const void *pData, sal_uInt32 nDatLen,
740 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
742 DigestMD5_Impl digest;
743 rtlDigestError result;
745 digest.m_digest = __rtl_digest_MD5;
746 __rtl_digest_initMD5 (&(digest.m_context));
748 result = rtl_digest_update (&digest, pData, nDatLen);
749 if (result == rtl_Digest_E_None)
750 result = rtl_digest_getMD5 (&digest, pBuffer, nBufLen);
752 memset (&digest, 0, sizeof (digest));
753 return (result);
757 * rtl_digest_createMD5.
759 rtlDigest SAL_CALL rtl_digest_createMD5() SAL_THROW_EXTERN_C()
761 DigestMD5_Impl *pImpl = (DigestMD5_Impl*)NULL;
762 pImpl = RTL_DIGEST_CREATE(DigestMD5_Impl);
763 if (pImpl)
765 pImpl->m_digest = __rtl_digest_MD5;
766 __rtl_digest_initMD5 (&(pImpl->m_context));
768 return ((rtlDigest)pImpl);
772 * rtl_digest_updateMD5.
774 rtlDigestError SAL_CALL rtl_digest_updateMD5 (
775 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
776 SAL_THROW_EXTERN_C()
778 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
779 const sal_uInt8 *d = (const sal_uInt8 *)pData;
781 DigestContextMD5 *ctx;
782 sal_uInt32 len;
784 if ((pImpl == NULL) || (pData == NULL))
785 return rtl_Digest_E_Argument;
787 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
788 return rtl_Digest_E_Algorithm;
790 if (nDatLen == 0)
791 return rtl_Digest_E_None;
793 ctx = &(pImpl->m_context);
795 len = ctx->m_nL + (nDatLen << 3);
796 if (len < ctx->m_nL) ctx->m_nH += 1;
797 ctx->m_nH += (nDatLen >> 29);
798 ctx->m_nL = len;
800 if (ctx->m_nDatLen)
802 sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
803 sal_uInt32 n = DIGEST_CBLOCK_MD5 - ctx->m_nDatLen;
805 if (nDatLen < n)
807 memcpy (p, d, nDatLen);
808 ctx->m_nDatLen += nDatLen;
810 return rtl_Digest_E_None;
813 memcpy (p, d, n);
814 d += n;
815 nDatLen -= n;
817 #ifdef OSL_BIGENDIAN
818 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
819 #endif /* OSL_BIGENDIAN */
821 __rtl_digest_updateMD5 (ctx);
822 ctx->m_nDatLen = 0;
825 while (nDatLen >= DIGEST_CBLOCK_MD5)
827 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_MD5);
828 d += DIGEST_CBLOCK_MD5;
829 nDatLen -= DIGEST_CBLOCK_MD5;
831 #ifdef OSL_BIGENDIAN
832 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
833 #endif /* OSL_BIGENDIAN */
835 __rtl_digest_updateMD5 (ctx);
838 memcpy (ctx->m_pData, d, nDatLen);
839 ctx->m_nDatLen = nDatLen;
841 return rtl_Digest_E_None;
845 * rtl_digest_getMD5.
847 rtlDigestError SAL_CALL rtl_digest_getMD5 (
848 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
849 SAL_THROW_EXTERN_C()
851 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
852 sal_uInt8 *p = pBuffer;
854 DigestContextMD5 *ctx;
856 if ((pImpl == NULL) || (pBuffer == NULL))
857 return rtl_Digest_E_Argument;
859 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
860 return rtl_Digest_E_Algorithm;
862 if (!(pImpl->m_digest.m_length <= nBufLen))
863 return rtl_Digest_E_BufferSize;
865 ctx = &(pImpl->m_context);
867 __rtl_digest_endMD5 (ctx);
868 RTL_DIGEST_LTOC (ctx->m_nA, p);
869 RTL_DIGEST_LTOC (ctx->m_nB, p);
870 RTL_DIGEST_LTOC (ctx->m_nC, p);
871 RTL_DIGEST_LTOC (ctx->m_nD, p);
872 __rtl_digest_initMD5 (ctx);
874 return rtl_Digest_E_None;
878 * rtl_digest_rawMD5.
880 rtlDigestError SAL_CALL rtl_digest_rawMD5 (
881 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
882 SAL_THROW_EXTERN_C()
884 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
885 sal_uInt8 *p = pBuffer;
887 DigestContextMD5 *ctx;
889 if ((pImpl == NULL) || (pBuffer == NULL))
890 return rtl_Digest_E_Argument;
892 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
893 return rtl_Digest_E_Algorithm;
895 if (!(pImpl->m_digest.m_length <= nBufLen))
896 return rtl_Digest_E_BufferSize;
898 ctx = &(pImpl->m_context);
900 /* __rtl_digest_endMD5 (ctx); *//* not finalized */
901 RTL_DIGEST_LTOC (ctx->m_nA, p);
902 RTL_DIGEST_LTOC (ctx->m_nB, p);
903 RTL_DIGEST_LTOC (ctx->m_nC, p);
904 RTL_DIGEST_LTOC (ctx->m_nD, p);
905 __rtl_digest_initMD5 (ctx);
907 return rtl_Digest_E_None;
911 * rtl_digest_destroyMD5.
913 void SAL_CALL rtl_digest_destroyMD5 (rtlDigest Digest) SAL_THROW_EXTERN_C()
915 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
916 if (pImpl)
918 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5)
919 rtl_freeZeroMemory (pImpl, sizeof (DigestMD5_Impl));
920 else
921 rtl_freeMemory (pImpl);
925 /*========================================================================
927 * rtl_digest_(SHA|SHA1) common internals.
929 *======================================================================*/
930 #define DIGEST_CBLOCK_SHA 64
931 #define DIGEST_LBLOCK_SHA 16
933 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x);
935 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x);
936 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x);
938 struct DigestContextSHA
940 DigestSHA_update_t *m_update;
941 sal_uInt32 m_nDatLen;
942 sal_uInt32 m_pData[DIGEST_LBLOCK_SHA];
943 sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE;
944 sal_uInt32 m_nL, m_nH;
947 struct DigestSHA_Impl
949 Digest_Impl m_digest;
950 DigestContextSHA m_context;
953 static void __rtl_digest_initSHA (
954 DigestContextSHA *ctx, DigestSHA_update_t *fct);
956 static void __rtl_digest_updateSHA (DigestContextSHA *ctx);
957 static void __rtl_digest_endSHA (DigestContextSHA *ctx);
959 #define K_00_19 (sal_uInt32)0x5a827999L
960 #define K_20_39 (sal_uInt32)0x6ed9eba1L
961 #define K_40_59 (sal_uInt32)0x8f1bbcdcL
962 #define K_60_79 (sal_uInt32)0xca62c1d6L
964 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
965 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
966 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
967 #define F_60_79(b,c,d) F_20_39(b,c,d)
969 #define BODY_X(i) \
970 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
972 #define BODY_00_15(u,i,a,b,c,d,e,f) \
973 (f) = X[i]; \
974 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
975 (b) = RTL_DIGEST_ROTL((b), 30);
977 #define BODY_16_19(u,i,a,b,c,d,e,f) \
978 (f) = BODY_X((i)); \
979 (f) = X[(i)&0x0f] = (u)((f)); \
980 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
981 (b) = RTL_DIGEST_ROTL((b), 30);
983 #define BODY_20_39(u,i,a,b,c,d,e,f) \
984 (f) = BODY_X((i)); \
985 (f) = X[(i)&0x0f] = (u)((f)); \
986 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
987 (b) = RTL_DIGEST_ROTL((b), 30);
989 #define BODY_40_59(u,i,a,b,c,d,e,f) \
990 (f) = BODY_X((i)); \
991 (f) = X[(i)&0x0f] = (u)((f)); \
992 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
993 (b) = RTL_DIGEST_ROTL((b), 30);
995 #define BODY_60_79(u,i,a,b,c,d,e,f) \
996 (f) = BODY_X((i)); \
997 (f) = X[(i)&0x0f] = (u)((f)); \
998 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
999 (b) = RTL_DIGEST_ROTL((b), 30);
1002 * __rtl_digest_initSHA.
1004 static void __rtl_digest_initSHA (
1005 DigestContextSHA *ctx, DigestSHA_update_t *fct)
1007 memset (ctx, 0, sizeof (DigestContextSHA));
1008 ctx->m_update = fct;
1010 ctx->m_nA = (sal_uInt32)0x67452301L;
1011 ctx->m_nB = (sal_uInt32)0xefcdab89L;
1012 ctx->m_nC = (sal_uInt32)0x98badcfeL;
1013 ctx->m_nD = (sal_uInt32)0x10325476L;
1014 ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
1018 * __rtl_digest_updateSHA.
1020 static void __rtl_digest_updateSHA (DigestContextSHA *ctx)
1022 sal_uInt32 A, B, C, D, E, T;
1023 sal_uInt32 *X;
1025 DigestSHA_update_t *U;
1026 U = ctx->m_update;
1028 A = ctx->m_nA;
1029 B = ctx->m_nB;
1030 C = ctx->m_nC;
1031 D = ctx->m_nD;
1032 E = ctx->m_nE;
1033 X = ctx->m_pData;
1035 BODY_00_15 (U, 0, A, B, C, D, E, T);
1036 BODY_00_15 (U, 1, T, A, B, C, D, E);
1037 BODY_00_15 (U, 2, E, T, A, B, C, D);
1038 BODY_00_15 (U, 3, D, E, T, A, B, C);
1039 BODY_00_15 (U, 4, C, D, E, T, A, B);
1040 BODY_00_15 (U, 5, B, C, D, E, T, A);
1041 BODY_00_15 (U, 6, A, B, C, D, E, T);
1042 BODY_00_15 (U, 7, T, A, B, C, D, E);
1043 BODY_00_15 (U, 8, E, T, A, B, C, D);
1044 BODY_00_15 (U, 9, D, E, T, A, B, C);
1045 BODY_00_15 (U, 10, C, D, E, T, A, B);
1046 BODY_00_15 (U, 11, B, C, D, E, T, A);
1047 BODY_00_15 (U, 12, A, B, C, D, E, T);
1048 BODY_00_15 (U, 13, T, A, B, C, D, E);
1049 BODY_00_15 (U, 14, E, T, A, B, C, D);
1050 BODY_00_15 (U, 15, D, E, T, A, B, C);
1051 BODY_16_19 (U, 16, C, D, E, T, A, B);
1052 BODY_16_19 (U, 17, B, C, D, E, T, A);
1053 BODY_16_19 (U, 18, A, B, C, D, E, T);
1054 BODY_16_19 (U, 19, T, A, B, C, D, E);
1056 BODY_20_39 (U, 20, E, T, A, B, C, D);
1057 BODY_20_39 (U, 21, D, E, T, A, B, C);
1058 BODY_20_39 (U, 22, C, D, E, T, A, B);
1059 BODY_20_39 (U, 23, B, C, D, E, T, A);
1060 BODY_20_39 (U, 24, A, B, C, D, E, T);
1061 BODY_20_39 (U, 25, T, A, B, C, D, E);
1062 BODY_20_39 (U, 26, E, T, A, B, C, D);
1063 BODY_20_39 (U, 27, D, E, T, A, B, C);
1064 BODY_20_39 (U, 28, C, D, E, T, A, B);
1065 BODY_20_39 (U, 29, B, C, D, E, T, A);
1066 BODY_20_39 (U, 30, A, B, C, D, E, T);
1067 BODY_20_39 (U, 31, T, A, B, C, D, E);
1068 BODY_20_39 (U, 32, E, T, A, B, C, D);
1069 BODY_20_39 (U, 33, D, E, T, A, B, C);
1070 BODY_20_39 (U, 34, C, D, E, T, A, B);
1071 BODY_20_39 (U, 35, B, C, D, E, T, A);
1072 BODY_20_39 (U, 36, A, B, C, D, E, T);
1073 BODY_20_39 (U, 37, T, A, B, C, D, E);
1074 BODY_20_39 (U, 38, E, T, A, B, C, D);
1075 BODY_20_39 (U, 39, D, E, T, A, B, C);
1077 BODY_40_59 (U, 40, C, D, E, T, A, B);
1078 BODY_40_59 (U, 41, B, C, D, E, T, A);
1079 BODY_40_59 (U, 42, A, B, C, D, E, T);
1080 BODY_40_59 (U, 43, T, A, B, C, D, E);
1081 BODY_40_59 (U, 44, E, T, A, B, C, D);
1082 BODY_40_59 (U, 45, D, E, T, A, B, C);
1083 BODY_40_59 (U, 46, C, D, E, T, A, B);
1084 BODY_40_59 (U, 47, B, C, D, E, T, A);
1085 BODY_40_59 (U, 48, A, B, C, D, E, T);
1086 BODY_40_59 (U, 49, T, A, B, C, D, E);
1087 BODY_40_59 (U, 50, E, T, A, B, C, D);
1088 BODY_40_59 (U, 51, D, E, T, A, B, C);
1089 BODY_40_59 (U, 52, C, D, E, T, A, B);
1090 BODY_40_59 (U, 53, B, C, D, E, T, A);
1091 BODY_40_59 (U, 54, A, B, C, D, E, T);
1092 BODY_40_59 (U, 55, T, A, B, C, D, E);
1093 BODY_40_59 (U, 56, E, T, A, B, C, D);
1094 BODY_40_59 (U, 57, D, E, T, A, B, C);
1095 BODY_40_59 (U, 58, C, D, E, T, A, B);
1096 BODY_40_59 (U, 59, B, C, D, E, T, A);
1098 BODY_60_79 (U, 60, A, B, C, D, E, T);
1099 BODY_60_79 (U, 61, T, A, B, C, D, E);
1100 BODY_60_79 (U, 62, E, T, A, B, C, D);
1101 BODY_60_79 (U, 63, D, E, T, A, B, C);
1102 BODY_60_79 (U, 64, C, D, E, T, A, B);
1103 BODY_60_79 (U, 65, B, C, D, E, T, A);
1104 BODY_60_79 (U, 66, A, B, C, D, E, T);
1105 BODY_60_79 (U, 67, T, A, B, C, D, E);
1106 BODY_60_79 (U, 68, E, T, A, B, C, D);
1107 BODY_60_79 (U, 69, D, E, T, A, B, C);
1108 BODY_60_79 (U, 70, C, D, E, T, A, B);
1109 BODY_60_79 (U, 71, B, C, D, E, T, A);
1110 BODY_60_79 (U, 72, A, B, C, D, E, T);
1111 BODY_60_79 (U, 73, T, A, B, C, D, E);
1112 BODY_60_79 (U, 74, E, T, A, B, C, D);
1113 BODY_60_79 (U, 75, D, E, T, A, B, C);
1114 BODY_60_79 (U, 76, C, D, E, T, A, B);
1115 BODY_60_79 (U, 77, B, C, D, E, T, A);
1116 BODY_60_79 (U, 78, A, B, C, D, E, T);
1117 BODY_60_79 (U, 79, T, A, B, C, D, E);
1119 ctx->m_nA += E;
1120 ctx->m_nB += T;
1121 ctx->m_nC += A;
1122 ctx->m_nD += B;
1123 ctx->m_nE += C;
1127 * __rtl_digest_endSHA.
1129 static void __rtl_digest_endSHA (DigestContextSHA *ctx)
1131 static const sal_uInt8 end[4] =
1133 0x80, 0x00, 0x00, 0x00
1135 const sal_uInt8 *p = end;
1137 sal_uInt32 *X;
1138 int i;
1140 X = ctx->m_pData;
1141 i = (ctx->m_nDatLen >> 2);
1143 #ifdef OSL_BIGENDIAN
1144 __rtl_digest_swapLong (X, i + 1);
1145 #endif /* OSL_BIGENDIAN */
1147 switch (ctx->m_nDatLen & 0x03)
1149 case 1: X[i] &= 0x000000ff; break;
1150 case 2: X[i] &= 0x0000ffff; break;
1151 case 3: X[i] &= 0x00ffffff; break;
1154 switch (ctx->m_nDatLen & 0x03)
1156 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
1157 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
1158 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
1159 case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
1162 __rtl_digest_swapLong (X, i + 1);
1164 i += 1;
1166 if (i >= (DIGEST_LBLOCK_SHA - 2))
1168 for (; i < DIGEST_LBLOCK_SHA; i++)
1169 X[i] = 0;
1170 __rtl_digest_updateSHA (ctx);
1171 i = 0;
1174 for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
1175 X[i] = 0;
1177 X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
1178 X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
1180 __rtl_digest_updateSHA (ctx);
1183 /*========================================================================
1185 * rtl_digest_SHA internals.
1187 *======================================================================*/
1189 * __rtl_digest_SHA_0.
1191 static const Digest_Impl __rtl_digest_SHA_0 =
1193 rtl_Digest_AlgorithmSHA,
1194 RTL_DIGEST_LENGTH_SHA,
1196 NULL,
1197 rtl_digest_destroySHA,
1198 rtl_digest_updateSHA,
1199 rtl_digest_getSHA
1203 * __rtl_digest_updateSHA_0.
1205 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x)
1207 return x;
1210 /*========================================================================
1212 * rtl_digest_SHA implementation.
1214 *======================================================================*/
1216 * rtl_digest_SHA.
1218 rtlDigestError SAL_CALL rtl_digest_SHA (
1219 const void *pData, sal_uInt32 nDatLen,
1220 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1222 DigestSHA_Impl digest;
1223 rtlDigestError result;
1225 digest.m_digest = __rtl_digest_SHA_0;
1226 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_0);
1228 result = rtl_digest_updateSHA (&digest, pData, nDatLen);
1229 if (result == rtl_Digest_E_None)
1230 result = rtl_digest_getSHA (&digest, pBuffer, nBufLen);
1232 memset (&digest, 0, sizeof (digest));
1233 return (result);
1237 * rtl_digest_createSHA.
1239 rtlDigest SAL_CALL rtl_digest_createSHA() SAL_THROW_EXTERN_C()
1241 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1242 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1243 if (pImpl)
1245 pImpl->m_digest = __rtl_digest_SHA_0;
1246 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_0);
1248 return ((rtlDigest)pImpl);
1252 * rtl_digest_updateSHA.
1254 rtlDigestError SAL_CALL rtl_digest_updateSHA (
1255 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1256 SAL_THROW_EXTERN_C()
1258 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1259 const sal_uInt8 *d = (const sal_uInt8 *)pData;
1261 DigestContextSHA *ctx;
1262 sal_uInt32 len;
1264 if ((pImpl == NULL) || (pData == NULL))
1265 return rtl_Digest_E_Argument;
1267 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1268 return rtl_Digest_E_Algorithm;
1270 if (nDatLen == 0)
1271 return rtl_Digest_E_None;
1273 ctx = &(pImpl->m_context);
1275 len = ctx->m_nL + (nDatLen << 3);
1276 if (len < ctx->m_nL) ctx->m_nH += 1;
1277 ctx->m_nH += (nDatLen >> 29);
1278 ctx->m_nL = len;
1280 if (ctx->m_nDatLen)
1282 sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
1283 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1285 if (nDatLen < n)
1287 memcpy (p, d, nDatLen);
1288 ctx->m_nDatLen += nDatLen;
1290 return rtl_Digest_E_None;
1293 memcpy (p, d, n);
1294 d += n;
1295 nDatLen -= n;
1297 #ifndef OSL_BIGENDIAN
1298 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1299 #endif /* OSL_BIGENDIAN */
1301 __rtl_digest_updateSHA (ctx);
1302 ctx->m_nDatLen = 0;
1305 while (nDatLen >= DIGEST_CBLOCK_SHA)
1307 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1308 d += DIGEST_CBLOCK_SHA;
1309 nDatLen -= DIGEST_CBLOCK_SHA;
1311 #ifndef OSL_BIGENDIAN
1312 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1313 #endif /* OSL_BIGENDIAN */
1315 __rtl_digest_updateSHA (ctx);
1318 memcpy (ctx->m_pData, d, nDatLen);
1319 ctx->m_nDatLen = nDatLen;
1321 return rtl_Digest_E_None;
1325 * rtl_digest_getSHA.
1327 rtlDigestError SAL_CALL rtl_digest_getSHA (
1328 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1329 SAL_THROW_EXTERN_C()
1331 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1332 sal_uInt8 *p = pBuffer;
1334 DigestContextSHA *ctx;
1336 if ((pImpl == NULL) || (pBuffer == NULL))
1337 return rtl_Digest_E_Argument;
1339 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1340 return rtl_Digest_E_Algorithm;
1342 if (!(pImpl->m_digest.m_length <= nBufLen))
1343 return rtl_Digest_E_BufferSize;
1345 ctx = &(pImpl->m_context);
1347 __rtl_digest_endSHA (ctx);
1348 RTL_DIGEST_HTONL (ctx->m_nA, p);
1349 RTL_DIGEST_HTONL (ctx->m_nB, p);
1350 RTL_DIGEST_HTONL (ctx->m_nC, p);
1351 RTL_DIGEST_HTONL (ctx->m_nD, p);
1352 RTL_DIGEST_HTONL (ctx->m_nE, p);
1353 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_0);
1355 return rtl_Digest_E_None;
1359 * rtl_digest_destroySHA.
1361 void SAL_CALL rtl_digest_destroySHA (rtlDigest Digest) SAL_THROW_EXTERN_C()
1363 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1364 if (pImpl)
1366 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA)
1367 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1368 else
1369 rtl_freeMemory (pImpl);
1373 /*========================================================================
1375 * rtl_digest_SHA1 internals.
1377 *======================================================================*/
1379 * __rtl_digest_SHA_1.
1381 static const Digest_Impl __rtl_digest_SHA_1 =
1383 rtl_Digest_AlgorithmSHA1,
1384 RTL_DIGEST_LENGTH_SHA1,
1386 NULL,
1387 rtl_digest_destroySHA1,
1388 rtl_digest_updateSHA1,
1389 rtl_digest_getSHA1
1393 * __rtl_digest_updateSHA_1.
1395 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
1397 return RTL_DIGEST_ROTL (x, 1);
1400 /*========================================================================
1402 * rtl_digest_SHA1 implementation.
1404 *======================================================================*/
1406 * rtl_digest_SHA1.
1408 rtlDigestError SAL_CALL rtl_digest_SHA1 (
1409 const void *pData, sal_uInt32 nDatLen,
1410 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1412 DigestSHA_Impl digest;
1413 rtlDigestError result;
1415 digest.m_digest = __rtl_digest_SHA_1;
1416 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
1418 result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
1419 if (result == rtl_Digest_E_None)
1420 result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
1422 memset (&digest, 0, sizeof (digest));
1423 return (result);
1427 * rtl_digest_createSHA1.
1429 rtlDigest SAL_CALL rtl_digest_createSHA1() SAL_THROW_EXTERN_C()
1431 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1432 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1433 if (pImpl)
1435 pImpl->m_digest = __rtl_digest_SHA_1;
1436 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1438 return ((rtlDigest)pImpl);
1442 * rtl_digest_updateSHA1.
1444 rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
1445 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1446 SAL_THROW_EXTERN_C()
1448 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1449 const sal_uInt8 *d = (const sal_uInt8 *)pData;
1451 DigestContextSHA *ctx;
1452 sal_uInt32 len;
1454 if ((pImpl == NULL) || (pData == NULL))
1455 return rtl_Digest_E_Argument;
1457 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1458 return rtl_Digest_E_Algorithm;
1460 if (nDatLen == 0)
1461 return rtl_Digest_E_None;
1463 ctx = &(pImpl->m_context);
1465 len = ctx->m_nL + (nDatLen << 3);
1466 if (len < ctx->m_nL) ctx->m_nH += 1;
1467 ctx->m_nH += (nDatLen >> 29);
1468 ctx->m_nL = len;
1470 if (ctx->m_nDatLen)
1472 sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
1473 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1475 if (nDatLen < n)
1477 memcpy (p, d, nDatLen);
1478 ctx->m_nDatLen += nDatLen;
1480 return rtl_Digest_E_None;
1483 memcpy (p, d, n);
1484 d += n;
1485 nDatLen -= n;
1487 #ifndef OSL_BIGENDIAN
1488 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1489 #endif /* OSL_BIGENDIAN */
1491 __rtl_digest_updateSHA (ctx);
1492 ctx->m_nDatLen = 0;
1495 while (nDatLen >= DIGEST_CBLOCK_SHA)
1497 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1498 d += DIGEST_CBLOCK_SHA;
1499 nDatLen -= DIGEST_CBLOCK_SHA;
1501 #ifndef OSL_BIGENDIAN
1502 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1503 #endif /* OSL_BIGENDIAN */
1505 __rtl_digest_updateSHA (ctx);
1508 memcpy (ctx->m_pData, d, nDatLen);
1509 ctx->m_nDatLen = nDatLen;
1511 return rtl_Digest_E_None;
1515 * rtl_digest_getSHA1.
1517 rtlDigestError SAL_CALL rtl_digest_getSHA1 (
1518 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1519 SAL_THROW_EXTERN_C()
1521 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1522 sal_uInt8 *p = pBuffer;
1524 DigestContextSHA *ctx;
1526 if ((pImpl == NULL) || (pBuffer == NULL))
1527 return rtl_Digest_E_Argument;
1529 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1530 return rtl_Digest_E_Algorithm;
1532 if (!(pImpl->m_digest.m_length <= nBufLen))
1533 return rtl_Digest_E_BufferSize;
1535 ctx = &(pImpl->m_context);
1537 __rtl_digest_endSHA (ctx);
1538 RTL_DIGEST_HTONL (ctx->m_nA, p);
1539 RTL_DIGEST_HTONL (ctx->m_nB, p);
1540 RTL_DIGEST_HTONL (ctx->m_nC, p);
1541 RTL_DIGEST_HTONL (ctx->m_nD, p);
1542 RTL_DIGEST_HTONL (ctx->m_nE, p);
1543 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
1545 return rtl_Digest_E_None;
1549 * rtl_digest_destroySHA1.
1551 void SAL_CALL rtl_digest_destroySHA1 (rtlDigest Digest) SAL_THROW_EXTERN_C()
1553 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1554 if (pImpl)
1556 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
1557 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1558 else
1559 rtl_freeMemory (pImpl);
1563 /*========================================================================
1565 * rtl_digest_HMAC_MD5 internals.
1567 *======================================================================*/
1568 #define DIGEST_CBLOCK_HMAC_MD5 64
1570 struct ContextHMAC_MD5
1572 DigestMD5_Impl m_hash;
1573 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_MD5];
1576 struct DigestHMAC_MD5_Impl
1578 Digest_Impl m_digest;
1579 ContextHMAC_MD5 m_context;
1582 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx);
1583 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1584 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1587 * __rtl_digest_HMAC_MD5.
1589 static const Digest_Impl __rtl_digest_HMAC_MD5 =
1591 rtl_Digest_AlgorithmHMAC_MD5,
1592 RTL_DIGEST_LENGTH_MD5,
1594 rtl_digest_initHMAC_MD5,
1595 rtl_digest_destroyHMAC_MD5,
1596 rtl_digest_updateHMAC_MD5,
1597 rtl_digest_getHMAC_MD5
1601 * __rtl_digest_initHMAC_MD5.
1603 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx)
1605 DigestMD5_Impl *pImpl = &(ctx->m_hash);
1607 pImpl->m_digest = __rtl_digest_MD5;
1608 __rtl_digest_initMD5 (&(pImpl->m_context));
1610 memset (ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_MD5);
1614 * __rtl_digest_ipadHMAC_MD5.
1616 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1618 sal_uInt32 i;
1620 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1621 ctx->m_opad[i] ^= 0x36;
1622 rtl_digest_updateMD5 (
1623 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1624 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1625 ctx->m_opad[i] ^= 0x36;
1629 * __rtl_digest_opadHMAC_MD5.
1631 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1633 sal_uInt32 i;
1635 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1636 ctx->m_opad[i] ^= 0x5c;
1639 /*========================================================================
1641 * rtl_digest_HMAC_MD5 implementation.
1643 *======================================================================*/
1645 * rtl_digest_HMAC_MD5.
1647 rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
1648 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1649 const void *pData, sal_uInt32 nDatLen,
1650 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1652 DigestHMAC_MD5_Impl digest;
1653 rtlDigestError result;
1655 digest.m_digest = __rtl_digest_HMAC_MD5;
1657 result = rtl_digest_initHMAC_MD5 (&digest, pKeyData, nKeyLen);
1658 if (result == rtl_Digest_E_None)
1660 result = rtl_digest_updateHMAC_MD5 (&digest, pData, nDatLen);
1661 if (result == rtl_Digest_E_None)
1662 result = rtl_digest_getHMAC_MD5 (&digest, pBuffer, nBufLen);
1665 memset (&digest, 0, sizeof (digest));
1666 return (result);
1670 * rtl_digest_createHMAC_MD5.
1672 rtlDigest SAL_CALL rtl_digest_createHMAC_MD5() SAL_THROW_EXTERN_C()
1674 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)NULL;
1675 pImpl = RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl);
1676 if (pImpl)
1678 pImpl->m_digest = __rtl_digest_HMAC_MD5;
1679 __rtl_digest_initHMAC_MD5 (&(pImpl->m_context));
1681 return ((rtlDigest)pImpl);
1685 * rtl_digest_initHMAC_MD5.
1687 rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
1688 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1689 SAL_THROW_EXTERN_C()
1691 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1692 ContextHMAC_MD5 *ctx;
1694 if ((pImpl == NULL) || (pKeyData == NULL))
1695 return rtl_Digest_E_Argument;
1697 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1698 return rtl_Digest_E_Algorithm;
1700 ctx = &(pImpl->m_context);
1701 __rtl_digest_initHMAC_MD5 (ctx);
1703 if (nKeyLen > DIGEST_CBLOCK_HMAC_MD5)
1705 /* Initialize 'opad' with hashed 'KeyData' */
1706 rtl_digest_updateMD5 (
1707 &(ctx->m_hash), pKeyData, nKeyLen);
1708 rtl_digest_getMD5 (
1709 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_MD5);
1711 else
1713 /* Initialize 'opad' with plain 'KeyData' */
1714 memcpy (ctx->m_opad, pKeyData, nKeyLen);
1717 __rtl_digest_ipadHMAC_MD5 (ctx);
1718 __rtl_digest_opadHMAC_MD5 (ctx);
1720 return rtl_Digest_E_None;
1724 * rtl_digest_updateHMAC_MD5.
1726 rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
1727 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1728 SAL_THROW_EXTERN_C()
1730 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1731 ContextHMAC_MD5 *ctx;
1733 if ((pImpl == NULL) || (pData == NULL))
1734 return rtl_Digest_E_Argument;
1736 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1737 return rtl_Digest_E_Algorithm;
1739 ctx = &(pImpl->m_context);
1740 rtl_digest_updateMD5 (&(ctx->m_hash), pData, nDatLen);
1742 return rtl_Digest_E_None;
1746 * rtl_digest_getHMAC_MD5.
1748 rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
1749 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1750 SAL_THROW_EXTERN_C()
1752 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1753 ContextHMAC_MD5 *ctx;
1755 if ((pImpl == NULL) || (pBuffer == NULL))
1756 return rtl_Digest_E_Argument;
1758 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1759 return rtl_Digest_E_Algorithm;
1761 if (!(pImpl->m_digest.m_length <= nBufLen))
1762 return rtl_Digest_E_BufferSize;
1764 nBufLen = pImpl->m_digest.m_length;
1766 ctx = &(pImpl->m_context);
1767 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1769 rtl_digest_updateMD5 (&(ctx->m_hash), ctx->m_opad, 64);
1770 rtl_digest_updateMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1771 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1773 __rtl_digest_opadHMAC_MD5 (ctx);
1774 __rtl_digest_ipadHMAC_MD5 (ctx);
1775 __rtl_digest_opadHMAC_MD5 (ctx);
1777 return rtl_Digest_E_None;
1781 * rtl_digest_destroyHMAC_MD5.
1783 void SAL_CALL rtl_digest_destroyHMAC_MD5 (rtlDigest Digest) SAL_THROW_EXTERN_C()
1785 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1786 if (pImpl)
1788 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5)
1789 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_MD5_Impl));
1790 else
1791 rtl_freeMemory (pImpl);
1795 /*========================================================================
1797 * rtl_digest_HMAC_SHA1 internals.
1799 *======================================================================*/
1800 #define DIGEST_CBLOCK_HMAC_SHA1 64
1802 struct ContextHMAC_SHA1
1804 DigestSHA_Impl m_hash;
1805 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_SHA1];
1808 struct DigestHMAC_SHA1_Impl
1810 Digest_Impl m_digest;
1811 ContextHMAC_SHA1 m_context;
1814 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1815 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1816 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1819 * __rtl_digest_HMAC_SHA1.
1821 static const Digest_Impl __rtl_digest_HMAC_SHA1 =
1823 rtl_Digest_AlgorithmHMAC_SHA1,
1824 RTL_DIGEST_LENGTH_SHA1,
1826 rtl_digest_initHMAC_SHA1,
1827 rtl_digest_destroyHMAC_SHA1,
1828 rtl_digest_updateHMAC_SHA1,
1829 rtl_digest_getHMAC_SHA1
1833 * __rtl_digest_initHMAC_SHA1.
1835 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1837 DigestSHA_Impl *pImpl = &(ctx->m_hash);
1839 pImpl->m_digest = __rtl_digest_SHA_1;
1840 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1842 memset (ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_SHA1);
1846 * __rtl_digest_ipadHMAC_SHA1.
1848 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1850 sal_uInt32 i;
1852 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1853 ctx->m_opad[i] ^= 0x36;
1854 rtl_digest_updateSHA1 (
1855 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1856 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1857 ctx->m_opad[i] ^= 0x36;
1861 * __rtl_digest_opadHMAC_SHA1.
1863 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1865 sal_uInt32 i;
1867 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1868 ctx->m_opad[i] ^= 0x5c;
1871 /*========================================================================
1873 * rtl_digest_HMAC_SHA1 implementation.
1875 *======================================================================*/
1877 * rtl_digest_HMAC_SHA1.
1879 rtlDigestError SAL_CALL rtl_digest_HMAC_SHA1 (
1880 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1881 const void *pData, sal_uInt32 nDatLen,
1882 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1884 DigestHMAC_SHA1_Impl digest;
1885 rtlDigestError result;
1887 digest.m_digest = __rtl_digest_HMAC_SHA1;
1889 result = rtl_digest_initHMAC_SHA1 (&digest, pKeyData, nKeyLen);
1890 if (result == rtl_Digest_E_None)
1892 result = rtl_digest_updateHMAC_SHA1 (&digest, pData, nDatLen);
1893 if (result == rtl_Digest_E_None)
1894 result = rtl_digest_getHMAC_SHA1 (&digest, pBuffer, nBufLen);
1897 memset (&digest, 0, sizeof (digest));
1898 return (result);
1902 * rtl_digest_createHMAC_SHA1.
1904 rtlDigest SAL_CALL rtl_digest_createHMAC_SHA1() SAL_THROW_EXTERN_C()
1906 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)NULL;
1907 pImpl = RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl);
1908 if (pImpl)
1910 pImpl->m_digest = __rtl_digest_HMAC_SHA1;
1911 __rtl_digest_initHMAC_SHA1 (&(pImpl->m_context));
1913 return ((rtlDigest)pImpl);
1917 * rtl_digest_initHMAC_SHA1.
1919 rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
1920 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1921 SAL_THROW_EXTERN_C()
1923 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1924 ContextHMAC_SHA1 *ctx;
1926 if ((pImpl == NULL) || (pKeyData == NULL))
1927 return rtl_Digest_E_Argument;
1929 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1930 return rtl_Digest_E_Algorithm;
1932 ctx = &(pImpl->m_context);
1933 __rtl_digest_initHMAC_SHA1 (ctx);
1935 if (nKeyLen > DIGEST_CBLOCK_HMAC_SHA1)
1937 /* Initialize 'opad' with hashed 'KeyData' */
1938 rtl_digest_updateSHA1 (
1939 &(ctx->m_hash), pKeyData, nKeyLen);
1940 rtl_digest_getSHA1 (
1941 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_SHA1);
1943 else
1945 /* Initialize 'opad' with plain 'KeyData' */
1946 memcpy (ctx->m_opad, pKeyData, nKeyLen);
1949 __rtl_digest_ipadHMAC_SHA1 (ctx);
1950 __rtl_digest_opadHMAC_SHA1 (ctx);
1952 return rtl_Digest_E_None;
1956 * rtl_digest_updateHMAC_SHA1.
1958 rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
1959 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1960 SAL_THROW_EXTERN_C()
1962 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1963 ContextHMAC_SHA1 *ctx;
1965 if ((pImpl == NULL) || (pData == NULL))
1966 return rtl_Digest_E_Argument;
1968 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1969 return rtl_Digest_E_Algorithm;
1971 ctx = &(pImpl->m_context);
1972 rtl_digest_updateSHA1 (&(ctx->m_hash), pData, nDatLen);
1974 return rtl_Digest_E_None;
1978 * rtl_digest_getHMAC_SHA1.
1980 rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
1981 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1982 SAL_THROW_EXTERN_C()
1984 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1985 ContextHMAC_SHA1 *ctx;
1987 if ((pImpl == NULL) || (pBuffer == NULL))
1988 return rtl_Digest_E_Argument;
1990 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1991 return rtl_Digest_E_Algorithm;
1993 if (!(pImpl->m_digest.m_length <= nBufLen))
1994 return rtl_Digest_E_BufferSize;
1996 nBufLen = pImpl->m_digest.m_length;
1998 ctx = &(pImpl->m_context);
1999 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2001 rtl_digest_updateSHA1 (&(ctx->m_hash), ctx->m_opad, sizeof(ctx->m_opad));
2002 rtl_digest_updateSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2003 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2005 __rtl_digest_opadHMAC_SHA1 (ctx);
2006 __rtl_digest_ipadHMAC_SHA1 (ctx);
2007 __rtl_digest_opadHMAC_SHA1 (ctx);
2009 return rtl_Digest_E_None;
2013 * rtl_digest_destroyHMAC_SHA1.
2015 void SAL_CALL rtl_digest_destroyHMAC_SHA1 (rtlDigest Digest)
2016 SAL_THROW_EXTERN_C()
2018 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
2019 if (pImpl)
2021 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1)
2022 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_SHA1_Impl));
2023 else
2024 rtl_freeMemory (pImpl);
2028 /*========================================================================
2030 * rtl_digest_PBKDF2 internals.
2032 *======================================================================*/
2033 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
2036 * __rtl_digest_updatePBKDF2.
2038 static void __rtl_digest_updatePBKDF2 (
2039 rtlDigest hDigest,
2040 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2],
2041 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2042 sal_uInt32 nCount, sal_uInt32 nIndex)
2044 /* T_i = F (P, S, c, i) */
2045 sal_uInt8 U[DIGEST_CBLOCK_PBKDF2];
2046 sal_uInt32 i, k;
2048 /* U_(1) = PRF (P, S || INDEX) */
2049 rtl_digest_updateHMAC_SHA1 (hDigest, pSaltData, nSaltLen);
2050 rtl_digest_updateHMAC_SHA1 (hDigest, &nIndex, sizeof(nIndex));
2051 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2053 /* T = U_(1) */
2054 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] = U[k];
2056 /* T ^= U_(2) ^ ... ^ U_(c) */
2057 for (i = 1; i < nCount; i++)
2059 /* U_(i) = PRF (P, U_(i-1)) */
2060 rtl_digest_updateHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2061 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2063 /* T ^= U_(i) */
2064 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] ^= U[k];
2067 memset (U, 0, DIGEST_CBLOCK_PBKDF2);
2070 /*========================================================================
2072 * rtl_digest_PBKDF2 implementation.
2074 *======================================================================*/
2076 * rtl_digest_PBKDF2.
2078 rtlDigestError SAL_CALL rtl_digest_PBKDF2 (
2079 sal_uInt8 *pKeyData , sal_uInt32 nKeyLen,
2080 const sal_uInt8 *pPassData, sal_uInt32 nPassLen,
2081 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2082 sal_uInt32 nCount) SAL_THROW_EXTERN_C()
2084 DigestHMAC_SHA1_Impl digest;
2085 sal_uInt32 i = 1;
2087 if ((pKeyData == NULL) || (pPassData == NULL) || (pSaltData == NULL))
2088 return rtl_Digest_E_Argument;
2090 digest.m_digest = __rtl_digest_HMAC_SHA1;
2091 rtl_digest_initHMAC_SHA1 (&digest, pPassData, nPassLen);
2093 /* DK = T_(1) || T_(2) || ... || T_(l) */
2094 while (nKeyLen >= DIGEST_CBLOCK_PBKDF2)
2096 /* T_(i) = F (P, S, c, i); DK ||= T_(i) */
2097 __rtl_digest_updatePBKDF2 (
2098 &digest, pKeyData,
2099 pSaltData, nSaltLen,
2100 nCount, OSL_NETDWORD(i));
2102 /* Next 'KeyData' block */
2103 pKeyData += DIGEST_CBLOCK_PBKDF2;
2104 nKeyLen -= DIGEST_CBLOCK_PBKDF2;
2105 i += 1;
2107 if (nKeyLen > 0)
2109 /* Last 'KeyData' block */
2110 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2];
2112 /* T_i = F (P, S, c, i) */
2113 __rtl_digest_updatePBKDF2 (
2114 &digest, T,
2115 pSaltData, nSaltLen,
2116 nCount, OSL_NETDWORD(i));
2118 /* DK ||= T_(i) */
2119 memcpy (pKeyData, T, nKeyLen);
2120 memset (T, 0, DIGEST_CBLOCK_PBKDF2);
2123 memset (&digest, 0, sizeof (digest));
2124 return rtl_Digest_E_None;
2127 /*========================================================================
2129 * The End.
2131 *======================================================================*/
2133 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */