merge the formfield patch from ooo-build
[ooovba.git] / sal / rtl / source / digest.c
blob035b6736ba3b712506d63e5e926d747b8df1512b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: digest.c,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #define _RTL_DIGEST_C_ "$Revision: 1.9 $"
33 #include <sal/types.h>
34 #include <sal/macros.h>
35 #include <osl/endian.h>
36 #include <rtl/alloc.h>
37 #include <rtl/memory.h>
38 #include <rtl/digest.h>
40 /*========================================================================
42 * rtlDigest internals.
44 *======================================================================*/
45 #define RTL_DIGEST_CREATE(T) ((T*)(rtl_allocateZeroMemory(sizeof(T))))
47 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
49 #define RTL_DIGEST_HTONL(l,c) \
50 (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
51 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
52 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
53 *((c)++) = (sal_uInt8)(((l) ) & 0xff))
55 #define RTL_DIGEST_LTOC(l,c) \
56 (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \
57 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
58 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
59 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
61 typedef rtlDigestError (SAL_CALL Digest_init_t) (
62 void *ctx, const sal_uInt8 *Data, sal_uInt32 DatLen);
64 typedef void (SAL_CALL Digest_delete_t) (void *ctx);
66 typedef rtlDigestError (SAL_CALL Digest_update_t) (
67 void *ctx, const void *Data, sal_uInt32 DatLen);
69 typedef rtlDigestError (SAL_CALL Digest_get_t) (
70 void *ctx, sal_uInt8 *Buffer, sal_uInt32 BufLen);
72 typedef struct digest_impl_st
74 rtlDigestAlgorithm m_algorithm;
75 sal_uInt32 m_length;
77 Digest_init_t *m_init;
78 Digest_delete_t *m_delete;
79 Digest_update_t *m_update;
80 Digest_get_t *m_get;
81 } Digest_Impl;
84 * __rtl_digest_swapLong.
86 static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
88 register sal_uInt32 *X;
89 register int i, n;
91 X = pData;
92 n = nDatLen;
94 for (i = 0; i < n; i++)
95 X[i] = OSL_SWAPDWORD(X[i]);
98 /*========================================================================
100 * rtlDigest implementation.
102 *======================================================================*/
104 * rtl_digest_create.
106 rtlDigest SAL_CALL rtl_digest_create (rtlDigestAlgorithm Algorithm)
108 rtlDigest Digest = (rtlDigest)NULL;
109 switch (Algorithm)
111 case rtl_Digest_AlgorithmMD2:
112 Digest = rtl_digest_createMD2();
113 break;
115 case rtl_Digest_AlgorithmMD5:
116 Digest = rtl_digest_createMD5();
117 break;
119 case rtl_Digest_AlgorithmSHA:
120 Digest = rtl_digest_createSHA();
121 break;
123 case rtl_Digest_AlgorithmSHA1:
124 Digest = rtl_digest_createSHA1();
125 break;
127 case rtl_Digest_AlgorithmHMAC_MD5:
128 Digest = rtl_digest_createHMAC_MD5();
129 break;
131 case rtl_Digest_AlgorithmHMAC_SHA1:
132 Digest = rtl_digest_createHMAC_SHA1();
133 break;
135 default: /* rtl_Digest_AlgorithmInvalid */
136 break;
138 return Digest;
142 * rtl_digest_queryAlgorithm.
144 rtlDigestAlgorithm SAL_CALL rtl_digest_queryAlgorithm (rtlDigest Digest)
146 Digest_Impl *pImpl = (Digest_Impl *)Digest;
147 if (pImpl)
148 return pImpl->m_algorithm;
149 else
150 return rtl_Digest_AlgorithmInvalid;
154 * rtl_digest_queryLength.
156 sal_uInt32 SAL_CALL rtl_digest_queryLength (rtlDigest Digest)
158 Digest_Impl *pImpl = (Digest_Impl *)Digest;
159 if (pImpl)
160 return pImpl->m_length;
161 else
162 return 0;
166 * rtl_digest_init.
168 rtlDigestError SAL_CALL rtl_digest_init (
169 rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
171 Digest_Impl *pImpl = (Digest_Impl *)Digest;
172 if (pImpl)
174 if (pImpl->m_init)
175 return pImpl->m_init (Digest, pData, nDatLen);
176 else
177 return rtl_Digest_E_None;
179 return rtl_Digest_E_Argument;
183 * rtl_digest_update.
185 rtlDigestError SAL_CALL rtl_digest_update (
186 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
188 Digest_Impl *pImpl = (Digest_Impl *)Digest;
189 if (pImpl && pImpl->m_update)
190 return pImpl->m_update (Digest, pData, nDatLen);
191 else
192 return rtl_Digest_E_Argument;
196 * rtl_digest_get.
198 rtlDigestError SAL_CALL rtl_digest_get (
199 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
201 Digest_Impl *pImpl = (Digest_Impl *)Digest;
202 if (pImpl && pImpl->m_get)
203 return pImpl->m_get (Digest, pBuffer, nBufLen);
204 else
205 return rtl_Digest_E_Argument;
209 * rtl_digest_destroy.
211 void SAL_CALL rtl_digest_destroy (rtlDigest Digest)
213 Digest_Impl *pImpl = (Digest_Impl *)Digest;
214 if (pImpl && pImpl->m_delete)
215 pImpl->m_delete (Digest);
218 /*========================================================================
220 * rtl_digest_MD2 internals.
222 *======================================================================*/
223 #define DIGEST_CBLOCK_MD2 16
224 #define DIGEST_LBLOCK_MD2 16
226 typedef struct digestMD2_context_st
228 sal_uInt32 m_nDatLen;
229 sal_uInt8 m_pData[DIGEST_CBLOCK_MD2];
230 sal_uInt32 m_state[DIGEST_LBLOCK_MD2];
231 sal_uInt32 m_chksum[DIGEST_LBLOCK_MD2];
232 } DigestContextMD2;
234 typedef struct digestMD2_impl_st
236 Digest_Impl m_digest;
237 DigestContextMD2 m_context;
238 } DigestMD2_Impl;
240 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx);
241 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx);
242 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx);
244 static const sal_uInt32 S[256] =
246 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
247 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
248 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
249 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
250 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
251 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
252 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
253 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
254 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
255 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
256 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
257 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
258 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
259 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
260 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
261 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
262 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
263 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
264 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
265 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
266 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
267 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
268 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
269 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
270 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
271 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
272 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
273 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
274 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
275 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
276 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
277 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
281 * __rtl_digest_MD2.
283 static const Digest_Impl __rtl_digest_MD2 =
285 rtl_Digest_AlgorithmMD2,
286 RTL_DIGEST_LENGTH_MD2,
288 NULL,
289 rtl_digest_destroyMD2,
290 rtl_digest_updateMD2,
291 rtl_digest_getMD2
295 * __rtl_digest_initMD2.
297 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx)
299 rtl_zeroMemory (ctx, sizeof (DigestContextMD2));
303 * __rtl_digest_updateMD2.
305 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx)
307 register sal_uInt8 *X;
308 register sal_uInt32 *sp1, *sp2;
309 register sal_uInt32 i, k, t;
311 sal_uInt32 state[48];
313 X = ctx->m_pData;
314 sp1 = ctx->m_state;
315 sp2 = ctx->m_chksum;
317 k = sp2[DIGEST_LBLOCK_MD2 - 1];
318 for (i = 0; i < 16; i++)
320 state[i + 0] = sp1[i];
321 state[i + 16] = t = X[i];
322 state[i + 32] = t ^ sp1[i];
323 k = sp2[i] ^= S[t^k];
326 t = 0;
327 for (i = 0; i < 18; i++)
329 for (k = 0; k < 48; k += 8)
331 t = state[k + 0] ^= S[t];
332 t = state[k + 1] ^= S[t];
333 t = state[k + 2] ^= S[t];
334 t = state[k + 3] ^= S[t];
335 t = state[k + 4] ^= S[t];
336 t = state[k + 5] ^= S[t];
337 t = state[k + 6] ^= S[t];
338 t = state[k + 7] ^= S[t];
340 t = ((t + i) & 0xff);
343 rtl_copyMemory (sp1, state, 16 * sizeof(sal_uInt32));
344 rtl_zeroMemory (state, 48 * sizeof(sal_uInt32));
348 * __rtl_digest_endMD2.
350 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx)
352 register sal_uInt8 *X;
353 register sal_uInt32 *C;
354 sal_uInt32 i, n;
356 X = ctx->m_pData;
357 C = ctx->m_chksum;
358 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
360 for (i = ctx->m_nDatLen; i < DIGEST_CBLOCK_MD2; i++)
361 X[i] = (sal_uInt8)(n & 0xff);
362 __rtl_digest_updateMD2 (ctx);
364 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
365 X[i] = (sal_uInt8)(C[i] & 0xff);
366 __rtl_digest_updateMD2 (ctx);
369 /*========================================================================
371 * rtl_digest_MD2 implementation.
373 *======================================================================*/
375 * rtl_digest_MD2.
377 rtlDigestError SAL_CALL rtl_digest_MD2 (
378 const void *pData, sal_uInt32 nDatLen,
379 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
381 DigestMD2_Impl digest;
382 rtlDigestError result;
384 digest.m_digest = __rtl_digest_MD2;
385 __rtl_digest_initMD2 (&(digest.m_context));
387 result = rtl_digest_updateMD2 (&digest, pData, nDatLen);
388 if (result == rtl_Digest_E_None)
389 result = rtl_digest_getMD2 (&digest, pBuffer, nBufLen);
391 rtl_zeroMemory (&digest, sizeof (digest));
392 return (result);
396 * rtl_digest_createMD2.
398 rtlDigest SAL_CALL rtl_digest_createMD2 (void)
400 DigestMD2_Impl *pImpl = (DigestMD2_Impl*)NULL;
401 pImpl = RTL_DIGEST_CREATE(DigestMD2_Impl);
402 if (pImpl)
404 pImpl->m_digest = __rtl_digest_MD2;
405 __rtl_digest_initMD2 (&(pImpl->m_context));
407 return ((rtlDigest)pImpl);
411 * rtl_digest_updateMD2.
413 rtlDigestError SAL_CALL rtl_digest_updateMD2 (
414 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
416 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
417 const sal_uInt8 *d = (const sal_uInt8 *)pData;
419 DigestContextMD2 *ctx;
421 if ((pImpl == NULL) || (pData == NULL))
422 return rtl_Digest_E_Argument;
424 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
425 return rtl_Digest_E_Algorithm;
427 if (nDatLen == 0)
428 return rtl_Digest_E_None;
430 ctx = &(pImpl->m_context);
432 if (ctx->m_nDatLen)
434 sal_uInt8 *p = ctx->m_pData + ctx->m_nDatLen;
435 sal_uInt32 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
437 if (nDatLen < n)
439 rtl_copyMemory (p, d, nDatLen);
440 ctx->m_nDatLen += nDatLen;
442 return rtl_Digest_E_None;
445 rtl_copyMemory (p, d, n);
446 d += n;
447 nDatLen -= n;
449 __rtl_digest_updateMD2 (ctx);
450 ctx->m_nDatLen = 0;
453 while (nDatLen >= DIGEST_CBLOCK_MD2)
455 rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_MD2);
456 d += DIGEST_CBLOCK_MD2;
457 nDatLen -= DIGEST_CBLOCK_MD2;
459 __rtl_digest_updateMD2 (ctx);
462 rtl_copyMemory (ctx->m_pData, d, nDatLen);
463 ctx->m_nDatLen = nDatLen;
465 return rtl_Digest_E_None;
469 * rtl_digest_getMD2.
471 rtlDigestError SAL_CALL rtl_digest_getMD2 (
472 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
474 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
475 sal_uInt32 i;
477 DigestContextMD2 *ctx;
479 if ((pImpl == NULL) || (pBuffer == NULL))
480 return rtl_Digest_E_Argument;
482 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
483 return rtl_Digest_E_Algorithm;
485 if (!(pImpl->m_digest.m_length <= nBufLen))
486 return rtl_Digest_E_BufferSize;
488 ctx = &(pImpl->m_context);
490 __rtl_digest_endMD2 (ctx);
491 for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
492 pBuffer[i] = (sal_uInt8)(ctx->m_state[i] & 0xff);
493 __rtl_digest_initMD2 (ctx);
495 return rtl_Digest_E_None;
499 * rtl_digest_destroyMD2.
501 void SAL_CALL rtl_digest_destroyMD2 (rtlDigest Digest)
503 DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
504 if (pImpl)
506 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2)
507 rtl_freeZeroMemory (pImpl, sizeof (DigestMD2_Impl));
508 else
509 rtl_freeMemory (pImpl);
513 /*========================================================================
515 * rtl_digest_MD5 internals.
517 *======================================================================*/
518 #define DIGEST_CBLOCK_MD5 64
519 #define DIGEST_LBLOCK_MD5 16
521 typedef struct digestMD5_context_st
523 sal_uInt32 m_nDatLen;
524 sal_uInt32 m_pData[DIGEST_LBLOCK_MD5];
525 sal_uInt32 m_nA, m_nB, m_nC, m_nD;
526 sal_uInt32 m_nL, m_nH;
527 } DigestContextMD5;
529 typedef struct digestMD5_impl_st
531 Digest_Impl m_digest;
532 DigestContextMD5 m_context;
533 } DigestMD5_Impl;
535 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx);
536 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx);
537 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx);
539 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
540 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
541 #define H(x,y,z) ((x) ^ (y) ^ (z))
542 #define I(x,y,z) (((x) | (~(z))) ^ (y))
544 #define R0(a,b,c,d,k,s,t) { \
545 a += ((k) + (t) + F((b), (c), (d))); \
546 a = RTL_DIGEST_ROTL(a, s); \
547 a += b; }
549 #define R1(a,b,c,d,k,s,t) { \
550 a += ((k) + (t) + G((b), (c), (d))); \
551 a = RTL_DIGEST_ROTL(a, s); \
552 a += b; }
554 #define R2(a,b,c,d,k,s,t) { \
555 a += ((k) + (t) + H((b), (c), (d))); \
556 a = RTL_DIGEST_ROTL(a, s); \
557 a += b; }
559 #define R3(a,b,c,d,k,s,t) { \
560 a += ((k) + (t) + I((b), (c), (d))); \
561 a = RTL_DIGEST_ROTL(a, s); \
562 a += b; }
565 * __rtl_digest_MD5.
567 static const Digest_Impl __rtl_digest_MD5 =
569 rtl_Digest_AlgorithmMD5,
570 RTL_DIGEST_LENGTH_MD5,
572 NULL,
573 rtl_digest_destroyMD5,
574 rtl_digest_updateMD5,
575 rtl_digest_getMD5
579 * __rtl_digest_initMD5.
581 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx)
583 rtl_zeroMemory (ctx, sizeof (DigestContextMD5));
585 ctx->m_nA = (sal_uInt32)0x67452301L;
586 ctx->m_nB = (sal_uInt32)0xefcdab89L;
587 ctx->m_nC = (sal_uInt32)0x98badcfeL;
588 ctx->m_nD = (sal_uInt32)0x10325476L;
592 * __rtl_digest_updateMD5.
594 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx)
596 register sal_uInt32 A, B, C, D;
597 register sal_uInt32 *X;
599 A = ctx->m_nA;
600 B = ctx->m_nB;
601 C = ctx->m_nC;
602 D = ctx->m_nD;
603 X = ctx->m_pData;
605 R0 (A, B, C, D, X[ 0], 7, 0xd76aa478L);
606 R0 (D, A, B, C, X[ 1], 12, 0xe8c7b756L);
607 R0 (C, D, A, B, X[ 2], 17, 0x242070dbL);
608 R0 (B, C, D, A, X[ 3], 22, 0xc1bdceeeL);
609 R0 (A, B, C, D, X[ 4], 7, 0xf57c0fafL);
610 R0 (D, A, B, C, X[ 5], 12, 0x4787c62aL);
611 R0 (C, D, A, B, X[ 6], 17, 0xa8304613L);
612 R0 (B, C, D, A, X[ 7], 22, 0xfd469501L);
613 R0 (A, B, C, D, X[ 8], 7, 0x698098d8L);
614 R0 (D, A, B, C, X[ 9], 12, 0x8b44f7afL);
615 R0 (C, D, A, B, X[10], 17, 0xffff5bb1L);
616 R0 (B, C, D, A, X[11], 22, 0x895cd7beL);
617 R0 (A, B, C, D, X[12], 7, 0x6b901122L);
618 R0 (D, A, B, C, X[13], 12, 0xfd987193L);
619 R0 (C, D, A, B, X[14], 17, 0xa679438eL);
620 R0 (B, C, D, A, X[15], 22, 0x49b40821L);
622 R1 (A, B, C, D, X[ 1], 5, 0xf61e2562L);
623 R1 (D, A, B, C, X[ 6], 9, 0xc040b340L);
624 R1 (C, D, A, B, X[11], 14, 0x265e5a51L);
625 R1 (B, C, D, A, X[ 0], 20, 0xe9b6c7aaL);
626 R1 (A, B, C, D, X[ 5], 5, 0xd62f105dL);
627 R1 (D, A, B, C, X[10], 9, 0x02441453L);
628 R1 (C, D, A, B, X[15], 14, 0xd8a1e681L);
629 R1 (B, C, D, A, X[ 4], 20, 0xe7d3fbc8L);
630 R1 (A, B, C, D, X[ 9], 5, 0x21e1cde6L);
631 R1 (D, A, B, C, X[14], 9, 0xc33707d6L);
632 R1 (C, D, A, B, X[ 3], 14, 0xf4d50d87L);
633 R1 (B, C, D, A, X[ 8], 20, 0x455a14edL);
634 R1 (A, B, C, D, X[13], 5, 0xa9e3e905L);
635 R1 (D, A, B, C, X[ 2], 9, 0xfcefa3f8L);
636 R1 (C, D, A, B, X[ 7], 14, 0x676f02d9L);
637 R1 (B, C, D, A, X[12], 20, 0x8d2a4c8aL);
639 R2 (A, B, C, D, X[ 5], 4, 0xfffa3942L);
640 R2 (D, A, B, C, X[ 8], 11, 0x8771f681L);
641 R2 (C, D, A, B, X[11], 16, 0x6d9d6122L);
642 R2 (B, C, D, A, X[14], 23, 0xfde5380cL);
643 R2 (A, B, C, D, X[ 1], 4, 0xa4beea44L);
644 R2 (D, A, B, C, X[ 4], 11, 0x4bdecfa9L);
645 R2 (C, D, A, B, X[ 7], 16, 0xf6bb4b60L);
646 R2 (B, C, D, A, X[10], 23, 0xbebfbc70L);
647 R2 (A, B, C, D, X[13], 4, 0x289b7ec6L);
648 R2 (D, A, B, C, X[ 0], 11, 0xeaa127faL);
649 R2 (C, D, A, B, X[ 3], 16, 0xd4ef3085L);
650 R2 (B, C, D, A, X[ 6], 23, 0x04881d05L);
651 R2 (A, B, C, D, X[ 9], 4, 0xd9d4d039L);
652 R2 (D, A, B, C, X[12], 11, 0xe6db99e5L);
653 R2 (C, D, A, B, X[15], 16, 0x1fa27cf8L);
654 R2 (B, C, D, A, X[ 2], 23, 0xc4ac5665L);
656 R3 (A, B, C, D, X[ 0], 6, 0xf4292244L);
657 R3 (D, A, B, C, X[ 7], 10, 0x432aff97L);
658 R3 (C, D, A, B, X[14], 15, 0xab9423a7L);
659 R3 (B, C, D, A, X[ 5], 21, 0xfc93a039L);
660 R3 (A, B, C, D, X[12], 6, 0x655b59c3L);
661 R3 (D, A, B, C, X[ 3], 10, 0x8f0ccc92L);
662 R3 (C, D, A, B, X[10], 15, 0xffeff47dL);
663 R3 (B, C, D, A, X[ 1], 21, 0x85845dd1L);
664 R3 (A, B, C, D, X[ 8], 6, 0x6fa87e4fL);
665 R3 (D, A, B, C, X[15], 10, 0xfe2ce6e0L);
666 R3 (C, D, A, B, X[ 6], 15, 0xa3014314L);
667 R3 (B, C, D, A, X[13], 21, 0x4e0811a1L);
668 R3 (A, B, C, D, X[ 4], 6, 0xf7537e82L);
669 R3 (D, A, B, C, X[11], 10, 0xbd3af235L);
670 R3 (C, D, A, B, X[ 2], 15, 0x2ad7d2bbL);
671 R3 (B, C, D, A, X[ 9], 21, 0xeb86d391L);
673 ctx->m_nA += A;
674 ctx->m_nB += B;
675 ctx->m_nC += C;
676 ctx->m_nD += D;
680 * __rtl_digest_endMD5.
682 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx)
684 static const sal_uInt8 end[4] =
686 0x80, 0x00, 0x00, 0x00
688 register const sal_uInt8 *p = end;
690 register sal_uInt32 *X;
691 register int i;
693 X = ctx->m_pData;
694 i = (ctx->m_nDatLen >> 2);
696 #ifdef OSL_BIGENDIAN
697 __rtl_digest_swapLong (X, i + 1);
698 #endif /* OSL_BIGENDIAN */
700 switch (ctx->m_nDatLen & 0x03)
702 case 1: X[i] &= 0x000000ff; break;
703 case 2: X[i] &= 0x0000ffff; break;
704 case 3: X[i] &= 0x00ffffff; break;
707 switch (ctx->m_nDatLen & 0x03)
709 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
710 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
711 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
712 case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
715 i += 1;
717 if (i >= (DIGEST_LBLOCK_MD5 - 2))
719 for (; i < DIGEST_LBLOCK_MD5; i++)
720 X[i] = 0;
721 __rtl_digest_updateMD5 (ctx);
722 i = 0;
725 for (; i < (DIGEST_LBLOCK_MD5 - 2); i++)
726 X[i] = 0;
728 X[DIGEST_LBLOCK_MD5 - 2] = ctx->m_nL;
729 X[DIGEST_LBLOCK_MD5 - 1] = ctx->m_nH;
731 __rtl_digest_updateMD5 (ctx);
734 /*========================================================================
736 * rtl_digest_MD5 implementation.
738 *======================================================================*/
740 * rtl_digest_MD5.
742 rtlDigestError SAL_CALL rtl_digest_MD5 (
743 const void *pData, sal_uInt32 nDatLen,
744 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
746 DigestMD5_Impl digest;
747 rtlDigestError result;
749 digest.m_digest = __rtl_digest_MD5;
750 __rtl_digest_initMD5 (&(digest.m_context));
752 result = rtl_digest_update (&digest, pData, nDatLen);
753 if (result == rtl_Digest_E_None)
754 result = rtl_digest_getMD5 (&digest, pBuffer, nBufLen);
756 rtl_zeroMemory (&digest, sizeof (digest));
757 return (result);
761 * rtl_digest_createMD5.
763 rtlDigest SAL_CALL rtl_digest_createMD5 (void)
765 DigestMD5_Impl *pImpl = (DigestMD5_Impl*)NULL;
766 pImpl = RTL_DIGEST_CREATE(DigestMD5_Impl);
767 if (pImpl)
769 pImpl->m_digest = __rtl_digest_MD5;
770 __rtl_digest_initMD5 (&(pImpl->m_context));
772 return ((rtlDigest)pImpl);
776 * rtl_digest_updateMD5.
778 rtlDigestError SAL_CALL rtl_digest_updateMD5 (
779 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
781 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
782 const sal_uInt8 *d = (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 = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
806 sal_uInt32 n = DIGEST_CBLOCK_MD5 - ctx->m_nDatLen;
808 if (nDatLen < n)
810 rtl_copyMemory (p, d, nDatLen);
811 ctx->m_nDatLen += nDatLen;
813 return rtl_Digest_E_None;
816 rtl_copyMemory (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 rtl_copyMemory (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 rtl_copyMemory (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)
853 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
854 sal_uInt8 *p = pBuffer;
856 DigestContextMD5 *ctx;
858 if ((pImpl == NULL) || (pBuffer == NULL))
859 return rtl_Digest_E_Argument;
861 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
862 return rtl_Digest_E_Algorithm;
864 if (!(pImpl->m_digest.m_length <= nBufLen))
865 return rtl_Digest_E_BufferSize;
867 ctx = &(pImpl->m_context);
869 __rtl_digest_endMD5 (ctx);
870 RTL_DIGEST_LTOC (ctx->m_nA, p);
871 RTL_DIGEST_LTOC (ctx->m_nB, p);
872 RTL_DIGEST_LTOC (ctx->m_nC, p);
873 RTL_DIGEST_LTOC (ctx->m_nD, p);
874 __rtl_digest_initMD5 (ctx);
876 return rtl_Digest_E_None;
880 * rtl_digest_rawMD5.
882 rtlDigestError SAL_CALL rtl_digest_rawMD5 (
883 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
885 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
886 sal_uInt8 *p = pBuffer;
888 DigestContextMD5 *ctx;
890 if ((pImpl == NULL) || (pBuffer == NULL))
891 return rtl_Digest_E_Argument;
893 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
894 return rtl_Digest_E_Algorithm;
896 if (!(pImpl->m_digest.m_length <= nBufLen))
897 return rtl_Digest_E_BufferSize;
899 ctx = &(pImpl->m_context);
901 /* __rtl_digest_endMD5 (ctx); *//* not finalized */
902 RTL_DIGEST_LTOC (ctx->m_nA, p);
903 RTL_DIGEST_LTOC (ctx->m_nB, p);
904 RTL_DIGEST_LTOC (ctx->m_nC, p);
905 RTL_DIGEST_LTOC (ctx->m_nD, p);
906 __rtl_digest_initMD5 (ctx);
908 return rtl_Digest_E_None;
912 * rtl_digest_destroyMD5.
914 void SAL_CALL rtl_digest_destroyMD5 (rtlDigest Digest)
916 DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
917 if (pImpl)
919 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5)
920 rtl_freeZeroMemory (pImpl, sizeof (DigestMD5_Impl));
921 else
922 rtl_freeMemory (pImpl);
926 /*========================================================================
928 * rtl_digest_(SHA|SHA1) common internals.
930 *======================================================================*/
931 #define DIGEST_CBLOCK_SHA 64
932 #define DIGEST_LBLOCK_SHA 16
934 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x);
936 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x);
937 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x);
939 typedef struct digestSHA_context_st
941 DigestSHA_update_t *m_update;
942 sal_uInt32 m_nDatLen;
943 sal_uInt32 m_pData[DIGEST_LBLOCK_SHA];
944 sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE;
945 sal_uInt32 m_nL, m_nH;
946 } DigestContextSHA;
948 typedef struct digestSHA_impl_st
950 Digest_Impl m_digest;
951 DigestContextSHA m_context;
952 } DigestSHA_Impl;
954 static void __rtl_digest_initSHA (
955 DigestContextSHA *ctx, DigestSHA_update_t *fct);
957 static void __rtl_digest_updateSHA (DigestContextSHA *ctx);
958 static void __rtl_digest_endSHA (DigestContextSHA *ctx);
960 #define K_00_19 (sal_uInt32)0x5a827999L
961 #define K_20_39 (sal_uInt32)0x6ed9eba1L
962 #define K_40_59 (sal_uInt32)0x8f1bbcdcL
963 #define K_60_79 (sal_uInt32)0xca62c1d6L
965 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
966 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
967 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
968 #define F_60_79(b,c,d) F_20_39(b,c,d)
970 #define BODY_X(i) \
971 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
973 #define BODY_00_15(u,i,a,b,c,d,e,f) \
974 (f) = X[i]; \
975 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
976 (b) = RTL_DIGEST_ROTL((b), 30);
978 #define BODY_16_19(u,i,a,b,c,d,e,f) \
979 (f) = BODY_X((i)); \
980 (f) = X[(i)&0x0f] = (u)((f)); \
981 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
982 (b) = RTL_DIGEST_ROTL((b), 30);
984 #define BODY_20_39(u,i,a,b,c,d,e,f) \
985 (f) = BODY_X((i)); \
986 (f) = X[(i)&0x0f] = (u)((f)); \
987 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
988 (b) = RTL_DIGEST_ROTL((b), 30);
990 #define BODY_40_59(u,i,a,b,c,d,e,f) \
991 (f) = BODY_X((i)); \
992 (f) = X[(i)&0x0f] = (u)((f)); \
993 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
994 (b) = RTL_DIGEST_ROTL((b), 30);
996 #define BODY_60_79(u,i,a,b,c,d,e,f) \
997 (f) = BODY_X((i)); \
998 (f) = X[(i)&0x0f] = (u)((f)); \
999 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
1000 (b) = RTL_DIGEST_ROTL((b), 30);
1003 * __rtl_digest_initSHA.
1005 static void __rtl_digest_initSHA (
1006 DigestContextSHA *ctx, DigestSHA_update_t *fct)
1008 rtl_zeroMemory (ctx, sizeof (DigestContextSHA));
1009 ctx->m_update = fct;
1011 ctx->m_nA = (sal_uInt32)0x67452301L;
1012 ctx->m_nB = (sal_uInt32)0xefcdab89L;
1013 ctx->m_nC = (sal_uInt32)0x98badcfeL;
1014 ctx->m_nD = (sal_uInt32)0x10325476L;
1015 ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
1019 * __rtl_digest_updateSHA.
1021 static void __rtl_digest_updateSHA (DigestContextSHA *ctx)
1023 register sal_uInt32 A, B, C, D, E, T;
1024 register sal_uInt32 *X;
1026 register DigestSHA_update_t *U;
1027 U = ctx->m_update;
1029 A = ctx->m_nA;
1030 B = ctx->m_nB;
1031 C = ctx->m_nC;
1032 D = ctx->m_nD;
1033 E = ctx->m_nE;
1034 X = ctx->m_pData;
1036 BODY_00_15 (U, 0, A, B, C, D, E, T);
1037 BODY_00_15 (U, 1, T, A, B, C, D, E);
1038 BODY_00_15 (U, 2, E, T, A, B, C, D);
1039 BODY_00_15 (U, 3, D, E, T, A, B, C);
1040 BODY_00_15 (U, 4, C, D, E, T, A, B);
1041 BODY_00_15 (U, 5, B, C, D, E, T, A);
1042 BODY_00_15 (U, 6, A, B, C, D, E, T);
1043 BODY_00_15 (U, 7, T, A, B, C, D, E);
1044 BODY_00_15 (U, 8, E, T, A, B, C, D);
1045 BODY_00_15 (U, 9, D, E, T, A, B, C);
1046 BODY_00_15 (U, 10, C, D, E, T, A, B);
1047 BODY_00_15 (U, 11, B, C, D, E, T, A);
1048 BODY_00_15 (U, 12, A, B, C, D, E, T);
1049 BODY_00_15 (U, 13, T, A, B, C, D, E);
1050 BODY_00_15 (U, 14, E, T, A, B, C, D);
1051 BODY_00_15 (U, 15, D, E, T, A, B, C);
1052 BODY_16_19 (U, 16, C, D, E, T, A, B);
1053 BODY_16_19 (U, 17, B, C, D, E, T, A);
1054 BODY_16_19 (U, 18, A, B, C, D, E, T);
1055 BODY_16_19 (U, 19, T, A, B, C, D, E);
1057 BODY_20_39 (U, 20, E, T, A, B, C, D);
1058 BODY_20_39 (U, 21, D, E, T, A, B, C);
1059 BODY_20_39 (U, 22, C, D, E, T, A, B);
1060 BODY_20_39 (U, 23, B, C, D, E, T, A);
1061 BODY_20_39 (U, 24, A, B, C, D, E, T);
1062 BODY_20_39 (U, 25, T, A, B, C, D, E);
1063 BODY_20_39 (U, 26, E, T, A, B, C, D);
1064 BODY_20_39 (U, 27, D, E, T, A, B, C);
1065 BODY_20_39 (U, 28, C, D, E, T, A, B);
1066 BODY_20_39 (U, 29, B, C, D, E, T, A);
1067 BODY_20_39 (U, 30, A, B, C, D, E, T);
1068 BODY_20_39 (U, 31, T, A, B, C, D, E);
1069 BODY_20_39 (U, 32, E, T, A, B, C, D);
1070 BODY_20_39 (U, 33, D, E, T, A, B, C);
1071 BODY_20_39 (U, 34, C, D, E, T, A, B);
1072 BODY_20_39 (U, 35, B, C, D, E, T, A);
1073 BODY_20_39 (U, 36, A, B, C, D, E, T);
1074 BODY_20_39 (U, 37, T, A, B, C, D, E);
1075 BODY_20_39 (U, 38, E, T, A, B, C, D);
1076 BODY_20_39 (U, 39, D, E, T, A, B, C);
1078 BODY_40_59 (U, 40, C, D, E, T, A, B);
1079 BODY_40_59 (U, 41, B, C, D, E, T, A);
1080 BODY_40_59 (U, 42, A, B, C, D, E, T);
1081 BODY_40_59 (U, 43, T, A, B, C, D, E);
1082 BODY_40_59 (U, 44, E, T, A, B, C, D);
1083 BODY_40_59 (U, 45, D, E, T, A, B, C);
1084 BODY_40_59 (U, 46, C, D, E, T, A, B);
1085 BODY_40_59 (U, 47, B, C, D, E, T, A);
1086 BODY_40_59 (U, 48, A, B, C, D, E, T);
1087 BODY_40_59 (U, 49, T, A, B, C, D, E);
1088 BODY_40_59 (U, 50, E, T, A, B, C, D);
1089 BODY_40_59 (U, 51, D, E, T, A, B, C);
1090 BODY_40_59 (U, 52, C, D, E, T, A, B);
1091 BODY_40_59 (U, 53, B, C, D, E, T, A);
1092 BODY_40_59 (U, 54, A, B, C, D, E, T);
1093 BODY_40_59 (U, 55, T, A, B, C, D, E);
1094 BODY_40_59 (U, 56, E, T, A, B, C, D);
1095 BODY_40_59 (U, 57, D, E, T, A, B, C);
1096 BODY_40_59 (U, 58, C, D, E, T, A, B);
1097 BODY_40_59 (U, 59, B, C, D, E, T, A);
1099 BODY_60_79 (U, 60, A, B, C, D, E, T);
1100 BODY_60_79 (U, 61, T, A, B, C, D, E);
1101 BODY_60_79 (U, 62, E, T, A, B, C, D);
1102 BODY_60_79 (U, 63, D, E, T, A, B, C);
1103 BODY_60_79 (U, 64, C, D, E, T, A, B);
1104 BODY_60_79 (U, 65, B, C, D, E, T, A);
1105 BODY_60_79 (U, 66, A, B, C, D, E, T);
1106 BODY_60_79 (U, 67, T, A, B, C, D, E);
1107 BODY_60_79 (U, 68, E, T, A, B, C, D);
1108 BODY_60_79 (U, 69, D, E, T, A, B, C);
1109 BODY_60_79 (U, 70, C, D, E, T, A, B);
1110 BODY_60_79 (U, 71, B, C, D, E, T, A);
1111 BODY_60_79 (U, 72, A, B, C, D, E, T);
1112 BODY_60_79 (U, 73, T, A, B, C, D, E);
1113 BODY_60_79 (U, 74, E, T, A, B, C, D);
1114 BODY_60_79 (U, 75, D, E, T, A, B, C);
1115 BODY_60_79 (U, 76, C, D, E, T, A, B);
1116 BODY_60_79 (U, 77, B, C, D, E, T, A);
1117 BODY_60_79 (U, 78, A, B, C, D, E, T);
1118 BODY_60_79 (U, 79, T, A, B, C, D, E);
1120 ctx->m_nA += E;
1121 ctx->m_nB += T;
1122 ctx->m_nC += A;
1123 ctx->m_nD += B;
1124 ctx->m_nE += C;
1128 * __rtl_digest_endSHA.
1130 static void __rtl_digest_endSHA (DigestContextSHA *ctx)
1132 static const sal_uInt8 end[4] =
1134 0x80, 0x00, 0x00, 0x00
1136 register const sal_uInt8 *p = end;
1138 register sal_uInt32 *X;
1139 register int i;
1141 X = ctx->m_pData;
1142 i = (ctx->m_nDatLen >> 2);
1144 #ifdef OSL_BIGENDIAN
1145 __rtl_digest_swapLong (X, i + 1);
1146 #endif /* OSL_BIGENDIAN */
1148 switch (ctx->m_nDatLen & 0x03)
1150 case 1: X[i] &= 0x000000ff; break;
1151 case 2: X[i] &= 0x0000ffff; break;
1152 case 3: X[i] &= 0x00ffffff; break;
1155 switch (ctx->m_nDatLen & 0x03)
1157 case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L;
1158 case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L;
1159 case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
1160 case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
1163 __rtl_digest_swapLong (X, i + 1);
1165 i += 1;
1167 if (i >= (DIGEST_LBLOCK_SHA - 2))
1169 for (; i < DIGEST_LBLOCK_SHA; i++)
1170 X[i] = 0;
1171 __rtl_digest_updateSHA (ctx);
1172 i = 0;
1175 for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
1176 X[i] = 0;
1178 X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
1179 X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
1181 __rtl_digest_updateSHA (ctx);
1184 /*========================================================================
1186 * rtl_digest_SHA internals.
1188 *======================================================================*/
1190 * __rtl_digest_SHA_0.
1192 static const Digest_Impl __rtl_digest_SHA_0 =
1194 rtl_Digest_AlgorithmSHA,
1195 RTL_DIGEST_LENGTH_SHA,
1197 NULL,
1198 rtl_digest_destroySHA,
1199 rtl_digest_updateSHA,
1200 rtl_digest_getSHA
1204 * __rtl_digest_updateSHA_0.
1206 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x)
1208 return x;
1211 /*========================================================================
1213 * rtl_digest_SHA implementation.
1215 *======================================================================*/
1217 * rtl_digest_SHA.
1219 rtlDigestError SAL_CALL rtl_digest_SHA (
1220 const void *pData, sal_uInt32 nDatLen,
1221 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1223 DigestSHA_Impl digest;
1224 rtlDigestError result;
1226 digest.m_digest = __rtl_digest_SHA_0;
1227 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_0);
1229 result = rtl_digest_updateSHA (&digest, pData, nDatLen);
1230 if (result == rtl_Digest_E_None)
1231 result = rtl_digest_getSHA (&digest, pBuffer, nBufLen);
1233 rtl_zeroMemory (&digest, sizeof (digest));
1234 return (result);
1238 * rtl_digest_createSHA.
1240 rtlDigest SAL_CALL rtl_digest_createSHA (void)
1242 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1243 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1244 if (pImpl)
1246 pImpl->m_digest = __rtl_digest_SHA_0;
1247 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_0);
1249 return ((rtlDigest)pImpl);
1253 * rtl_digest_updateSHA.
1255 rtlDigestError SAL_CALL rtl_digest_updateSHA (
1256 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
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 rtl_copyMemory (p, d, nDatLen);
1288 ctx->m_nDatLen += nDatLen;
1290 return rtl_Digest_E_None;
1293 rtl_copyMemory (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 rtl_copyMemory (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 rtl_copyMemory (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)
1330 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1331 sal_uInt8 *p = pBuffer;
1333 DigestContextSHA *ctx;
1335 if ((pImpl == NULL) || (pBuffer == NULL))
1336 return rtl_Digest_E_Argument;
1338 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1339 return rtl_Digest_E_Algorithm;
1341 if (!(pImpl->m_digest.m_length <= nBufLen))
1342 return rtl_Digest_E_BufferSize;
1344 ctx = &(pImpl->m_context);
1346 __rtl_digest_endSHA (ctx);
1347 RTL_DIGEST_HTONL (ctx->m_nA, p);
1348 RTL_DIGEST_HTONL (ctx->m_nB, p);
1349 RTL_DIGEST_HTONL (ctx->m_nC, p);
1350 RTL_DIGEST_HTONL (ctx->m_nD, p);
1351 RTL_DIGEST_HTONL (ctx->m_nE, p);
1352 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_0);
1354 return rtl_Digest_E_None;
1358 * rtl_digest_destroySHA.
1360 void SAL_CALL rtl_digest_destroySHA (rtlDigest Digest)
1362 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1363 if (pImpl)
1365 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA)
1366 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1367 else
1368 rtl_freeMemory (pImpl);
1372 /*========================================================================
1374 * rtl_digest_SHA1 internals.
1376 *======================================================================*/
1378 * __rtl_digest_SHA_1.
1380 static const Digest_Impl __rtl_digest_SHA_1 =
1382 rtl_Digest_AlgorithmSHA1,
1383 RTL_DIGEST_LENGTH_SHA1,
1385 NULL,
1386 rtl_digest_destroySHA1,
1387 rtl_digest_updateSHA1,
1388 rtl_digest_getSHA1
1392 * __rtl_digest_updateSHA_1.
1394 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
1396 return RTL_DIGEST_ROTL (x, 1);
1399 /*========================================================================
1401 * rtl_digest_SHA1 implementation.
1403 *======================================================================*/
1405 * rtl_digest_SHA1.
1407 rtlDigestError SAL_CALL rtl_digest_SHA1 (
1408 const void *pData, sal_uInt32 nDatLen,
1409 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1411 DigestSHA_Impl digest;
1412 rtlDigestError result;
1414 digest.m_digest = __rtl_digest_SHA_1;
1415 __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
1417 result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
1418 if (result == rtl_Digest_E_None)
1419 result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
1421 rtl_zeroMemory (&digest, sizeof (digest));
1422 return (result);
1426 * rtl_digest_createSHA1.
1428 rtlDigest SAL_CALL rtl_digest_createSHA1 (void)
1430 DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1431 pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1432 if (pImpl)
1434 pImpl->m_digest = __rtl_digest_SHA_1;
1435 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1437 return ((rtlDigest)pImpl);
1441 * rtl_digest_updateSHA1.
1443 rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
1444 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1446 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1447 const sal_uInt8 *d = (const sal_uInt8 *)pData;
1449 DigestContextSHA *ctx;
1450 sal_uInt32 len;
1452 if ((pImpl == NULL) || (pData == NULL))
1453 return rtl_Digest_E_Argument;
1455 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1456 return rtl_Digest_E_Algorithm;
1458 if (nDatLen == 0)
1459 return rtl_Digest_E_None;
1461 ctx = &(pImpl->m_context);
1463 len = ctx->m_nL + (nDatLen << 3);
1464 if (len < ctx->m_nL) ctx->m_nH += 1;
1465 ctx->m_nH += (nDatLen >> 29);
1466 ctx->m_nL = len;
1468 if (ctx->m_nDatLen)
1470 sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
1471 sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1473 if (nDatLen < n)
1475 rtl_copyMemory (p, d, nDatLen);
1476 ctx->m_nDatLen += nDatLen;
1478 return rtl_Digest_E_None;
1481 rtl_copyMemory (p, d, n);
1482 d += n;
1483 nDatLen -= n;
1485 #ifndef OSL_BIGENDIAN
1486 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1487 #endif /* OSL_BIGENDIAN */
1489 __rtl_digest_updateSHA (ctx);
1490 ctx->m_nDatLen = 0;
1493 while (nDatLen >= DIGEST_CBLOCK_SHA)
1495 rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1496 d += DIGEST_CBLOCK_SHA;
1497 nDatLen -= DIGEST_CBLOCK_SHA;
1499 #ifndef OSL_BIGENDIAN
1500 __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1501 #endif /* OSL_BIGENDIAN */
1503 __rtl_digest_updateSHA (ctx);
1506 rtl_copyMemory (ctx->m_pData, d, nDatLen);
1507 ctx->m_nDatLen = nDatLen;
1509 return rtl_Digest_E_None;
1513 * rtl_digest_getSHA1.
1515 rtlDigestError SAL_CALL rtl_digest_getSHA1 (
1516 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1518 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1519 sal_uInt8 *p = pBuffer;
1521 DigestContextSHA *ctx;
1523 if ((pImpl == NULL) || (pBuffer == NULL))
1524 return rtl_Digest_E_Argument;
1526 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1527 return rtl_Digest_E_Algorithm;
1529 if (!(pImpl->m_digest.m_length <= nBufLen))
1530 return rtl_Digest_E_BufferSize;
1532 ctx = &(pImpl->m_context);
1534 __rtl_digest_endSHA (ctx);
1535 RTL_DIGEST_HTONL (ctx->m_nA, p);
1536 RTL_DIGEST_HTONL (ctx->m_nB, p);
1537 RTL_DIGEST_HTONL (ctx->m_nC, p);
1538 RTL_DIGEST_HTONL (ctx->m_nD, p);
1539 RTL_DIGEST_HTONL (ctx->m_nE, p);
1540 __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
1542 return rtl_Digest_E_None;
1546 * rtl_digest_destroySHA1.
1548 void SAL_CALL rtl_digest_destroySHA1 (rtlDigest Digest)
1550 DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1551 if (pImpl)
1553 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
1554 rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1555 else
1556 rtl_freeMemory (pImpl);
1560 /*========================================================================
1562 * rtl_digest_HMAC_MD5 internals.
1564 *======================================================================*/
1565 #define DIGEST_CBLOCK_HMAC_MD5 64
1567 typedef struct _contextHMAC_MD5_st
1569 DigestMD5_Impl m_hash;
1570 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_MD5];
1571 } ContextHMAC_MD5;
1573 typedef struct _digestHMAC_MD5_impl_st
1575 Digest_Impl m_digest;
1576 ContextHMAC_MD5 m_context;
1577 } DigestHMAC_MD5_Impl;
1579 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx);
1580 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1581 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1584 * __rtl_digest_HMAC_MD5.
1586 static const Digest_Impl __rtl_digest_HMAC_MD5 =
1588 rtl_Digest_AlgorithmHMAC_MD5,
1589 RTL_DIGEST_LENGTH_MD5,
1591 rtl_digest_initHMAC_MD5,
1592 rtl_digest_destroyHMAC_MD5,
1593 rtl_digest_updateHMAC_MD5,
1594 rtl_digest_getHMAC_MD5
1598 * __rtl_digest_initHMAC_MD5.
1600 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx)
1602 DigestMD5_Impl *pImpl = &(ctx->m_hash);
1604 pImpl->m_digest = __rtl_digest_MD5;
1605 __rtl_digest_initMD5 (&(pImpl->m_context));
1607 rtl_zeroMemory (ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1611 * __rtl_digest_ipadHMAC_MD5.
1613 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1615 register sal_uInt32 i;
1617 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1618 ctx->m_opad[i] ^= 0x36;
1619 rtl_digest_updateMD5 (
1620 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1621 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1622 ctx->m_opad[i] ^= 0x36;
1626 * __rtl_digest_opadHMAC_MD5.
1628 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1630 register sal_uInt32 i;
1632 for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1633 ctx->m_opad[i] ^= 0x5c;
1636 /*========================================================================
1638 * rtl_digest_HMAC_MD5 implementation.
1640 *======================================================================*/
1642 * rtl_digest_HMAC_MD5.
1644 rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
1645 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1646 const void *pData, sal_uInt32 nDatLen,
1647 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1649 DigestHMAC_MD5_Impl digest;
1650 rtlDigestError result;
1652 digest.m_digest = __rtl_digest_HMAC_MD5;
1654 result = rtl_digest_initHMAC_MD5 (&digest, pKeyData, nKeyLen);
1655 if (result == rtl_Digest_E_None)
1657 result = rtl_digest_updateHMAC_MD5 (&digest, pData, nDatLen);
1658 if (result == rtl_Digest_E_None)
1659 result = rtl_digest_getHMAC_MD5 (&digest, pBuffer, nBufLen);
1662 rtl_zeroMemory (&digest, sizeof (digest));
1663 return (result);
1667 * rtl_digest_createHMAC_MD5.
1669 rtlDigest SAL_CALL rtl_digest_createHMAC_MD5 (void)
1671 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)NULL;
1672 pImpl = RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl);
1673 if (pImpl)
1675 pImpl->m_digest = __rtl_digest_HMAC_MD5;
1676 __rtl_digest_initHMAC_MD5 (&(pImpl->m_context));
1678 return ((rtlDigest)pImpl);
1682 * rtl_digest_initHMAC_MD5.
1684 rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
1685 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1687 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1688 ContextHMAC_MD5 *ctx;
1690 if ((pImpl == NULL) || (pKeyData == NULL))
1691 return rtl_Digest_E_Argument;
1693 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1694 return rtl_Digest_E_Algorithm;
1696 ctx = &(pImpl->m_context);
1697 __rtl_digest_initHMAC_MD5 (ctx);
1699 if (nKeyLen > DIGEST_CBLOCK_HMAC_MD5)
1701 /* Initialize 'opad' with hashed 'KeyData' */
1702 rtl_digest_updateMD5 (
1703 &(ctx->m_hash), pKeyData, nKeyLen);
1704 rtl_digest_getMD5 (
1705 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_MD5);
1707 else
1709 /* Initialize 'opad' with plain 'KeyData' */
1710 rtl_copyMemory (ctx->m_opad, pKeyData, nKeyLen);
1713 __rtl_digest_ipadHMAC_MD5 (ctx);
1714 __rtl_digest_opadHMAC_MD5 (ctx);
1716 return rtl_Digest_E_None;
1720 * rtl_digest_updateHMAC_MD5.
1722 rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
1723 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1725 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1726 ContextHMAC_MD5 *ctx;
1728 if ((pImpl == NULL) || (pData == NULL))
1729 return rtl_Digest_E_Argument;
1731 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1732 return rtl_Digest_E_Algorithm;
1734 ctx = &(pImpl->m_context);
1735 rtl_digest_updateMD5 (&(ctx->m_hash), pData, nDatLen);
1737 return rtl_Digest_E_None;
1741 * rtl_digest_getHMAC_MD5.
1743 rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
1744 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1746 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1747 ContextHMAC_MD5 *ctx;
1749 if ((pImpl == NULL) || (pBuffer == NULL))
1750 return rtl_Digest_E_Argument;
1752 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1753 return rtl_Digest_E_Algorithm;
1755 if (!(pImpl->m_digest.m_length <= nBufLen))
1756 return rtl_Digest_E_BufferSize;
1758 nBufLen = pImpl->m_digest.m_length;
1760 ctx = &(pImpl->m_context);
1761 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1763 rtl_digest_updateMD5 (&(ctx->m_hash), ctx->m_opad, 64);
1764 rtl_digest_updateMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1765 rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1767 __rtl_digest_opadHMAC_MD5 (ctx);
1768 __rtl_digest_ipadHMAC_MD5 (ctx);
1769 __rtl_digest_opadHMAC_MD5 (ctx);
1771 return rtl_Digest_E_None;
1775 * rtl_digest_destroyHMAC_MD5.
1777 void SAL_CALL rtl_digest_destroyHMAC_MD5 (rtlDigest Digest)
1779 DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1780 if (pImpl)
1782 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5)
1783 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_MD5_Impl));
1784 else
1785 rtl_freeMemory (pImpl);
1789 /*========================================================================
1791 * rtl_digest_HMAC_SHA1 internals.
1793 *======================================================================*/
1794 #define DIGEST_CBLOCK_HMAC_SHA1 64
1796 typedef struct _contextHMAC_SHA1_st
1798 DigestSHA_Impl m_hash;
1799 sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_SHA1];
1800 } ContextHMAC_SHA1;
1802 typedef struct _digestHMAC_SHA1_impl_st
1804 Digest_Impl m_digest;
1805 ContextHMAC_SHA1 m_context;
1806 } DigestHMAC_SHA1_Impl;
1808 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1809 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1810 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1813 * __rtl_digest_HMAC_SHA1.
1815 static const Digest_Impl __rtl_digest_HMAC_SHA1 =
1817 rtl_Digest_AlgorithmHMAC_SHA1,
1818 RTL_DIGEST_LENGTH_SHA1,
1820 rtl_digest_initHMAC_SHA1,
1821 rtl_digest_destroyHMAC_SHA1,
1822 rtl_digest_updateHMAC_SHA1,
1823 rtl_digest_getHMAC_SHA1
1827 * __rtl_digest_initHMAC_SHA1.
1829 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1831 DigestSHA_Impl *pImpl = &(ctx->m_hash);
1833 pImpl->m_digest = __rtl_digest_SHA_1;
1834 __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1836 rtl_zeroMemory (ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1840 * __rtl_digest_ipadHMAC_SHA1.
1842 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1844 register sal_uInt32 i;
1846 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1847 ctx->m_opad[i] ^= 0x36;
1848 rtl_digest_updateSHA1 (
1849 &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1850 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1851 ctx->m_opad[i] ^= 0x36;
1855 * __rtl_digest_opadHMAC_SHA1.
1857 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1859 register sal_uInt32 i;
1861 for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1862 ctx->m_opad[i] ^= 0x5c;
1865 /*========================================================================
1867 * rtl_digest_HMAC_SHA1 implementation.
1869 *======================================================================*/
1871 * rtl_digest_HMAC_SHA1.
1873 rtlDigestError SAL_CALL rtl_digest_HMAC_SHA1 (
1874 const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1875 const void *pData, sal_uInt32 nDatLen,
1876 sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1878 DigestHMAC_SHA1_Impl digest;
1879 rtlDigestError result;
1881 digest.m_digest = __rtl_digest_HMAC_SHA1;
1883 result = rtl_digest_initHMAC_SHA1 (&digest, pKeyData, nKeyLen);
1884 if (result == rtl_Digest_E_None)
1886 result = rtl_digest_updateHMAC_SHA1 (&digest, pData, nDatLen);
1887 if (result == rtl_Digest_E_None)
1888 result = rtl_digest_getHMAC_SHA1 (&digest, pBuffer, nBufLen);
1891 rtl_zeroMemory (&digest, sizeof (digest));
1892 return (result);
1896 * rtl_digest_createHMAC_SHA1.
1898 rtlDigest SAL_CALL rtl_digest_createHMAC_SHA1 (void)
1900 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)NULL;
1901 pImpl = RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl);
1902 if (pImpl)
1904 pImpl->m_digest = __rtl_digest_HMAC_SHA1;
1905 __rtl_digest_initHMAC_SHA1 (&(pImpl->m_context));
1907 return ((rtlDigest)pImpl);
1911 * rtl_digest_initHMAC_SHA1.
1913 rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
1914 rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1916 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1917 ContextHMAC_SHA1 *ctx;
1919 if ((pImpl == NULL) || (pKeyData == NULL))
1920 return rtl_Digest_E_Argument;
1922 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1923 return rtl_Digest_E_Algorithm;
1925 ctx = &(pImpl->m_context);
1926 __rtl_digest_initHMAC_SHA1 (ctx);
1928 if (nKeyLen > DIGEST_CBLOCK_HMAC_SHA1)
1930 /* Initialize 'opad' with hashed 'KeyData' */
1931 rtl_digest_updateSHA1 (
1932 &(ctx->m_hash), pKeyData, nKeyLen);
1933 rtl_digest_getSHA1 (
1934 &(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_SHA1);
1936 else
1938 /* Initialize 'opad' with plain 'KeyData' */
1939 rtl_copyMemory (ctx->m_opad, pKeyData, nKeyLen);
1942 __rtl_digest_ipadHMAC_SHA1 (ctx);
1943 __rtl_digest_opadHMAC_SHA1 (ctx);
1945 return rtl_Digest_E_None;
1949 * rtl_digest_updateHMAC_SHA1.
1951 rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
1952 rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1954 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1955 ContextHMAC_SHA1 *ctx;
1957 if ((pImpl == NULL) || (pData == NULL))
1958 return rtl_Digest_E_Argument;
1960 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1961 return rtl_Digest_E_Algorithm;
1963 ctx = &(pImpl->m_context);
1964 rtl_digest_updateSHA1 (&(ctx->m_hash), pData, nDatLen);
1966 return rtl_Digest_E_None;
1970 * rtl_digest_getHMAC_SHA1.
1972 rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
1973 rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1975 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1976 ContextHMAC_SHA1 *ctx;
1978 if ((pImpl == NULL) || (pBuffer == NULL))
1979 return rtl_Digest_E_Argument;
1981 if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1982 return rtl_Digest_E_Algorithm;
1984 if (!(pImpl->m_digest.m_length <= nBufLen))
1985 return rtl_Digest_E_BufferSize;
1987 nBufLen = pImpl->m_digest.m_length;
1989 ctx = &(pImpl->m_context);
1990 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
1992 rtl_digest_updateSHA1 (&(ctx->m_hash), ctx->m_opad, sizeof(ctx->m_opad));
1993 rtl_digest_updateSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
1994 rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
1996 __rtl_digest_opadHMAC_SHA1 (ctx);
1997 __rtl_digest_ipadHMAC_SHA1 (ctx);
1998 __rtl_digest_opadHMAC_SHA1 (ctx);
2000 return rtl_Digest_E_None;
2004 * rtl_digest_destroyHMAC_SHA1.
2006 void SAL_CALL rtl_digest_destroyHMAC_SHA1 (rtlDigest Digest)
2008 DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
2009 if (pImpl)
2011 if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1)
2012 rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_SHA1_Impl));
2013 else
2014 rtl_freeMemory (pImpl);
2018 /*========================================================================
2020 * rtl_digest_PBKDF2 internals.
2022 *======================================================================*/
2023 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
2026 * __rtl_digest_updatePBKDF2.
2028 static void __rtl_digest_updatePBKDF2 (
2029 rtlDigest hDigest,
2030 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2],
2031 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2032 sal_uInt32 nCount, sal_uInt32 nIndex)
2034 /* T_i = F (P, S, c, i) */
2035 sal_uInt8 U[DIGEST_CBLOCK_PBKDF2];
2036 register sal_uInt32 i, k;
2038 /* U_(1) = PRF (P, S || INDEX) */
2039 rtl_digest_updateHMAC_SHA1 (hDigest, pSaltData, nSaltLen);
2040 rtl_digest_updateHMAC_SHA1 (hDigest, &nIndex, sizeof(nIndex));
2041 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2043 /* T = U_(1) */
2044 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] = U[k];
2046 /* T ^= U_(2) ^ ... ^ U_(c) */
2047 for (i = 1; i < nCount; i++)
2049 /* U_(i) = PRF (P, U_(i-1)) */
2050 rtl_digest_updateHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2051 rtl_digest_getHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2053 /* T ^= U_(i) */
2054 for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] ^= U[k];
2057 rtl_zeroMemory (U, DIGEST_CBLOCK_PBKDF2);
2060 /*========================================================================
2062 * rtl_digest_PBKDF2 implementation.
2064 *======================================================================*/
2066 * rtl_digest_PBKDF2.
2068 rtlDigestError SAL_CALL rtl_digest_PBKDF2 (
2069 sal_uInt8 *pKeyData , sal_uInt32 nKeyLen,
2070 const sal_uInt8 *pPassData, sal_uInt32 nPassLen,
2071 const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2072 sal_uInt32 nCount)
2074 DigestHMAC_SHA1_Impl digest;
2075 sal_uInt32 i = 1;
2077 if ((pKeyData == NULL) || (pPassData == NULL) || (pSaltData == NULL))
2078 return rtl_Digest_E_Argument;
2080 digest.m_digest = __rtl_digest_HMAC_SHA1;
2081 rtl_digest_initHMAC_SHA1 (&digest, pPassData, nPassLen);
2083 /* DK = T_(1) || T_(2) || ... || T_(l) */
2084 while (nKeyLen >= DIGEST_CBLOCK_PBKDF2)
2086 /* T_(i) = F (P, S, c, i); DK ||= T_(i) */
2087 __rtl_digest_updatePBKDF2 (
2088 &digest, pKeyData,
2089 pSaltData, nSaltLen,
2090 nCount, OSL_NETDWORD(i));
2092 /* Next 'KeyData' block */
2093 pKeyData += DIGEST_CBLOCK_PBKDF2;
2094 nKeyLen -= DIGEST_CBLOCK_PBKDF2;
2095 i += 1;
2097 if (nKeyLen > 0)
2099 /* Last 'KeyData' block */
2100 sal_uInt8 T[DIGEST_CBLOCK_PBKDF2];
2102 /* T_i = F (P, S, c, i) */
2103 __rtl_digest_updatePBKDF2 (
2104 &digest, T,
2105 pSaltData, nSaltLen,
2106 nCount, OSL_NETDWORD(i));
2108 /* DK ||= T_(i) */
2109 rtl_copyMemory (pKeyData, T, nKeyLen);
2110 rtl_zeroMemory (T, DIGEST_CBLOCK_PBKDF2);
2113 rtl_zeroMemory (&digest, sizeof (digest));
2114 return rtl_Digest_E_None;
2117 /*========================================================================
2119 * The End.
2121 *======================================================================*/