update credits
[LibreOffice.git] / sal / rtl / digest.cxx
blobd8f4c7119142e9f76023197afa9d2a7757bce4d8
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 <osl/endian.h>
24 #include <rtl/alloc.h>
25 #include <rtl/digest.h>
27 /*========================================================================
29 * rtlDigest internals.
31 *======================================================================*/
32 #define RTL_DIGEST_CREATE(T) (static_cast<T*>(rtl_allocateZeroMemory(sizeof(T))))
34 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
36 #define RTL_DIGEST_HTONL(l,c) \
37 (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
38 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
39 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
40 *((c)++) = (sal_uInt8)(((l) ) & 0xff))
42 #define RTL_DIGEST_LTOC(l,c) \
43 (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \
44 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
45 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
46 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
48 typedef rtlDigestError (SAL_CALL Digest_init_t) (
49 void *ctx, const sal_uInt8 *Data, sal_uInt32 DatLen);
51 typedef void (SAL_CALL Digest_delete_t) (void *ctx);
53 typedef rtlDigestError (SAL_CALL Digest_update_t) (
54 void *ctx, const void *Data, sal_uInt32 DatLen);
56 typedef rtlDigestError (SAL_CALL Digest_get_t) (
57 void *ctx, sal_uInt8 *Buffer, sal_uInt32 BufLen);
59 struct Digest_Impl
61 rtlDigestAlgorithm m_algorithm;
62 sal_uInt32 m_length;
64 Digest_init_t *m_init;
65 Digest_delete_t *m_delete;
66 Digest_update_t *m_update;
67 Digest_get_t *m_get;
71 * __rtl_digest_swapLong.
73 static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
75 sal_uInt32 *X;
76 int i, n;
78 X = pData;
79 n = nDatLen;
81 for (i = 0; i < n; i++)
82 X[i] = OSL_SWAPDWORD(X[i]);
85 /*========================================================================
87 * rtlDigest implementation.
89 *======================================================================*/
91 * rtl_digest_create.
93 rtlDigest SAL_CALL rtl_digest_create (rtlDigestAlgorithm Algorithm)
94 SAL_THROW_EXTERN_C()
96 rtlDigest Digest = (rtlDigest)NULL;
97 switch (Algorithm)
99 case rtl_Digest_AlgorithmMD2:
100 Digest = rtl_digest_createMD2();
101 break;
103 case rtl_Digest_AlgorithmMD5:
104 Digest = rtl_digest_createMD5();
105 break;
107 case rtl_Digest_AlgorithmSHA:
108 Digest = rtl_digest_createSHA();
109 break;
111 case rtl_Digest_AlgorithmSHA1:
112 Digest = rtl_digest_createSHA1();
113 break;
115 case rtl_Digest_AlgorithmHMAC_MD5:
116 Digest = rtl_digest_createHMAC_MD5();
117 break;
119 case rtl_Digest_AlgorithmHMAC_SHA1:
120 Digest = rtl_digest_createHMAC_SHA1();
121 break;
123 default: /* rtl_Digest_AlgorithmInvalid */
124 break;
126 return Digest;
130 * rtl_digest_queryAlgorithm.
132 rtlDigestAlgorithm SAL_CALL rtl_digest_queryAlgorithm (rtlDigest Digest)
133 SAL_THROW_EXTERN_C()
135 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
136 if (pImpl)
137 return pImpl->m_algorithm;
138 else
139 return rtl_Digest_AlgorithmInvalid;
143 * rtl_digest_queryLength.
145 sal_uInt32 SAL_CALL rtl_digest_queryLength (rtlDigest Digest)
146 SAL_THROW_EXTERN_C()
148 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
149 if (pImpl)
150 return pImpl->m_length;
151 else
152 return 0;
156 * rtl_digest_init.
158 rtlDigestError SAL_CALL rtl_digest_init (
159 rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
160 SAL_THROW_EXTERN_C()
162 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
163 if (pImpl)
165 if (pImpl->m_init)
166 return pImpl->m_init (Digest, pData, nDatLen);
167 else
168 return rtl_Digest_E_None;
170 return rtl_Digest_E_Argument;
174 * rtl_digest_update.
176 rtlDigestError SAL_CALL rtl_digest_update (
177 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
178 SAL_THROW_EXTERN_C()
180 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
181 if (pImpl && pImpl->m_update)
182 return pImpl->m_update (Digest, pData, nDatLen);
183 else
184 return rtl_Digest_E_Argument;
188 * rtl_digest_get.
190 rtlDigestError SAL_CALL rtl_digest_get (
191 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
192 SAL_THROW_EXTERN_C()
194 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
195 if (pImpl && pImpl->m_get)
196 return pImpl->m_get (Digest, pBuffer, nBufLen);
197 else
198 return rtl_Digest_E_Argument;
202 * rtl_digest_destroy.
204 void SAL_CALL rtl_digest_destroy (rtlDigest Digest) SAL_THROW_EXTERN_C()
206 Digest_Impl *pImpl = static_cast<Digest_Impl *>(Digest);
207 if (pImpl && pImpl->m_delete)
208 pImpl->m_delete (Digest);
211 /*========================================================================
213 * rtl_digest_MD2 internals.
215 *======================================================================*/
216 #define DIGEST_CBLOCK_MD2 16
217 #define DIGEST_LBLOCK_MD2 16
219 struct DigestContextMD2
221 sal_uInt32 m_nDatLen;
222 sal_uInt8 m_pData[DIGEST_CBLOCK_MD2];
223 sal_uInt32 m_state[DIGEST_LBLOCK_MD2];
224 sal_uInt32 m_chksum[DIGEST_LBLOCK_MD2];
227 struct DigestMD2_Impl
229 Digest_Impl m_digest;
230 DigestContextMD2 m_context;
233 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx);
234 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx);
235 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx);
237 static const sal_uInt32 S[256] =
239 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
240 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
241 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
242 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
243 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
244 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
245 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
246 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
247 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
248 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
249 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
250 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
251 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
252 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
253 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
254 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
255 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
256 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
257 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
258 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
259 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
260 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
261 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
262 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
263 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
264 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
265 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
266 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
267 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
268 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
269 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
270 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
274 * __rtl_digest_MD2.
276 static const Digest_Impl __rtl_digest_MD2 =
278 rtl_Digest_AlgorithmMD2,
279 RTL_DIGEST_LENGTH_MD2,
281 NULL,
282 rtl_digest_destroyMD2,
283 rtl_digest_updateMD2,
284 rtl_digest_getMD2
288 * __rtl_digest_initMD2.
290 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx)
292 memset (ctx, 0, sizeof (DigestContextMD2));
296 * __rtl_digest_updateMD2.
298 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx)
300 sal_uInt8 *X;
301 sal_uInt32 *sp1, *sp2;
302 sal_uInt32 i, k, t;
304 sal_uInt32 state[48];
306 X = ctx->m_pData;
307 sp1 = ctx->m_state;
308 sp2 = ctx->m_chksum;
310 k = sp2[DIGEST_LBLOCK_MD2 - 1];
311 for (i = 0; i < 16; i++)
313 state[i + 0] = sp1[i];
314 state[i + 16] = t = X[i];
315 state[i + 32] = t ^ sp1[i];
316 k = sp2[i] ^= S[t^k];
319 t = 0;
320 for (i = 0; i < 18; i++)
322 for (k = 0; k < 48; k += 8)
324 t = state[k + 0] ^= S[t];
325 t = state[k + 1] ^= S[t];
326 t = state[k + 2] ^= S[t];
327 t = state[k + 3] ^= S[t];
328 t = state[k + 4] ^= S[t];
329 t = state[k + 5] ^= S[t];
330 t = state[k + 6] ^= S[t];
331 t = state[k + 7] ^= S[t];
333 t = ((t + i) & 0xff);
336 memcpy (sp1, state, 16 * sizeof(sal_uInt32));
337 memset (state, 0, 48 * sizeof(sal_uInt32));
341 * __rtl_digest_endMD2.
343 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx)
345 sal_uInt8 *X;
346 sal_uInt32 *C;
347 sal_uInt32 i, n;
349 X = ctx->m_pData;
350 C = ctx->m_chksum;
351 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
353 for (i = ctx->m_nDatLen; i < DIGEST_CBLOCK_MD2; i++)
354 X[i] = (sal_uInt8)(n & 0xff);
355 __rtl_digest_updateMD2 (ctx);
357 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
358 X[i] = (sal_uInt8)(C[i] & 0xff);
359 __rtl_digest_updateMD2 (ctx);
362 /*========================================================================
364 * rtl_digest_MD2 implementation.
366 *======================================================================*/
368 * rtl_digest_MD2.
370 rtlDigestError SAL_CALL rtl_digest_MD2 (
371 const void *pData, sal_uInt32 nDatLen,
372 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
374 DigestMD2_Impl digest;
375 rtlDigestError result;
377 digest.m_digest = __rtl_digest_MD2;
378 __rtl_digest_initMD2 (&(digest.m_context));
380 result = rtl_digest_updateMD2 (&digest, pData, nDatLen);
381 if (result == rtl_Digest_E_None)
382 result = rtl_digest_getMD2 (&digest, pBuffer, nBufLen);
384 memset (&digest, 0, sizeof (digest));
385 return result;
389 * rtl_digest_createMD2.
391 rtlDigest SAL_CALL rtl_digest_createMD2() SAL_THROW_EXTERN_C()
393 DigestMD2_Impl *pImpl = (DigestMD2_Impl*)NULL;
394 pImpl = RTL_DIGEST_CREATE(DigestMD2_Impl);
395 if (pImpl)
397 pImpl->m_digest = __rtl_digest_MD2;
398 __rtl_digest_initMD2 (&(pImpl->m_context));
400 return (rtlDigest)pImpl;
404 * rtl_digest_updateMD2.
406 rtlDigestError SAL_CALL rtl_digest_updateMD2 (
407 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
408 SAL_THROW_EXTERN_C()
410 DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
411 const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
413 DigestContextMD2 *ctx;
415 if ((pImpl == NULL) || (pData == NULL))
416 return rtl_Digest_E_Argument;
418 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
419 return rtl_Digest_E_Algorithm;
421 if (nDatLen == 0)
422 return rtl_Digest_E_None;
424 ctx = &(pImpl->m_context);
426 if (ctx->m_nDatLen)
428 sal_uInt8 *p = ctx->m_pData + ctx->m_nDatLen;
429 sal_uInt32 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
431 if (nDatLen < n)
433 memcpy (p, d, nDatLen);
434 ctx->m_nDatLen += nDatLen;
436 return rtl_Digest_E_None;
439 memcpy (p, d, n);
440 d += n;
441 nDatLen -= n;
443 __rtl_digest_updateMD2 (ctx);
444 ctx->m_nDatLen = 0;
447 while (nDatLen >= DIGEST_CBLOCK_MD2)
449 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_MD2);
450 d += DIGEST_CBLOCK_MD2;
451 nDatLen -= DIGEST_CBLOCK_MD2;
453 __rtl_digest_updateMD2 (ctx);
456 memcpy (ctx->m_pData, d, nDatLen);
457 ctx->m_nDatLen = nDatLen;
459 return rtl_Digest_E_None;
463 * rtl_digest_getMD2.
465 rtlDigestError SAL_CALL rtl_digest_getMD2 (
466 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
467 SAL_THROW_EXTERN_C()
469 DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
470 sal_uInt32 i;
472 DigestContextMD2 *ctx;
474 if ((pImpl == NULL) || (pBuffer == NULL))
475 return rtl_Digest_E_Argument;
477 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
478 return rtl_Digest_E_Algorithm;
480 if (!(pImpl->m_digest.m_length <= nBufLen))
481 return rtl_Digest_E_BufferSize;
483 ctx = &(pImpl->m_context);
485 __rtl_digest_endMD2 (ctx);
486 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
487 pBuffer[i] = (sal_uInt8)(ctx->m_state[i] & 0xff);
488 __rtl_digest_initMD2 (ctx);
490 return rtl_Digest_E_None;
494 * rtl_digest_destroyMD2.
496 void SAL_CALL rtl_digest_destroyMD2 (rtlDigest Digest) SAL_THROW_EXTERN_C()
498 DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
499 if (pImpl)
501 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2)
502 rtl_freeZeroMemory (pImpl, sizeof (DigestMD2_Impl));
503 else
504 rtl_freeMemory (pImpl);
508 /*========================================================================
510 * rtl_digest_MD5 internals.
512 *======================================================================*/
513 #define DIGEST_CBLOCK_MD5 64
514 #define DIGEST_LBLOCK_MD5 16
516 struct DigestContextMD5
518 sal_uInt32 m_nDatLen;
519 sal_uInt32 m_pData[DIGEST_LBLOCK_MD5];
520 sal_uInt32 m_nA, m_nB, m_nC, m_nD;
521 sal_uInt32 m_nL, m_nH;
524 struct DigestMD5_Impl
526 Digest_Impl m_digest;
527 DigestContextMD5 m_context;
530 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx);
531 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx);
532 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx);
534 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
535 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
536 #define H(x,y,z) ((x) ^ (y) ^ (z))
537 #define I(x,y,z) (((x) | (~(z))) ^ (y))
539 #define R0(a,b,c,d,k,s,t) { \
540 a += ((k) + (t) + F((b), (c), (d))); \
541 a = RTL_DIGEST_ROTL(a, s); \
542 a += b; }
544 #define R1(a,b,c,d,k,s,t) { \
545 a += ((k) + (t) + G((b), (c), (d))); \
546 a = RTL_DIGEST_ROTL(a, s); \
547 a += b; }
549 #define R2(a,b,c,d,k,s,t) { \
550 a += ((k) + (t) + H((b), (c), (d))); \
551 a = RTL_DIGEST_ROTL(a, s); \
552 a += b; }
554 #define R3(a,b,c,d,k,s,t) { \
555 a += ((k) + (t) + I((b), (c), (d))); \
556 a = RTL_DIGEST_ROTL(a, s); \
557 a += b; }
560 * __rtl_digest_MD5.
562 static const Digest_Impl __rtl_digest_MD5 =
564 rtl_Digest_AlgorithmMD5,
565 RTL_DIGEST_LENGTH_MD5,
567 NULL,
568 rtl_digest_destroyMD5,
569 rtl_digest_updateMD5,
570 rtl_digest_getMD5
574 * __rtl_digest_initMD5.
576 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx)
578 memset (ctx, 0, sizeof (DigestContextMD5));
580 ctx->m_nA = (sal_uInt32)0x67452301L;
581 ctx->m_nB = (sal_uInt32)0xefcdab89L;
582 ctx->m_nC = (sal_uInt32)0x98badcfeL;
583 ctx->m_nD = (sal_uInt32)0x10325476L;
587 * __rtl_digest_updateMD5.
589 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx)
591 sal_uInt32 A, B, C, D;
592 sal_uInt32 *X;
594 A = ctx->m_nA;
595 B = ctx->m_nB;
596 C = ctx->m_nC;
597 D = ctx->m_nD;
598 X = ctx->m_pData;
600 R0 (A, B, C, D, X[ 0], 7, 0xd76aa478L);
601 R0 (D, A, B, C, X[ 1], 12, 0xe8c7b756L);
602 R0 (C, D, A, B, X[ 2], 17, 0x242070dbL);
603 R0 (B, C, D, A, X[ 3], 22, 0xc1bdceeeL);
604 R0 (A, B, C, D, X[ 4], 7, 0xf57c0fafL);
605 R0 (D, A, B, C, X[ 5], 12, 0x4787c62aL);
606 R0 (C, D, A, B, X[ 6], 17, 0xa8304613L);
607 R0 (B, C, D, A, X[ 7], 22, 0xfd469501L);
608 R0 (A, B, C, D, X[ 8], 7, 0x698098d8L);
609 R0 (D, A, B, C, X[ 9], 12, 0x8b44f7afL);
610 R0 (C, D, A, B, X[10], 17, 0xffff5bb1L);
611 R0 (B, C, D, A, X[11], 22, 0x895cd7beL);
612 R0 (A, B, C, D, X[12], 7, 0x6b901122L);
613 R0 (D, A, B, C, X[13], 12, 0xfd987193L);
614 R0 (C, D, A, B, X[14], 17, 0xa679438eL);
615 R0 (B, C, D, A, X[15], 22, 0x49b40821L);
617 R1 (A, B, C, D, X[ 1], 5, 0xf61e2562L);
618 R1 (D, A, B, C, X[ 6], 9, 0xc040b340L);
619 R1 (C, D, A, B, X[11], 14, 0x265e5a51L);
620 R1 (B, C, D, A, X[ 0], 20, 0xe9b6c7aaL);
621 R1 (A, B, C, D, X[ 5], 5, 0xd62f105dL);
622 R1 (D, A, B, C, X[10], 9, 0x02441453L);
623 R1 (C, D, A, B, X[15], 14, 0xd8a1e681L);
624 R1 (B, C, D, A, X[ 4], 20, 0xe7d3fbc8L);
625 R1 (A, B, C, D, X[ 9], 5, 0x21e1cde6L);
626 R1 (D, A, B, C, X[14], 9, 0xc33707d6L);
627 R1 (C, D, A, B, X[ 3], 14, 0xf4d50d87L);
628 R1 (B, C, D, A, X[ 8], 20, 0x455a14edL);
629 R1 (A, B, C, D, X[13], 5, 0xa9e3e905L);
630 R1 (D, A, B, C, X[ 2], 9, 0xfcefa3f8L);
631 R1 (C, D, A, B, X[ 7], 14, 0x676f02d9L);
632 R1 (B, C, D, A, X[12], 20, 0x8d2a4c8aL);
634 R2 (A, B, C, D, X[ 5], 4, 0xfffa3942L);
635 R2 (D, A, B, C, X[ 8], 11, 0x8771f681L);
636 R2 (C, D, A, B, X[11], 16, 0x6d9d6122L);
637 R2 (B, C, D, A, X[14], 23, 0xfde5380cL);
638 R2 (A, B, C, D, X[ 1], 4, 0xa4beea44L);
639 R2 (D, A, B, C, X[ 4], 11, 0x4bdecfa9L);
640 R2 (C, D, A, B, X[ 7], 16, 0xf6bb4b60L);
641 R2 (B, C, D, A, X[10], 23, 0xbebfbc70L);
642 R2 (A, B, C, D, X[13], 4, 0x289b7ec6L);
643 R2 (D, A, B, C, X[ 0], 11, 0xeaa127faL);
644 R2 (C, D, A, B, X[ 3], 16, 0xd4ef3085L);
645 R2 (B, C, D, A, X[ 6], 23, 0x04881d05L);
646 R2 (A, B, C, D, X[ 9], 4, 0xd9d4d039L);
647 R2 (D, A, B, C, X[12], 11, 0xe6db99e5L);
648 R2 (C, D, A, B, X[15], 16, 0x1fa27cf8L);
649 R2 (B, C, D, A, X[ 2], 23, 0xc4ac5665L);
651 R3 (A, B, C, D, X[ 0], 6, 0xf4292244L);
652 R3 (D, A, B, C, X[ 7], 10, 0x432aff97L);
653 R3 (C, D, A, B, X[14], 15, 0xab9423a7L);
654 R3 (B, C, D, A, X[ 5], 21, 0xfc93a039L);
655 R3 (A, B, C, D, X[12], 6, 0x655b59c3L);
656 R3 (D, A, B, C, X[ 3], 10, 0x8f0ccc92L);
657 R3 (C, D, A, B, X[10], 15, 0xffeff47dL);
658 R3 (B, C, D, A, X[ 1], 21, 0x85845dd1L);
659 R3 (A, B, C, D, X[ 8], 6, 0x6fa87e4fL);
660 R3 (D, A, B, C, X[15], 10, 0xfe2ce6e0L);
661 R3 (C, D, A, B, X[ 6], 15, 0xa3014314L);
662 R3 (B, C, D, A, X[13], 21, 0x4e0811a1L);
663 R3 (A, B, C, D, X[ 4], 6, 0xf7537e82L);
664 R3 (D, A, B, C, X[11], 10, 0xbd3af235L);
665 R3 (C, D, A, B, X[ 2], 15, 0x2ad7d2bbL);
666 R3 (B, C, D, A, X[ 9], 21, 0xeb86d391L);
668 ctx->m_nA += A;
669 ctx->m_nB += B;
670 ctx->m_nC += C;
671 ctx->m_nD += D;
675 * __rtl_digest_endMD5.
677 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx)
679 static const sal_uInt8 end[4] =
681 0x80, 0x00, 0x00, 0x00
683 const sal_uInt8 *p = end;
685 sal_uInt32 *X;
686 int i;
688 X = ctx->m_pData;
689 i = (ctx->m_nDatLen >> 2);
691 #ifdef OSL_BIGENDIAN
692 __rtl_digest_swapLong (X, i + 1);
693 #endif /* OSL_BIGENDIAN */
695 switch (ctx->m_nDatLen & 0x03)
697 case 1: X[i] &= 0x000000ff; break;
698 case 2: X[i] &= 0x0000ffff; break;
699 case 3: X[i] &= 0x00ffffff; break;
702 switch (ctx->m_nDatLen & 0x03)
704 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
705 /* fallthrough */
706 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
707 /* fallthrough */
708 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
709 /* fallthrough */
710 case 3: X[i] |= ((sal_uInt32)(*p)) << 24L;
711 /* fallthrough */
714 i += 1;
716 if (i >= (DIGEST_LBLOCK_MD5 - 2))
718 for (; i < DIGEST_LBLOCK_MD5; i++)
719 X[i] = 0;
720 __rtl_digest_updateMD5 (ctx);
721 i = 0;
724 for (; i < (DIGEST_LBLOCK_MD5 - 2); i++)
725 X[i] = 0;
727 X[DIGEST_LBLOCK_MD5 - 2] = ctx->m_nL;
728 X[DIGEST_LBLOCK_MD5 - 1] = ctx->m_nH;
730 __rtl_digest_updateMD5 (ctx);
733 /*========================================================================
735 * rtl_digest_MD5 implementation.
737 *======================================================================*/
739 * rtl_digest_MD5.
741 rtlDigestError SAL_CALL rtl_digest_MD5 (
742 const void *pData, sal_uInt32 nDatLen,
743 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
745 DigestMD5_Impl digest;
746 rtlDigestError result;
748 digest.m_digest = __rtl_digest_MD5;
749 __rtl_digest_initMD5 (&(digest.m_context));
751 result = rtl_digest_update (&digest, pData, nDatLen);
752 if (result == rtl_Digest_E_None)
753 result = rtl_digest_getMD5 (&digest, pBuffer, nBufLen);
755 memset (&digest, 0, sizeof (digest));
756 return result;
760 * rtl_digest_createMD5.
762 rtlDigest SAL_CALL rtl_digest_createMD5() SAL_THROW_EXTERN_C()
764 DigestMD5_Impl *pImpl = (DigestMD5_Impl*)NULL;
765 pImpl = RTL_DIGEST_CREATE(DigestMD5_Impl);
766 if (pImpl)
768 pImpl->m_digest = __rtl_digest_MD5;
769 __rtl_digest_initMD5 (&(pImpl->m_context));
771 return (rtlDigest)pImpl;
775 * rtl_digest_updateMD5.
777 rtlDigestError SAL_CALL rtl_digest_updateMD5 (
778 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
779 SAL_THROW_EXTERN_C()
781 DigestMD5_Impl *pImpl = static_cast<DigestMD5_Impl *>(Digest);
782 const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
784 DigestContextMD5 *ctx;
785 sal_uInt32 len;
787 if ((pImpl == NULL) || (pData == NULL))
788 return rtl_Digest_E_Argument;
790 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
791 return rtl_Digest_E_Algorithm;
793 if (nDatLen == 0)
794 return rtl_Digest_E_None;
796 ctx = &(pImpl->m_context);
798 len = ctx->m_nL + (nDatLen << 3);
799 if (len < ctx->m_nL) ctx->m_nH += 1;
800 ctx->m_nH += (nDatLen >> 29);
801 ctx->m_nL = len;
803 if (ctx->m_nDatLen)
805 sal_uInt8 *p = reinterpret_cast<sal_uInt8 *>(ctx->m_pData) + ctx->m_nDatLen;
806 sal_uInt32 n = DIGEST_CBLOCK_MD5 - ctx->m_nDatLen;
808 if (nDatLen < n)
810 memcpy (p, d, nDatLen);
811 ctx->m_nDatLen += nDatLen;
813 return rtl_Digest_E_None;
816 memcpy (p, d, n);
817 d += n;
818 nDatLen -= n;
820 #ifdef OSL_BIGENDIAN
821 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
822 #endif /* OSL_BIGENDIAN */
824 __rtl_digest_updateMD5 (ctx);
825 ctx->m_nDatLen = 0;
828 while (nDatLen >= DIGEST_CBLOCK_MD5)
830 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_MD5);
831 d += DIGEST_CBLOCK_MD5;
832 nDatLen -= DIGEST_CBLOCK_MD5;
834 #ifdef OSL_BIGENDIAN
835 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
836 #endif /* OSL_BIGENDIAN */
838 __rtl_digest_updateMD5 (ctx);
841 memcpy (ctx->m_pData, d, nDatLen);
842 ctx->m_nDatLen = nDatLen;
844 return rtl_Digest_E_None;
848 * rtl_digest_getMD5.
850 rtlDigestError SAL_CALL rtl_digest_getMD5 (
851 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
852 SAL_THROW_EXTERN_C()
854 DigestMD5_Impl *pImpl = static_cast<DigestMD5_Impl *>(Digest);
855 sal_uInt8 *p = pBuffer;
857 DigestContextMD5 *ctx;
859 if ((pImpl == NULL) || (pBuffer == NULL))
860 return rtl_Digest_E_Argument;
862 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
863 return rtl_Digest_E_Algorithm;
865 if (!(pImpl->m_digest.m_length <= nBufLen))
866 return rtl_Digest_E_BufferSize;
868 ctx = &(pImpl->m_context);
870 __rtl_digest_endMD5 (ctx);
871 RTL_DIGEST_LTOC (ctx->m_nA, p);
872 RTL_DIGEST_LTOC (ctx->m_nB, p);
873 RTL_DIGEST_LTOC (ctx->m_nC, p);
874 RTL_DIGEST_LTOC (ctx->m_nD, p);
875 __rtl_digest_initMD5 (ctx);
877 return rtl_Digest_E_None;
881 * rtl_digest_rawMD5.
883 rtlDigestError SAL_CALL rtl_digest_rawMD5 (
884 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
885 SAL_THROW_EXTERN_C()
887 DigestMD5_Impl *pImpl = static_cast<DigestMD5_Impl *>(Digest);
888 sal_uInt8 *p = pBuffer;
890 DigestContextMD5 *ctx;
892 if ((pImpl == NULL) || (pBuffer == NULL))
893 return rtl_Digest_E_Argument;
895 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
896 return rtl_Digest_E_Algorithm;
898 if (!(pImpl->m_digest.m_length <= nBufLen))
899 return rtl_Digest_E_BufferSize;
901 ctx = &(pImpl->m_context);
903 /* __rtl_digest_endMD5 (ctx); *//* not finalized */
904 RTL_DIGEST_LTOC (ctx->m_nA, p);
905 RTL_DIGEST_LTOC (ctx->m_nB, p);
906 RTL_DIGEST_LTOC (ctx->m_nC, p);
907 RTL_DIGEST_LTOC (ctx->m_nD, p);
908 __rtl_digest_initMD5 (ctx);
910 return rtl_Digest_E_None;
914 * rtl_digest_destroyMD5.
916 void SAL_CALL rtl_digest_destroyMD5 (rtlDigest Digest) SAL_THROW_EXTERN_C()
918 DigestMD5_Impl *pImpl = static_cast<DigestMD5_Impl *>(Digest);
919 if (pImpl)
921 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5)
922 rtl_freeZeroMemory (pImpl, sizeof (DigestMD5_Impl));
923 else
924 rtl_freeMemory (pImpl);
928 /*========================================================================
930 * rtl_digest_(SHA|SHA1) common internals.
932 *======================================================================*/
933 #define DIGEST_CBLOCK_SHA 64
934 #define DIGEST_LBLOCK_SHA 16
936 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x);
938 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x);
939 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x);
941 struct DigestContextSHA
943 DigestSHA_update_t *m_update;
944 sal_uInt32 m_nDatLen;
945 sal_uInt32 m_pData[DIGEST_LBLOCK_SHA];
946 sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE;
947 sal_uInt32 m_nL, m_nH;
950 struct DigestSHA_Impl
952 Digest_Impl m_digest;
953 DigestContextSHA m_context;
956 static void __rtl_digest_initSHA (
957 DigestContextSHA *ctx, DigestSHA_update_t *fct);
959 static void __rtl_digest_updateSHA (DigestContextSHA *ctx);
960 static void __rtl_digest_endSHA (DigestContextSHA *ctx);
962 #define K_00_19 (sal_uInt32)0x5a827999L
963 #define K_20_39 (sal_uInt32)0x6ed9eba1L
964 #define K_40_59 (sal_uInt32)0x8f1bbcdcL
965 #define K_60_79 (sal_uInt32)0xca62c1d6L
967 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
968 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
969 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
970 #define F_60_79(b,c,d) F_20_39(b,c,d)
972 #define BODY_X(i) \
973 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
975 #define BODY_00_15(u,i,a,b,c,d,e,f) \
976 (f) = X[i]; \
977 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
978 (b) = RTL_DIGEST_ROTL((b), 30);
980 #define BODY_16_19(u,i,a,b,c,d,e,f) \
981 (f) = BODY_X((i)); \
982 (f) = X[(i)&0x0f] = (u)((f)); \
983 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
984 (b) = RTL_DIGEST_ROTL((b), 30);
986 #define BODY_20_39(u,i,a,b,c,d,e,f) \
987 (f) = BODY_X((i)); \
988 (f) = X[(i)&0x0f] = (u)((f)); \
989 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
990 (b) = RTL_DIGEST_ROTL((b), 30);
992 #define BODY_40_59(u,i,a,b,c,d,e,f) \
993 (f) = BODY_X((i)); \
994 (f) = X[(i)&0x0f] = (u)((f)); \
995 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
996 (b) = RTL_DIGEST_ROTL((b), 30);
998 #define BODY_60_79(u,i,a,b,c,d,e,f) \
999 (f) = BODY_X((i)); \
1000 (f) = X[(i)&0x0f] = (u)((f)); \
1001 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
1002 (b) = RTL_DIGEST_ROTL((b), 30);
1005 * __rtl_digest_initSHA.
1007 static void __rtl_digest_initSHA (
1008 DigestContextSHA *ctx, DigestSHA_update_t *fct)
1010 memset (ctx, 0, sizeof (DigestContextSHA));
1011 ctx->m_update = fct;
1013 ctx->m_nA = (sal_uInt32)0x67452301L;
1014 ctx->m_nB = (sal_uInt32)0xefcdab89L;
1015 ctx->m_nC = (sal_uInt32)0x98badcfeL;
1016 ctx->m_nD = (sal_uInt32)0x10325476L;
1017 ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
1021 * __rtl_digest_updateSHA.
1023 static void __rtl_digest_updateSHA (DigestContextSHA *ctx)
1025 sal_uInt32 A, B, C, D, E, T;
1026 sal_uInt32 *X;
1028 DigestSHA_update_t *U;
1029 U = ctx->m_update;
1031 A = ctx->m_nA;
1032 B = ctx->m_nB;
1033 C = ctx->m_nC;
1034 D = ctx->m_nD;
1035 E = ctx->m_nE;
1036 X = ctx->m_pData;
1038 BODY_00_15 (U, 0, A, B, C, D, E, T);
1039 BODY_00_15 (U, 1, T, A, B, C, D, E);
1040 BODY_00_15 (U, 2, E, T, A, B, C, D);
1041 BODY_00_15 (U, 3, D, E, T, A, B, C);
1042 BODY_00_15 (U, 4, C, D, E, T, A, B);
1043 BODY_00_15 (U, 5, B, C, D, E, T, A);
1044 BODY_00_15 (U, 6, A, B, C, D, E, T);
1045 BODY_00_15 (U, 7, T, A, B, C, D, E);
1046 BODY_00_15 (U, 8, E, T, A, B, C, D);
1047 BODY_00_15 (U, 9, D, E, T, A, B, C);
1048 BODY_00_15 (U, 10, C, D, E, T, A, B);
1049 BODY_00_15 (U, 11, B, C, D, E, T, A);
1050 BODY_00_15 (U, 12, A, B, C, D, E, T);
1051 BODY_00_15 (U, 13, T, A, B, C, D, E);
1052 BODY_00_15 (U, 14, E, T, A, B, C, D);
1053 BODY_00_15 (U, 15, D, E, T, A, B, C);
1054 BODY_16_19 (U, 16, C, D, E, T, A, B);
1055 BODY_16_19 (U, 17, B, C, D, E, T, A);
1056 BODY_16_19 (U, 18, A, B, C, D, E, T);
1057 BODY_16_19 (U, 19, T, A, B, C, D, E);
1059 BODY_20_39 (U, 20, E, T, A, B, C, D);
1060 BODY_20_39 (U, 21, D, E, T, A, B, C);
1061 BODY_20_39 (U, 22, C, D, E, T, A, B);
1062 BODY_20_39 (U, 23, B, C, D, E, T, A);
1063 BODY_20_39 (U, 24, A, B, C, D, E, T);
1064 BODY_20_39 (U, 25, T, A, B, C, D, E);
1065 BODY_20_39 (U, 26, E, T, A, B, C, D);
1066 BODY_20_39 (U, 27, D, E, T, A, B, C);
1067 BODY_20_39 (U, 28, C, D, E, T, A, B);
1068 BODY_20_39 (U, 29, B, C, D, E, T, A);
1069 BODY_20_39 (U, 30, A, B, C, D, E, T);
1070 BODY_20_39 (U, 31, T, A, B, C, D, E);
1071 BODY_20_39 (U, 32, E, T, A, B, C, D);
1072 BODY_20_39 (U, 33, D, E, T, A, B, C);
1073 BODY_20_39 (U, 34, C, D, E, T, A, B);
1074 BODY_20_39 (U, 35, B, C, D, E, T, A);
1075 BODY_20_39 (U, 36, A, B, C, D, E, T);
1076 BODY_20_39 (U, 37, T, A, B, C, D, E);
1077 BODY_20_39 (U, 38, E, T, A, B, C, D);
1078 BODY_20_39 (U, 39, D, E, T, A, B, C);
1080 BODY_40_59 (U, 40, C, D, E, T, A, B);
1081 BODY_40_59 (U, 41, B, C, D, E, T, A);
1082 BODY_40_59 (U, 42, A, B, C, D, E, T);
1083 BODY_40_59 (U, 43, T, A, B, C, D, E);
1084 BODY_40_59 (U, 44, E, T, A, B, C, D);
1085 BODY_40_59 (U, 45, D, E, T, A, B, C);
1086 BODY_40_59 (U, 46, C, D, E, T, A, B);
1087 BODY_40_59 (U, 47, B, C, D, E, T, A);
1088 BODY_40_59 (U, 48, A, B, C, D, E, T);
1089 BODY_40_59 (U, 49, T, A, B, C, D, E);
1090 BODY_40_59 (U, 50, E, T, A, B, C, D);
1091 BODY_40_59 (U, 51, D, E, T, A, B, C);
1092 BODY_40_59 (U, 52, C, D, E, T, A, B);
1093 BODY_40_59 (U, 53, B, C, D, E, T, A);
1094 BODY_40_59 (U, 54, A, B, C, D, E, T);
1095 BODY_40_59 (U, 55, T, A, B, C, D, E);
1096 BODY_40_59 (U, 56, E, T, A, B, C, D);
1097 BODY_40_59 (U, 57, D, E, T, A, B, C);
1098 BODY_40_59 (U, 58, C, D, E, T, A, B);
1099 BODY_40_59 (U, 59, B, C, D, E, T, A);
1101 BODY_60_79 (U, 60, A, B, C, D, E, T);
1102 BODY_60_79 (U, 61, T, A, B, C, D, E);
1103 BODY_60_79 (U, 62, E, T, A, B, C, D);
1104 BODY_60_79 (U, 63, D, E, T, A, B, C);
1105 BODY_60_79 (U, 64, C, D, E, T, A, B);
1106 BODY_60_79 (U, 65, B, C, D, E, T, A);
1107 BODY_60_79 (U, 66, A, B, C, D, E, T);
1108 BODY_60_79 (U, 67, T, A, B, C, D, E);
1109 BODY_60_79 (U, 68, E, T, A, B, C, D);
1110 BODY_60_79 (U, 69, D, E, T, A, B, C);
1111 BODY_60_79 (U, 70, C, D, E, T, A, B);
1112 BODY_60_79 (U, 71, B, C, D, E, T, A);
1113 BODY_60_79 (U, 72, A, B, C, D, E, T);
1114 BODY_60_79 (U, 73, T, A, B, C, D, E);
1115 BODY_60_79 (U, 74, E, T, A, B, C, D);
1116 BODY_60_79 (U, 75, D, E, T, A, B, C);
1117 BODY_60_79 (U, 76, C, D, E, T, A, B);
1118 BODY_60_79 (U, 77, B, C, D, E, T, A);
1119 BODY_60_79 (U, 78, A, B, C, D, E, T);
1120 BODY_60_79 (U, 79, T, A, B, C, D, E);
1122 ctx->m_nA += E;
1123 ctx->m_nB += T;
1124 ctx->m_nC += A;
1125 ctx->m_nD += B;
1126 ctx->m_nE += C;
1130 * __rtl_digest_endSHA.
1132 static void __rtl_digest_endSHA (DigestContextSHA *ctx)
1134 static const sal_uInt8 end[4] =
1136 0x80, 0x00, 0x00, 0x00
1138 const sal_uInt8 *p = end;
1140 sal_uInt32 *X;
1141 int i;
1143 X = ctx->m_pData;
1144 i = (ctx->m_nDatLen >> 2);
1146 #ifdef OSL_BIGENDIAN
1147 __rtl_digest_swapLong (X, i + 1);
1148 #endif /* OSL_BIGENDIAN */
1150 switch (ctx->m_nDatLen & 0x03)
1152 case 1: X[i] &= 0x000000ff; break;
1153 case 2: X[i] &= 0x0000ffff; break;
1154 case 3: X[i] &= 0x00ffffff; break;
1157 switch (ctx->m_nDatLen & 0x03)
1159 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
1160 /* fallthrough */
1161 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
1162 /* fallthrough */
1163 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
1164 /* fallthrough */
1165 case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
1166 /* fallthrough */
1169 __rtl_digest_swapLong (X, i + 1);
1171 i += 1;
1173 if (i >= (DIGEST_LBLOCK_SHA - 2))
1175 for (; i < DIGEST_LBLOCK_SHA; i++)
1176 X[i] = 0;
1177 __rtl_digest_updateSHA (ctx);
1178 i = 0;
1181 for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
1182 X[i] = 0;
1184 X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
1185 X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
1187 __rtl_digest_updateSHA (ctx);
1190 /*========================================================================
1192 * rtl_digest_SHA internals.
1194 *======================================================================*/
1196 * __rtl_digest_SHA_0.
1198 static const Digest_Impl __rtl_digest_SHA_0 =
1200 rtl_Digest_AlgorithmSHA,
1201 RTL_DIGEST_LENGTH_SHA,
1203 NULL,
1204 rtl_digest_destroySHA,
1205 rtl_digest_updateSHA,
1206 rtl_digest_getSHA
1210 * __rtl_digest_updateSHA_0.
1212 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x)
1214 return x;
1217 /*========================================================================
1219 * rtl_digest_SHA implementation.
1221 *======================================================================*/
1223 * rtl_digest_SHA.
1225 rtlDigestError SAL_CALL rtl_digest_SHA (
1226 const void *pData, sal_uInt32 nDatLen,
1227 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1229 DigestSHA_Impl digest;
1230 rtlDigestError result;
1232 digest.m_digest = __rtl_digest_SHA_0;
1233 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_0);
1235 result = rtl_digest_updateSHA (&digest, pData, nDatLen);
1236 if (result == rtl_Digest_E_None)
1237 result = rtl_digest_getSHA (&digest, pBuffer, nBufLen);
1239 memset (&digest, 0, sizeof (digest));
1240 return result;
1244 * rtl_digest_createSHA.
1246 rtlDigest SAL_CALL rtl_digest_createSHA() SAL_THROW_EXTERN_C()
1248 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1249 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1250 if (pImpl)
1252 pImpl->m_digest = __rtl_digest_SHA_0;
1253 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_0);
1255 return (rtlDigest)pImpl;
1259 * rtl_digest_updateSHA.
1261 rtlDigestError SAL_CALL rtl_digest_updateSHA (
1262 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1263 SAL_THROW_EXTERN_C()
1265 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1266 const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
1268 DigestContextSHA *ctx;
1269 sal_uInt32 len;
1271 if ((pImpl == NULL) || (pData == NULL))
1272 return rtl_Digest_E_Argument;
1274 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1275 return rtl_Digest_E_Algorithm;
1277 if (nDatLen == 0)
1278 return rtl_Digest_E_None;
1280 ctx = &(pImpl->m_context);
1282 len = ctx->m_nL + (nDatLen << 3);
1283 if (len < ctx->m_nL) ctx->m_nH += 1;
1284 ctx->m_nH += (nDatLen >> 29);
1285 ctx->m_nL = len;
1287 if (ctx->m_nDatLen)
1289 sal_uInt8 *p = reinterpret_cast<sal_uInt8 *>(ctx->m_pData) + ctx->m_nDatLen;
1290 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1292 if (nDatLen < n)
1294 memcpy (p, d, nDatLen);
1295 ctx->m_nDatLen += nDatLen;
1297 return rtl_Digest_E_None;
1300 memcpy (p, d, n);
1301 d += n;
1302 nDatLen -= n;
1304 #ifndef OSL_BIGENDIAN
1305 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1306 #endif /* OSL_BIGENDIAN */
1308 __rtl_digest_updateSHA (ctx);
1309 ctx->m_nDatLen = 0;
1312 while (nDatLen >= DIGEST_CBLOCK_SHA)
1314 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1315 d += DIGEST_CBLOCK_SHA;
1316 nDatLen -= DIGEST_CBLOCK_SHA;
1318 #ifndef OSL_BIGENDIAN
1319 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1320 #endif /* OSL_BIGENDIAN */
1322 __rtl_digest_updateSHA (ctx);
1325 memcpy (ctx->m_pData, d, nDatLen);
1326 ctx->m_nDatLen = nDatLen;
1328 return rtl_Digest_E_None;
1332 * rtl_digest_getSHA.
1334 rtlDigestError SAL_CALL rtl_digest_getSHA (
1335 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1336 SAL_THROW_EXTERN_C()
1338 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1339 sal_uInt8 *p = pBuffer;
1341 DigestContextSHA *ctx;
1343 if ((pImpl == NULL) || (pBuffer == NULL))
1344 return rtl_Digest_E_Argument;
1346 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1347 return rtl_Digest_E_Algorithm;
1349 if (!(pImpl->m_digest.m_length <= nBufLen))
1350 return rtl_Digest_E_BufferSize;
1352 ctx = &(pImpl->m_context);
1354 __rtl_digest_endSHA (ctx);
1355 RTL_DIGEST_HTONL (ctx->m_nA, p);
1356 RTL_DIGEST_HTONL (ctx->m_nB, p);
1357 RTL_DIGEST_HTONL (ctx->m_nC, p);
1358 RTL_DIGEST_HTONL (ctx->m_nD, p);
1359 RTL_DIGEST_HTONL (ctx->m_nE, p);
1360 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_0);
1362 return rtl_Digest_E_None;
1366 * rtl_digest_destroySHA.
1368 void SAL_CALL rtl_digest_destroySHA (rtlDigest Digest) SAL_THROW_EXTERN_C()
1370 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1371 if (pImpl)
1373 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA)
1374 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1375 else
1376 rtl_freeMemory (pImpl);
1380 /*========================================================================
1382 * rtl_digest_SHA1 internals.
1384 *======================================================================*/
1386 * __rtl_digest_SHA_1.
1388 static const Digest_Impl __rtl_digest_SHA_1 =
1390 rtl_Digest_AlgorithmSHA1,
1391 RTL_DIGEST_LENGTH_SHA1,
1393 NULL,
1394 rtl_digest_destroySHA1,
1395 rtl_digest_updateSHA1,
1396 rtl_digest_getSHA1
1400 * __rtl_digest_updateSHA_1.
1402 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
1404 return RTL_DIGEST_ROTL (x, 1);
1407 /*========================================================================
1409 * rtl_digest_SHA1 implementation.
1411 *======================================================================*/
1413 * rtl_digest_SHA1.
1415 rtlDigestError SAL_CALL rtl_digest_SHA1 (
1416 const void *pData, sal_uInt32 nDatLen,
1417 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1419 DigestSHA_Impl digest;
1420 rtlDigestError result;
1422 digest.m_digest = __rtl_digest_SHA_1;
1423 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
1425 result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
1426 if (result == rtl_Digest_E_None)
1427 result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
1429 memset (&digest, 0, sizeof (digest));
1430 return result;
1434 * rtl_digest_createSHA1.
1436 rtlDigest SAL_CALL rtl_digest_createSHA1() SAL_THROW_EXTERN_C()
1438 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1439 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1440 if (pImpl)
1442 pImpl->m_digest = __rtl_digest_SHA_1;
1443 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1445 return (rtlDigest)pImpl;
1449 * rtl_digest_updateSHA1.
1451 rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
1452 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1453 SAL_THROW_EXTERN_C()
1455 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1456 const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
1458 DigestContextSHA *ctx;
1459 sal_uInt32 len;
1461 if ((pImpl == NULL) || (pData == NULL))
1462 return rtl_Digest_E_Argument;
1464 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1465 return rtl_Digest_E_Algorithm;
1467 if (nDatLen == 0)
1468 return rtl_Digest_E_None;
1470 ctx = &(pImpl->m_context);
1472 len = ctx->m_nL + (nDatLen << 3);
1473 if (len < ctx->m_nL) ctx->m_nH += 1;
1474 ctx->m_nH += (nDatLen >> 29);
1475 ctx->m_nL = len;
1477 if (ctx->m_nDatLen)
1479 sal_uInt8 *p = reinterpret_cast<sal_uInt8 *>(ctx->m_pData) + ctx->m_nDatLen;
1480 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1482 if (nDatLen < n)
1484 memcpy (p, d, nDatLen);
1485 ctx->m_nDatLen += nDatLen;
1487 return rtl_Digest_E_None;
1490 memcpy (p, d, n);
1491 d += n;
1492 nDatLen -= n;
1494 #ifndef OSL_BIGENDIAN
1495 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1496 #endif /* OSL_BIGENDIAN */
1498 __rtl_digest_updateSHA (ctx);
1499 ctx->m_nDatLen = 0;
1502 while (nDatLen >= DIGEST_CBLOCK_SHA)
1504 memcpy (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1505 d += DIGEST_CBLOCK_SHA;
1506 nDatLen -= DIGEST_CBLOCK_SHA;
1508 #ifndef OSL_BIGENDIAN
1509 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1510 #endif /* OSL_BIGENDIAN */
1512 __rtl_digest_updateSHA (ctx);
1515 memcpy (ctx->m_pData, d, nDatLen);
1516 ctx->m_nDatLen = nDatLen;
1518 return rtl_Digest_E_None;
1522 * rtl_digest_getSHA1.
1524 rtlDigestError SAL_CALL rtl_digest_getSHA1 (
1525 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1526 SAL_THROW_EXTERN_C()
1528 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1529 sal_uInt8 *p = pBuffer;
1531 DigestContextSHA *ctx;
1533 if ((pImpl == NULL) || (pBuffer == NULL))
1534 return rtl_Digest_E_Argument;
1536 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1537 return rtl_Digest_E_Algorithm;
1539 if (!(pImpl->m_digest.m_length <= nBufLen))
1540 return rtl_Digest_E_BufferSize;
1542 ctx = &(pImpl->m_context);
1544 __rtl_digest_endSHA (ctx);
1545 RTL_DIGEST_HTONL (ctx->m_nA, p);
1546 RTL_DIGEST_HTONL (ctx->m_nB, p);
1547 RTL_DIGEST_HTONL (ctx->m_nC, p);
1548 RTL_DIGEST_HTONL (ctx->m_nD, p);
1549 RTL_DIGEST_HTONL (ctx->m_nE, p);
1550 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
1552 return rtl_Digest_E_None;
1556 * rtl_digest_destroySHA1.
1558 void SAL_CALL rtl_digest_destroySHA1 (rtlDigest Digest) SAL_THROW_EXTERN_C()
1560 DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
1561 if (pImpl)
1563 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
1564 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1565 else
1566 rtl_freeMemory (pImpl);
1570 /*========================================================================
1572 * rtl_digest_HMAC_MD5 internals.
1574 *======================================================================*/
1575 #define DIGEST_CBLOCK_HMAC_MD5 64
1577 struct ContextHMAC_MD5
1579 DigestMD5_Impl m_hash;
1580 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_MD5];
1583 struct DigestHMAC_MD5_Impl
1585 Digest_Impl m_digest;
1586 ContextHMAC_MD5 m_context;
1589 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx);
1590 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1591 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1594 * __rtl_digest_HMAC_MD5.
1596 static const Digest_Impl __rtl_digest_HMAC_MD5 =
1598 rtl_Digest_AlgorithmHMAC_MD5,
1599 RTL_DIGEST_LENGTH_MD5,
1601 rtl_digest_initHMAC_MD5,
1602 rtl_digest_destroyHMAC_MD5,
1603 rtl_digest_updateHMAC_MD5,
1604 rtl_digest_getHMAC_MD5
1608 * __rtl_digest_initHMAC_MD5.
1610 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx)
1612 DigestMD5_Impl *pImpl = &(ctx->m_hash);
1614 pImpl->m_digest = __rtl_digest_MD5;
1615 __rtl_digest_initMD5 (&(pImpl->m_context));
1617 memset (ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_MD5);
1621 * __rtl_digest_ipadHMAC_MD5.
1623 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1625 sal_uInt32 i;
1627 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1628 ctx->m_opad[i] ^= 0x36;
1629 rtl_digest_updateMD5 (
1630 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1631 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1632 ctx->m_opad[i] ^= 0x36;
1636 * __rtl_digest_opadHMAC_MD5.
1638 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1640 sal_uInt32 i;
1642 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1643 ctx->m_opad[i] ^= 0x5c;
1646 /*========================================================================
1648 * rtl_digest_HMAC_MD5 implementation.
1650 *======================================================================*/
1652 * rtl_digest_HMAC_MD5.
1654 rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
1655 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1656 const void *pData, sal_uInt32 nDatLen,
1657 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1659 DigestHMAC_MD5_Impl digest;
1660 rtlDigestError result;
1662 digest.m_digest = __rtl_digest_HMAC_MD5;
1664 result = rtl_digest_initHMAC_MD5 (&digest, pKeyData, nKeyLen);
1665 if (result == rtl_Digest_E_None)
1667 result = rtl_digest_updateHMAC_MD5 (&digest, pData, nDatLen);
1668 if (result == rtl_Digest_E_None)
1669 result = rtl_digest_getHMAC_MD5 (&digest, pBuffer, nBufLen);
1672 memset (&digest, 0, sizeof (digest));
1673 return result;
1677 * rtl_digest_createHMAC_MD5.
1679 rtlDigest SAL_CALL rtl_digest_createHMAC_MD5() SAL_THROW_EXTERN_C()
1681 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)NULL;
1682 pImpl = RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl);
1683 if (pImpl)
1685 pImpl->m_digest = __rtl_digest_HMAC_MD5;
1686 __rtl_digest_initHMAC_MD5 (&(pImpl->m_context));
1688 return (rtlDigest)pImpl;
1692 * rtl_digest_initHMAC_MD5.
1694 rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
1695 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1696 SAL_THROW_EXTERN_C()
1698 DigestHMAC_MD5_Impl *pImpl = static_cast<DigestHMAC_MD5_Impl*>(Digest);
1699 ContextHMAC_MD5 *ctx;
1701 if ((pImpl == NULL) || (pKeyData == NULL))
1702 return rtl_Digest_E_Argument;
1704 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1705 return rtl_Digest_E_Algorithm;
1707 ctx = &(pImpl->m_context);
1708 __rtl_digest_initHMAC_MD5 (ctx);
1710 if (nKeyLen > DIGEST_CBLOCK_HMAC_MD5)
1712 /* Initialize 'opad' with hashed 'KeyData' */
1713 rtl_digest_updateMD5 (
1714 &(ctx->m_hash), pKeyData, nKeyLen);
1715 rtl_digest_getMD5 (
1716 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_MD5);
1718 else
1720 /* Initialize 'opad' with plain 'KeyData' */
1721 memcpy (ctx->m_opad, pKeyData, nKeyLen);
1724 __rtl_digest_ipadHMAC_MD5 (ctx);
1725 __rtl_digest_opadHMAC_MD5 (ctx);
1727 return rtl_Digest_E_None;
1731 * rtl_digest_updateHMAC_MD5.
1733 rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
1734 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1735 SAL_THROW_EXTERN_C()
1737 DigestHMAC_MD5_Impl *pImpl = static_cast<DigestHMAC_MD5_Impl*>(Digest);
1738 ContextHMAC_MD5 *ctx;
1740 if ((pImpl == NULL) || (pData == NULL))
1741 return rtl_Digest_E_Argument;
1743 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1744 return rtl_Digest_E_Algorithm;
1746 ctx = &(pImpl->m_context);
1747 rtl_digest_updateMD5 (&(ctx->m_hash), pData, nDatLen);
1749 return rtl_Digest_E_None;
1753 * rtl_digest_getHMAC_MD5.
1755 rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
1756 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1757 SAL_THROW_EXTERN_C()
1759 DigestHMAC_MD5_Impl *pImpl = static_cast<DigestHMAC_MD5_Impl*>(Digest);
1760 ContextHMAC_MD5 *ctx;
1762 if ((pImpl == NULL) || (pBuffer == NULL))
1763 return rtl_Digest_E_Argument;
1765 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1766 return rtl_Digest_E_Algorithm;
1768 if (!(pImpl->m_digest.m_length <= nBufLen))
1769 return rtl_Digest_E_BufferSize;
1771 nBufLen = pImpl->m_digest.m_length;
1773 ctx = &(pImpl->m_context);
1774 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1776 rtl_digest_updateMD5 (&(ctx->m_hash), ctx->m_opad, 64);
1777 rtl_digest_updateMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1778 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1780 __rtl_digest_opadHMAC_MD5 (ctx);
1781 __rtl_digest_ipadHMAC_MD5 (ctx);
1782 __rtl_digest_opadHMAC_MD5 (ctx);
1784 return rtl_Digest_E_None;
1788 * rtl_digest_destroyHMAC_MD5.
1790 void SAL_CALL rtl_digest_destroyHMAC_MD5 (rtlDigest Digest) SAL_THROW_EXTERN_C()
1792 DigestHMAC_MD5_Impl *pImpl = static_cast<DigestHMAC_MD5_Impl*>(Digest);
1793 if (pImpl)
1795 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5)
1796 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_MD5_Impl));
1797 else
1798 rtl_freeMemory (pImpl);
1802 /*========================================================================
1804 * rtl_digest_HMAC_SHA1 internals.
1806 *======================================================================*/
1807 #define DIGEST_CBLOCK_HMAC_SHA1 64
1809 struct ContextHMAC_SHA1
1811 DigestSHA_Impl m_hash;
1812 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_SHA1];
1815 struct DigestHMAC_SHA1_Impl
1817 Digest_Impl m_digest;
1818 ContextHMAC_SHA1 m_context;
1821 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1822 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1823 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1826 * __rtl_digest_HMAC_SHA1.
1828 static const Digest_Impl __rtl_digest_HMAC_SHA1 =
1830 rtl_Digest_AlgorithmHMAC_SHA1,
1831 RTL_DIGEST_LENGTH_SHA1,
1833 rtl_digest_initHMAC_SHA1,
1834 rtl_digest_destroyHMAC_SHA1,
1835 rtl_digest_updateHMAC_SHA1,
1836 rtl_digest_getHMAC_SHA1
1840 * __rtl_digest_initHMAC_SHA1.
1842 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1844 DigestSHA_Impl *pImpl = &(ctx->m_hash);
1846 pImpl->m_digest = __rtl_digest_SHA_1;
1847 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1849 memset (ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_SHA1);
1853 * __rtl_digest_ipadHMAC_SHA1.
1855 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1857 sal_uInt32 i;
1859 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1860 ctx->m_opad[i] ^= 0x36;
1861 rtl_digest_updateSHA1 (
1862 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1863 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1864 ctx->m_opad[i] ^= 0x36;
1868 * __rtl_digest_opadHMAC_SHA1.
1870 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1872 sal_uInt32 i;
1874 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1875 ctx->m_opad[i] ^= 0x5c;
1878 /*========================================================================
1880 * rtl_digest_HMAC_SHA1 implementation.
1882 *======================================================================*/
1884 * rtl_digest_HMAC_SHA1.
1886 rtlDigestError SAL_CALL rtl_digest_HMAC_SHA1 (
1887 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1888 const void *pData, sal_uInt32 nDatLen,
1889 sal_uInt8 *pBuffer, sal_uInt32 nBufLen) SAL_THROW_EXTERN_C()
1891 DigestHMAC_SHA1_Impl digest;
1892 rtlDigestError result;
1894 digest.m_digest = __rtl_digest_HMAC_SHA1;
1896 result = rtl_digest_initHMAC_SHA1 (&digest, pKeyData, nKeyLen);
1897 if (result == rtl_Digest_E_None)
1899 result = rtl_digest_updateHMAC_SHA1 (&digest, pData, nDatLen);
1900 if (result == rtl_Digest_E_None)
1901 result = rtl_digest_getHMAC_SHA1 (&digest, pBuffer, nBufLen);
1904 memset (&digest, 0, sizeof (digest));
1905 return result;
1909 * rtl_digest_createHMAC_SHA1.
1911 rtlDigest SAL_CALL rtl_digest_createHMAC_SHA1() SAL_THROW_EXTERN_C()
1913 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)NULL;
1914 pImpl = RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl);
1915 if (pImpl)
1917 pImpl->m_digest = __rtl_digest_HMAC_SHA1;
1918 __rtl_digest_initHMAC_SHA1 (&(pImpl->m_context));
1920 return (rtlDigest)pImpl;
1924 * rtl_digest_initHMAC_SHA1.
1926 rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
1927 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1928 SAL_THROW_EXTERN_C()
1930 DigestHMAC_SHA1_Impl *pImpl = static_cast<DigestHMAC_SHA1_Impl*>(Digest);
1931 ContextHMAC_SHA1 *ctx;
1933 if ((pImpl == NULL) || (pKeyData == NULL))
1934 return rtl_Digest_E_Argument;
1936 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1937 return rtl_Digest_E_Algorithm;
1939 ctx = &(pImpl->m_context);
1940 __rtl_digest_initHMAC_SHA1 (ctx);
1942 if (nKeyLen > DIGEST_CBLOCK_HMAC_SHA1)
1944 /* Initialize 'opad' with hashed 'KeyData' */
1945 rtl_digest_updateSHA1 (
1946 &(ctx->m_hash), pKeyData, nKeyLen);
1947 rtl_digest_getSHA1 (
1948 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_SHA1);
1950 else
1952 /* Initialize 'opad' with plain 'KeyData' */
1953 memcpy (ctx->m_opad, pKeyData, nKeyLen);
1956 __rtl_digest_ipadHMAC_SHA1 (ctx);
1957 __rtl_digest_opadHMAC_SHA1 (ctx);
1959 return rtl_Digest_E_None;
1963 * rtl_digest_updateHMAC_SHA1.
1965 rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
1966 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1967 SAL_THROW_EXTERN_C()
1969 DigestHMAC_SHA1_Impl *pImpl = static_cast<DigestHMAC_SHA1_Impl*>(Digest);
1970 ContextHMAC_SHA1 *ctx;
1972 if ((pImpl == NULL) || (pData == NULL))
1973 return rtl_Digest_E_Argument;
1975 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1976 return rtl_Digest_E_Algorithm;
1978 ctx = &(pImpl->m_context);
1979 rtl_digest_updateSHA1 (&(ctx->m_hash), pData, nDatLen);
1981 return rtl_Digest_E_None;
1985 * rtl_digest_getHMAC_SHA1.
1987 rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
1988 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1989 SAL_THROW_EXTERN_C()
1991 DigestHMAC_SHA1_Impl *pImpl = static_cast<DigestHMAC_SHA1_Impl*>(Digest);
1992 ContextHMAC_SHA1 *ctx;
1994 if ((pImpl == NULL) || (pBuffer == NULL))
1995 return rtl_Digest_E_Argument;
1997 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1998 return rtl_Digest_E_Algorithm;
2000 if (!(pImpl->m_digest.m_length <= nBufLen))
2001 return rtl_Digest_E_BufferSize;
2003 nBufLen = pImpl->m_digest.m_length;
2005 ctx = &(pImpl->m_context);
2006 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2008 rtl_digest_updateSHA1 (&(ctx->m_hash), ctx->m_opad, sizeof(ctx->m_opad));
2009 rtl_digest_updateSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2010 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
2012 __rtl_digest_opadHMAC_SHA1 (ctx);
2013 __rtl_digest_ipadHMAC_SHA1 (ctx);
2014 __rtl_digest_opadHMAC_SHA1 (ctx);
2016 return rtl_Digest_E_None;
2020 * rtl_digest_destroyHMAC_SHA1.
2022 void SAL_CALL rtl_digest_destroyHMAC_SHA1 (rtlDigest Digest)
2023 SAL_THROW_EXTERN_C()
2025 DigestHMAC_SHA1_Impl *pImpl = static_cast<DigestHMAC_SHA1_Impl*>(Digest);
2026 if (pImpl)
2028 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1)
2029 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_SHA1_Impl));
2030 else
2031 rtl_freeMemory (pImpl);
2035 /*========================================================================
2037 * rtl_digest_PBKDF2 internals.
2039 *======================================================================*/
2040 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
2043 * __rtl_digest_updatePBKDF2.
2045 static void __rtl_digest_updatePBKDF2 (
2046 rtlDigest hDigest,
2047 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2],
2048 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2049 sal_uInt32 nCount, sal_uInt32 nIndex)
2051 /* T_i = F (P, S, c, i) */
2052 sal_uInt8 U[DIGEST_CBLOCK_PBKDF2];
2053 sal_uInt32 i, k;
2055 /* U_(1) = PRF (P, S || INDEX) */
2056 rtl_digest_updateHMAC_SHA1 (hDigest, pSaltData, nSaltLen);
2057 rtl_digest_updateHMAC_SHA1 (hDigest, &nIndex, sizeof(nIndex));
2058 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2060 /* T = U_(1) */
2061 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] = U[k];
2063 /* T ^= U_(2) ^ ... ^ U_(c) */
2064 for (i = 1; i < nCount; i++)
2066 /* U_(i) = PRF (P, U_(i-1)) */
2067 rtl_digest_updateHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2068 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2070 /* T ^= U_(i) */
2071 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] ^= U[k];
2074 rtl_secureZeroMemory (U, DIGEST_CBLOCK_PBKDF2);
2077 /*========================================================================
2079 * rtl_digest_PBKDF2 implementation.
2081 *======================================================================*/
2083 * rtl_digest_PBKDF2.
2085 rtlDigestError SAL_CALL rtl_digest_PBKDF2 (
2086 sal_uInt8 *pKeyData , sal_uInt32 nKeyLen,
2087 const sal_uInt8 *pPassData, sal_uInt32 nPassLen,
2088 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2089 sal_uInt32 nCount) SAL_THROW_EXTERN_C()
2091 DigestHMAC_SHA1_Impl digest;
2092 sal_uInt32 i = 1;
2094 if ((pKeyData == NULL) || (pPassData == NULL) || (pSaltData == NULL))
2095 return rtl_Digest_E_Argument;
2097 digest.m_digest = __rtl_digest_HMAC_SHA1;
2098 rtl_digest_initHMAC_SHA1 (&digest, pPassData, nPassLen);
2100 /* DK = T_(1) || T_(2) || ... || T_(l) */
2101 while (nKeyLen >= DIGEST_CBLOCK_PBKDF2)
2103 /* T_(i) = F (P, S, c, i); DK ||= T_(i) */
2104 __rtl_digest_updatePBKDF2 (
2105 &digest, pKeyData,
2106 pSaltData, nSaltLen,
2107 nCount, OSL_NETDWORD(i));
2109 /* Next 'KeyData' block */
2110 pKeyData += DIGEST_CBLOCK_PBKDF2;
2111 nKeyLen -= DIGEST_CBLOCK_PBKDF2;
2112 i += 1;
2114 if (nKeyLen > 0)
2116 /* Last 'KeyData' block */
2117 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2];
2119 /* T_i = F (P, S, c, i) */
2120 __rtl_digest_updatePBKDF2 (
2121 &digest, T,
2122 pSaltData, nSaltLen,
2123 nCount, OSL_NETDWORD(i));
2125 /* DK ||= T_(i) */
2126 memcpy (pKeyData, T, nKeyLen);
2127 rtl_secureZeroMemory (T, DIGEST_CBLOCK_PBKDF2);
2130 memset (&digest, 0, sizeof (digest));
2131 return rtl_Digest_E_None;
2134 /*========================================================================
2136 * The End.
2138 *======================================================================*/
2140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */