xref: /aoo42x/main/sal/rtl/source/digest.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #define _RTL_DIGEST_C_ "$Revision: 1.9 $"
29 
30 #include <sal/types.h>
31 #include <sal/macros.h>
32 #include <osl/endian.h>
33 #include <rtl/alloc.h>
34 #include <rtl/memory.h>
35 #include <rtl/digest.h>
36 
37 /*========================================================================
38  *
39  * rtlDigest internals.
40  *
41  *======================================================================*/
42 #define RTL_DIGEST_CREATE(T) ((T*)(rtl_allocateZeroMemory(sizeof(T))))
43 
44 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
45 
46 #define RTL_DIGEST_HTONL(l,c) \
47 	(*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
48 	 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
49 	 *((c)++) = (sal_uInt8)(((l) >>  8L) & 0xff), \
50 	 *((c)++) = (sal_uInt8)(((l)       ) & 0xff))
51 
52 #define RTL_DIGEST_LTOC(l,c) \
53 	(*((c)++) = (sal_uInt8)(((l)       ) & 0xff), \
54 	 *((c)++) = (sal_uInt8)(((l) >>  8L) & 0xff), \
55 	 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
56 	 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
57 
58 typedef rtlDigestError (SAL_CALL Digest_init_t) (
59 	void *ctx, const sal_uInt8 *Data, sal_uInt32 DatLen);
60 
61 typedef void (SAL_CALL Digest_delete_t) (void *ctx);
62 
63 typedef rtlDigestError (SAL_CALL Digest_update_t) (
64 	void *ctx, const void *Data, sal_uInt32 DatLen);
65 
66 typedef rtlDigestError (SAL_CALL Digest_get_t) (
67 	void *ctx, sal_uInt8 *Buffer, sal_uInt32 BufLen);
68 
69 typedef struct digest_impl_st
70 {
71 	rtlDigestAlgorithm  m_algorithm;
72 	sal_uInt32          m_length;
73 
74 	Digest_init_t      *m_init;
75 	Digest_delete_t    *m_delete;
76 	Digest_update_t    *m_update;
77 	Digest_get_t       *m_get;
78 } Digest_Impl;
79 
80 /*
81  * __rtl_digest_swapLong.
82  */
83 static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
84 {
85 	register sal_uInt32 *X;
86 	register int         i, n;
87 
88 	X = pData;
89 	n = nDatLen;
90 
91 	for (i = 0; i < n; i++)
92 		X[i] = OSL_SWAPDWORD(X[i]);
93 }
94 
95 /*========================================================================
96  *
97  * rtlDigest implementation.
98  *
99  *======================================================================*/
100 /*
101  * rtl_digest_create.
102  */
103 rtlDigest SAL_CALL rtl_digest_create (rtlDigestAlgorithm Algorithm)
104 {
105 	rtlDigest Digest = (rtlDigest)NULL;
106 	switch (Algorithm)
107 	{
108 		case rtl_Digest_AlgorithmMD2:
109 			Digest = rtl_digest_createMD2();
110 			break;
111 
112 		case rtl_Digest_AlgorithmMD5:
113 			Digest = rtl_digest_createMD5();
114 			break;
115 
116 		case rtl_Digest_AlgorithmSHA:
117 			Digest = rtl_digest_createSHA();
118 			break;
119 
120 		case rtl_Digest_AlgorithmSHA1:
121 			Digest = rtl_digest_createSHA1();
122 			break;
123 
124 		case rtl_Digest_AlgorithmHMAC_MD5:
125 			Digest = rtl_digest_createHMAC_MD5();
126 			break;
127 
128 		case rtl_Digest_AlgorithmHMAC_SHA1:
129 			Digest = rtl_digest_createHMAC_SHA1();
130 			break;
131 
132 		default: /* rtl_Digest_AlgorithmInvalid */
133 			break;
134 	}
135 	return Digest;
136 }
137 
138 /*
139  * rtl_digest_queryAlgorithm.
140  */
141 rtlDigestAlgorithm SAL_CALL rtl_digest_queryAlgorithm (rtlDigest Digest)
142 {
143 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
144 	if (pImpl)
145 		return pImpl->m_algorithm;
146 	else
147 		return rtl_Digest_AlgorithmInvalid;
148 }
149 
150 /*
151  * rtl_digest_queryLength.
152  */
153 sal_uInt32 SAL_CALL rtl_digest_queryLength (rtlDigest Digest)
154 {
155 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
156 	if (pImpl)
157 		return pImpl->m_length;
158 	else
159 		return 0;
160 }
161 
162 /*
163  * rtl_digest_init.
164  */
165 rtlDigestError SAL_CALL rtl_digest_init (
166 	rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
167 {
168 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
169 	if (pImpl)
170 	{
171 		if (pImpl->m_init)
172 			return pImpl->m_init (Digest, pData, nDatLen);
173 		else
174 			return rtl_Digest_E_None;
175 	}
176 	return rtl_Digest_E_Argument;
177 }
178 
179 /*
180  * rtl_digest_update.
181  */
182 rtlDigestError SAL_CALL rtl_digest_update (
183 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
184 {
185 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
186 	if (pImpl && pImpl->m_update)
187 		return pImpl->m_update (Digest, pData, nDatLen);
188 	else
189 		return rtl_Digest_E_Argument;
190 }
191 
192 /*
193  * rtl_digest_get.
194  */
195 rtlDigestError SAL_CALL rtl_digest_get (
196 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
197 {
198 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
199 	if (pImpl && pImpl->m_get)
200 		return pImpl->m_get (Digest, pBuffer, nBufLen);
201 	else
202 		return rtl_Digest_E_Argument;
203 }
204 
205 /*
206  * rtl_digest_destroy.
207  */
208 void SAL_CALL rtl_digest_destroy (rtlDigest Digest)
209 {
210 	Digest_Impl *pImpl = (Digest_Impl *)Digest;
211 	if (pImpl && pImpl->m_delete)
212 		pImpl->m_delete (Digest);
213 }
214 
215 /*========================================================================
216  *
217  * rtl_digest_MD2 internals.
218  *
219  *======================================================================*/
220 #define DIGEST_CBLOCK_MD2 16
221 #define DIGEST_LBLOCK_MD2 16
222 
223 typedef struct digestMD2_context_st
224 {
225 	sal_uInt32 m_nDatLen;
226 	sal_uInt8  m_pData[DIGEST_CBLOCK_MD2];
227 	sal_uInt32 m_state[DIGEST_LBLOCK_MD2];
228 	sal_uInt32 m_chksum[DIGEST_LBLOCK_MD2];
229 } DigestContextMD2;
230 
231 typedef struct digestMD2_impl_st
232 {
233 	Digest_Impl      m_digest;
234 	DigestContextMD2 m_context;
235 } DigestMD2_Impl;
236 
237 static void __rtl_digest_initMD2   (DigestContextMD2 *ctx);
238 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx);
239 static void __rtl_digest_endMD2    (DigestContextMD2 *ctx);
240 
241 static const sal_uInt32 S[256] =
242 {
243 	0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
244 	0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
245 	0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
246 	0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
247 	0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
248 	0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
249 	0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
250 	0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
251 	0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
252 	0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
253 	0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
254 	0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
255 	0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
256 	0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
257 	0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
258 	0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
259 	0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
260 	0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
261 	0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
262 	0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
263 	0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
264 	0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
265 	0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
266 	0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
267 	0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
268 	0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
269 	0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
270 	0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
271 	0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
272 	0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
273 	0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
274 	0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
275 };
276 
277 /*
278  * __rtl_digest_MD2.
279  */
280 static const Digest_Impl __rtl_digest_MD2 =
281 {
282 	rtl_Digest_AlgorithmMD2,
283 	RTL_DIGEST_LENGTH_MD2,
284 
285 	NULL,
286 	rtl_digest_destroyMD2,
287 	rtl_digest_updateMD2,
288 	rtl_digest_getMD2
289 };
290 
291 /*
292  * __rtl_digest_initMD2.
293  */
294 static void __rtl_digest_initMD2 (DigestContextMD2 *ctx)
295 {
296 	rtl_zeroMemory (ctx, sizeof (DigestContextMD2));
297 }
298 
299 /*
300  * __rtl_digest_updateMD2.
301  */
302 static void __rtl_digest_updateMD2 (DigestContextMD2 *ctx)
303 {
304 	register sal_uInt8  *X;
305 	register sal_uInt32 *sp1, *sp2;
306 	register sal_uInt32  i, k, t;
307 
308 	sal_uInt32 state[48];
309 
310 	X   = ctx->m_pData;
311 	sp1 = ctx->m_state;
312 	sp2 = ctx->m_chksum;
313 
314 	k = sp2[DIGEST_LBLOCK_MD2 - 1];
315 	for (i = 0; i < 16; i++)
316 	{
317 		state[i +  0] = sp1[i];
318 		state[i + 16] = t = X[i];
319 		state[i + 32] = t ^ sp1[i];
320 		k = sp2[i] ^= S[t^k];
321 	}
322 
323 	t = 0;
324 	for (i = 0; i < 18; i++)
325 	{
326 		for (k = 0; k < 48; k += 8)
327 		{
328 			t = state[k + 0] ^= S[t];
329 			t = state[k + 1] ^= S[t];
330 			t = state[k + 2] ^= S[t];
331 			t = state[k + 3] ^= S[t];
332 			t = state[k + 4] ^= S[t];
333 			t = state[k + 5] ^= S[t];
334 			t = state[k + 6] ^= S[t];
335 			t = state[k + 7] ^= S[t];
336 		}
337 		t = ((t + i) & 0xff);
338 	}
339 
340 	rtl_copyMemory (sp1, state, 16 * sizeof(sal_uInt32));
341 	rtl_zeroMemory (state, 48 * sizeof(sal_uInt32));
342 }
343 
344 /*
345  * __rtl_digest_endMD2.
346  */
347 static void __rtl_digest_endMD2 (DigestContextMD2 *ctx)
348 {
349 	register sal_uInt8  *X;
350 	register sal_uInt32 *C;
351 	sal_uInt32           i, n;
352 
353 	X = ctx->m_pData;
354 	C = ctx->m_chksum;
355 	n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
356 
357 	for (i = ctx->m_nDatLen; i < DIGEST_CBLOCK_MD2; i++)
358 		X[i] = (sal_uInt8)(n & 0xff);
359 	__rtl_digest_updateMD2 (ctx);
360 
361 	for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
362 		X[i] = (sal_uInt8)(C[i] & 0xff);
363 	__rtl_digest_updateMD2 (ctx);
364 }
365 
366 /*========================================================================
367  *
368  * rtl_digest_MD2 implementation.
369  *
370  *======================================================================*/
371 /*
372  * rtl_digest_MD2.
373  */
374 rtlDigestError SAL_CALL rtl_digest_MD2 (
375 	const void *pData,   sal_uInt32 nDatLen,
376 	sal_uInt8  *pBuffer, sal_uInt32 nBufLen)
377 {
378 	DigestMD2_Impl digest;
379 	rtlDigestError result;
380 
381 	digest.m_digest = __rtl_digest_MD2;
382 	__rtl_digest_initMD2 (&(digest.m_context));
383 
384 	result = rtl_digest_updateMD2 (&digest, pData, nDatLen);
385 	if (result == rtl_Digest_E_None)
386 		result = rtl_digest_getMD2 (&digest, pBuffer, nBufLen);
387 
388 	rtl_zeroMemory (&digest, sizeof (digest));
389 	return (result);
390 }
391 
392 /*
393  * rtl_digest_createMD2.
394  */
395 rtlDigest SAL_CALL rtl_digest_createMD2 (void)
396 {
397 	DigestMD2_Impl *pImpl = (DigestMD2_Impl*)NULL;
398 	pImpl = RTL_DIGEST_CREATE(DigestMD2_Impl);
399 	if (pImpl)
400 	{
401 		pImpl->m_digest = __rtl_digest_MD2;
402 		__rtl_digest_initMD2 (&(pImpl->m_context));
403 	}
404 	return ((rtlDigest)pImpl);
405 }
406 
407 /*
408  * rtl_digest_updateMD2.
409  */
410 rtlDigestError SAL_CALL rtl_digest_updateMD2 (
411 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
412 {
413 	DigestMD2_Impl   *pImpl = (DigestMD2_Impl *)Digest;
414 	const sal_uInt8  *d     = (const sal_uInt8 *)pData;
415 
416 	DigestContextMD2 *ctx;
417 
418 	if ((pImpl == NULL) || (pData == NULL))
419 		return rtl_Digest_E_Argument;
420 
421 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
422 		return rtl_Digest_E_Algorithm;
423 
424 	if (nDatLen == 0)
425 		return rtl_Digest_E_None;
426 
427 	ctx = &(pImpl->m_context);
428 
429 	if (ctx->m_nDatLen)
430 	{
431 		sal_uInt8  *p = ctx->m_pData + ctx->m_nDatLen;
432 		sal_uInt32  n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
433 
434 		if (nDatLen < n)
435 		{
436 			rtl_copyMemory (p, d, nDatLen);
437 			ctx->m_nDatLen += nDatLen;
438 
439 			return rtl_Digest_E_None;
440 		}
441 
442 		rtl_copyMemory (p, d, n);
443 		d       += n;
444 		nDatLen -= n;
445 
446 		__rtl_digest_updateMD2 (ctx);
447 		ctx->m_nDatLen = 0;
448 	}
449 
450 	while (nDatLen >= DIGEST_CBLOCK_MD2)
451 	{
452 		rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_MD2);
453 		d       += DIGEST_CBLOCK_MD2;
454 		nDatLen -= DIGEST_CBLOCK_MD2;
455 
456 		__rtl_digest_updateMD2 (ctx);
457 	}
458 
459 	rtl_copyMemory (ctx->m_pData, d, nDatLen);
460 	ctx->m_nDatLen = nDatLen;
461 
462 	return rtl_Digest_E_None;
463 }
464 
465 /*
466  * rtl_digest_getMD2.
467  */
468 rtlDigestError SAL_CALL rtl_digest_getMD2 (
469 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
470 {
471 	DigestMD2_Impl   *pImpl = (DigestMD2_Impl *)Digest;
472 	sal_uInt32        i;
473 
474 	DigestContextMD2 *ctx;
475 
476 	if ((pImpl == NULL) || (pBuffer == NULL))
477 		return rtl_Digest_E_Argument;
478 
479 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2))
480 		return rtl_Digest_E_Algorithm;
481 
482 	if (!(pImpl->m_digest.m_length <= nBufLen))
483 		return rtl_Digest_E_BufferSize;
484 
485 	ctx = &(pImpl->m_context);
486 
487 	__rtl_digest_endMD2 (ctx);
488 	for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
489 		pBuffer[i] = (sal_uInt8)(ctx->m_state[i] & 0xff);
490 	__rtl_digest_initMD2 (ctx);
491 
492 	return rtl_Digest_E_None;
493 }
494 
495 /*
496  * rtl_digest_destroyMD2.
497  */
498 void SAL_CALL rtl_digest_destroyMD2 (rtlDigest Digest)
499 {
500 	DigestMD2_Impl *pImpl = (DigestMD2_Impl *)Digest;
501 	if (pImpl)
502 	{
503 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2)
504 			rtl_freeZeroMemory (pImpl, sizeof (DigestMD2_Impl));
505 		else
506 			rtl_freeMemory (pImpl);
507 	}
508 }
509 
510 /*========================================================================
511  *
512  * rtl_digest_MD5 internals.
513  *
514  *======================================================================*/
515 #define DIGEST_CBLOCK_MD5 64
516 #define DIGEST_LBLOCK_MD5 16
517 
518 typedef struct digestMD5_context_st
519 {
520 	sal_uInt32 m_nDatLen;
521 	sal_uInt32 m_pData[DIGEST_LBLOCK_MD5];
522 	sal_uInt32 m_nA, m_nB, m_nC, m_nD;
523 	sal_uInt32 m_nL, m_nH;
524 } DigestContextMD5;
525 
526 typedef struct digestMD5_impl_st
527 {
528 	Digest_Impl      m_digest;
529 	DigestContextMD5 m_context;
530 } DigestMD5_Impl;
531 
532 static void __rtl_digest_initMD5   (DigestContextMD5 *ctx);
533 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx);
534 static void __rtl_digest_endMD5    (DigestContextMD5 *ctx);
535 
536 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
537 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
538 #define H(x,y,z) ((x) ^ (y) ^ (z))
539 #define I(x,y,z) (((x) | (~(z))) ^ (y))
540 
541 #define R0(a,b,c,d,k,s,t) { \
542 	a += ((k) + (t) + F((b), (c), (d))); \
543 	a  = RTL_DIGEST_ROTL(a, s); \
544 	a += b; }
545 
546 #define R1(a,b,c,d,k,s,t) { \
547 	a += ((k) + (t) + G((b), (c), (d))); \
548 	a  = RTL_DIGEST_ROTL(a, s); \
549 	a += b; }
550 
551 #define R2(a,b,c,d,k,s,t) { \
552 	a += ((k) + (t) + H((b), (c), (d))); \
553 	a  = RTL_DIGEST_ROTL(a, s); \
554 	a += b; }
555 
556 #define R3(a,b,c,d,k,s,t) { \
557 	a += ((k) + (t) + I((b), (c), (d))); \
558 	a  = RTL_DIGEST_ROTL(a, s); \
559 	a += b; }
560 
561 /*
562  * __rtl_digest_MD5.
563  */
564 static const Digest_Impl __rtl_digest_MD5 =
565 {
566 	rtl_Digest_AlgorithmMD5,
567 	RTL_DIGEST_LENGTH_MD5,
568 
569 	NULL,
570 	rtl_digest_destroyMD5,
571 	rtl_digest_updateMD5,
572 	rtl_digest_getMD5
573 };
574 
575 /*
576  * __rtl_digest_initMD5.
577  */
578 static void __rtl_digest_initMD5 (DigestContextMD5 *ctx)
579 {
580 	rtl_zeroMemory (ctx, sizeof (DigestContextMD5));
581 
582 	ctx->m_nA = (sal_uInt32)0x67452301L;
583 	ctx->m_nB = (sal_uInt32)0xefcdab89L;
584 	ctx->m_nC = (sal_uInt32)0x98badcfeL;
585 	ctx->m_nD = (sal_uInt32)0x10325476L;
586 }
587 
588 /*
589  * __rtl_digest_updateMD5.
590  */
591 static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx)
592 {
593 	register sal_uInt32  A, B, C, D;
594 	register sal_uInt32 *X;
595 
596 	A = ctx->m_nA;
597 	B = ctx->m_nB;
598 	C = ctx->m_nC;
599 	D = ctx->m_nD;
600 	X = ctx->m_pData;
601 
602 	R0 (A, B, C, D, X[ 0],  7, 0xd76aa478L);
603 	R0 (D, A, B, C, X[ 1], 12, 0xe8c7b756L);
604 	R0 (C, D, A, B, X[ 2], 17, 0x242070dbL);
605 	R0 (B, C, D, A, X[ 3], 22, 0xc1bdceeeL);
606 	R0 (A, B, C, D, X[ 4],  7, 0xf57c0fafL);
607 	R0 (D, A, B, C, X[ 5], 12, 0x4787c62aL);
608 	R0 (C, D, A, B, X[ 6], 17, 0xa8304613L);
609 	R0 (B, C, D, A, X[ 7], 22, 0xfd469501L);
610 	R0 (A, B, C, D, X[ 8],  7, 0x698098d8L);
611 	R0 (D, A, B, C, X[ 9], 12, 0x8b44f7afL);
612 	R0 (C, D, A, B, X[10], 17, 0xffff5bb1L);
613 	R0 (B, C, D, A, X[11], 22, 0x895cd7beL);
614 	R0 (A, B, C, D, X[12],  7, 0x6b901122L);
615 	R0 (D, A, B, C, X[13], 12, 0xfd987193L);
616 	R0 (C, D, A, B, X[14], 17, 0xa679438eL);
617 	R0 (B, C, D, A, X[15], 22, 0x49b40821L);
618 
619 	R1 (A, B, C, D, X[ 1],  5, 0xf61e2562L);
620 	R1 (D, A, B, C, X[ 6],  9, 0xc040b340L);
621 	R1 (C, D, A, B, X[11], 14, 0x265e5a51L);
622 	R1 (B, C, D, A, X[ 0], 20, 0xe9b6c7aaL);
623 	R1 (A, B, C, D, X[ 5],  5, 0xd62f105dL);
624 	R1 (D, A, B, C, X[10],  9, 0x02441453L);
625 	R1 (C, D, A, B, X[15], 14, 0xd8a1e681L);
626 	R1 (B, C, D, A, X[ 4], 20, 0xe7d3fbc8L);
627 	R1 (A, B, C, D, X[ 9],  5, 0x21e1cde6L);
628 	R1 (D, A, B, C, X[14],  9, 0xc33707d6L);
629 	R1 (C, D, A, B, X[ 3], 14, 0xf4d50d87L);
630 	R1 (B, C, D, A, X[ 8], 20, 0x455a14edL);
631 	R1 (A, B, C, D, X[13],  5, 0xa9e3e905L);
632 	R1 (D, A, B, C, X[ 2],  9, 0xfcefa3f8L);
633 	R1 (C, D, A, B, X[ 7], 14, 0x676f02d9L);
634 	R1 (B, C, D, A, X[12], 20, 0x8d2a4c8aL);
635 
636 	R2 (A, B, C, D, X[ 5],  4, 0xfffa3942L);
637 	R2 (D, A, B, C, X[ 8], 11, 0x8771f681L);
638 	R2 (C, D, A, B, X[11], 16, 0x6d9d6122L);
639 	R2 (B, C, D, A, X[14], 23, 0xfde5380cL);
640 	R2 (A, B, C, D, X[ 1],  4, 0xa4beea44L);
641 	R2 (D, A, B, C, X[ 4], 11, 0x4bdecfa9L);
642 	R2 (C, D, A, B, X[ 7], 16, 0xf6bb4b60L);
643 	R2 (B, C, D, A, X[10], 23, 0xbebfbc70L);
644 	R2 (A, B, C, D, X[13],  4, 0x289b7ec6L);
645 	R2 (D, A, B, C, X[ 0], 11, 0xeaa127faL);
646 	R2 (C, D, A, B, X[ 3], 16, 0xd4ef3085L);
647 	R2 (B, C, D, A, X[ 6], 23, 0x04881d05L);
648 	R2 (A, B, C, D, X[ 9],  4, 0xd9d4d039L);
649 	R2 (D, A, B, C, X[12], 11, 0xe6db99e5L);
650 	R2 (C, D, A, B, X[15], 16, 0x1fa27cf8L);
651 	R2 (B, C, D, A, X[ 2], 23, 0xc4ac5665L);
652 
653 	R3 (A, B, C, D, X[ 0],  6, 0xf4292244L);
654 	R3 (D, A, B, C, X[ 7], 10, 0x432aff97L);
655 	R3 (C, D, A, B, X[14], 15, 0xab9423a7L);
656 	R3 (B, C, D, A, X[ 5], 21, 0xfc93a039L);
657 	R3 (A, B, C, D, X[12],  6, 0x655b59c3L);
658 	R3 (D, A, B, C, X[ 3], 10, 0x8f0ccc92L);
659 	R3 (C, D, A, B, X[10], 15, 0xffeff47dL);
660 	R3 (B, C, D, A, X[ 1], 21, 0x85845dd1L);
661 	R3 (A, B, C, D, X[ 8],  6, 0x6fa87e4fL);
662 	R3 (D, A, B, C, X[15], 10, 0xfe2ce6e0L);
663 	R3 (C, D, A, B, X[ 6], 15, 0xa3014314L);
664 	R3 (B, C, D, A, X[13], 21, 0x4e0811a1L);
665 	R3 (A, B, C, D, X[ 4],  6, 0xf7537e82L);
666 	R3 (D, A, B, C, X[11], 10, 0xbd3af235L);
667 	R3 (C, D, A, B, X[ 2], 15, 0x2ad7d2bbL);
668 	R3 (B, C, D, A, X[ 9], 21, 0xeb86d391L);
669 
670 	ctx->m_nA += A;
671 	ctx->m_nB += B;
672 	ctx->m_nC += C;
673 	ctx->m_nD += D;
674 }
675 
676 /*
677  * __rtl_digest_endMD5.
678  */
679 static void __rtl_digest_endMD5 (DigestContextMD5 *ctx)
680 {
681 	static const sal_uInt8 end[4] =
682 	{
683 		0x80, 0x00, 0x00, 0x00
684 	};
685 	register const sal_uInt8 *p = end;
686 
687 	register sal_uInt32 *X;
688 	register int         i;
689 
690 	X = ctx->m_pData;
691 	i = (ctx->m_nDatLen >> 2);
692 
693 #ifdef OSL_BIGENDIAN
694 	__rtl_digest_swapLong (X, i + 1);
695 #endif /* OSL_BIGENDIAN */
696 
697 	switch (ctx->m_nDatLen & 0x03)
698 	{
699 		case 1: X[i] &= 0x000000ff; break;
700 		case 2: X[i] &= 0x0000ffff; break;
701 		case 3: X[i] &= 0x00ffffff; break;
702 	}
703 
704 	switch (ctx->m_nDatLen & 0x03)
705 	{
706 		case 0: X[i]  = ((sal_uInt32)(*(p++))) <<  0L;
707 		case 1: X[i] |= ((sal_uInt32)(*(p++))) <<  8L;
708 		case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
709 		case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
710 	}
711 
712 	i += 1;
713 
714 	if (i >= (DIGEST_LBLOCK_MD5 - 2))
715 	{
716 		for (; i < DIGEST_LBLOCK_MD5; i++)
717 			X[i] = 0;
718 		__rtl_digest_updateMD5 (ctx);
719 		i = 0;
720 	}
721 
722 	for (; i < (DIGEST_LBLOCK_MD5 - 2); i++)
723 		X[i] = 0;
724 
725 	X[DIGEST_LBLOCK_MD5 - 2] = ctx->m_nL;
726 	X[DIGEST_LBLOCK_MD5 - 1] = ctx->m_nH;
727 
728 	__rtl_digest_updateMD5 (ctx);
729 }
730 
731 /*========================================================================
732  *
733  * rtl_digest_MD5 implementation.
734  *
735  *======================================================================*/
736 /*
737  * rtl_digest_MD5.
738  */
739 rtlDigestError SAL_CALL rtl_digest_MD5 (
740 	const void *pData,   sal_uInt32 nDatLen,
741 	sal_uInt8  *pBuffer, sal_uInt32 nBufLen)
742 {
743 	DigestMD5_Impl digest;
744 	rtlDigestError result;
745 
746 	digest.m_digest = __rtl_digest_MD5;
747 	__rtl_digest_initMD5 (&(digest.m_context));
748 
749 	result = rtl_digest_update (&digest, pData, nDatLen);
750 	if (result == rtl_Digest_E_None)
751 		result = rtl_digest_getMD5 (&digest, pBuffer, nBufLen);
752 
753 	rtl_zeroMemory (&digest, sizeof (digest));
754 	return (result);
755 }
756 
757 /*
758  * rtl_digest_createMD5.
759  */
760 rtlDigest SAL_CALL rtl_digest_createMD5 (void)
761 {
762 	DigestMD5_Impl *pImpl = (DigestMD5_Impl*)NULL;
763 	pImpl = RTL_DIGEST_CREATE(DigestMD5_Impl);
764 	if (pImpl)
765 	{
766 		pImpl->m_digest = __rtl_digest_MD5;
767 		__rtl_digest_initMD5 (&(pImpl->m_context));
768 	}
769 	return ((rtlDigest)pImpl);
770 }
771 
772 /*
773  * rtl_digest_updateMD5.
774  */
775 rtlDigestError SAL_CALL rtl_digest_updateMD5 (
776 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
777 {
778 	DigestMD5_Impl   *pImpl = (DigestMD5_Impl *)Digest;
779 	const sal_uInt8  *d     = (const sal_uInt8 *)pData;
780 
781 	DigestContextMD5 *ctx;
782 	sal_uInt32        len;
783 
784 	if ((pImpl == NULL) || (pData == NULL))
785 		return rtl_Digest_E_Argument;
786 
787 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
788 		return rtl_Digest_E_Algorithm;
789 
790 	if (nDatLen == 0)
791 		return rtl_Digest_E_None;
792 
793 	ctx = &(pImpl->m_context);
794 
795 	len = ctx->m_nL + (nDatLen << 3);
796 	if (len < ctx->m_nL) ctx->m_nH += 1;
797 	ctx->m_nH += (nDatLen >> 29);
798 	ctx->m_nL  = len;
799 
800 	if (ctx->m_nDatLen)
801 	{
802 		sal_uInt8  *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
803 		sal_uInt32  n = DIGEST_CBLOCK_MD5 - ctx->m_nDatLen;
804 
805 		if (nDatLen < n)
806 		{
807 			rtl_copyMemory (p, d, nDatLen);
808 			ctx->m_nDatLen += nDatLen;
809 
810 			return rtl_Digest_E_None;
811 		}
812 
813 		rtl_copyMemory (p, d, n);
814 		d       += n;
815 		nDatLen -= n;
816 
817 #ifdef OSL_BIGENDIAN
818 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
819 #endif /* OSL_BIGENDIAN */
820 
821 		__rtl_digest_updateMD5 (ctx);
822 		ctx->m_nDatLen = 0;
823 	}
824 
825 	while (nDatLen >= DIGEST_CBLOCK_MD5)
826 	{
827 		rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_MD5);
828 		d       += DIGEST_CBLOCK_MD5;
829 		nDatLen -= DIGEST_CBLOCK_MD5;
830 
831 #ifdef OSL_BIGENDIAN
832 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_MD5);
833 #endif /* OSL_BIGENDIAN */
834 
835 		__rtl_digest_updateMD5 (ctx);
836 	}
837 
838 	rtl_copyMemory (ctx->m_pData, d, nDatLen);
839 	ctx->m_nDatLen = nDatLen;
840 
841 	return rtl_Digest_E_None;
842 }
843 
844 /*
845  * rtl_digest_getMD5.
846  */
847 rtlDigestError SAL_CALL rtl_digest_getMD5 (
848 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
849 {
850 	DigestMD5_Impl   *pImpl = (DigestMD5_Impl *)Digest;
851 	sal_uInt8        *p     = pBuffer;
852 
853 	DigestContextMD5 *ctx;
854 
855 	if ((pImpl == NULL) || (pBuffer == NULL))
856 		return rtl_Digest_E_Argument;
857 
858 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
859 		return rtl_Digest_E_Algorithm;
860 
861 	if (!(pImpl->m_digest.m_length <= nBufLen))
862 		return rtl_Digest_E_BufferSize;
863 
864 	ctx = &(pImpl->m_context);
865 
866 	__rtl_digest_endMD5 (ctx);
867 	RTL_DIGEST_LTOC (ctx->m_nA, p);
868 	RTL_DIGEST_LTOC (ctx->m_nB, p);
869 	RTL_DIGEST_LTOC (ctx->m_nC, p);
870 	RTL_DIGEST_LTOC (ctx->m_nD, p);
871 	__rtl_digest_initMD5 (ctx);
872 
873 	return rtl_Digest_E_None;
874 }
875 
876 /*
877  * rtl_digest_rawMD5.
878  */
879 rtlDigestError SAL_CALL rtl_digest_rawMD5 (
880 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
881 {
882 	DigestMD5_Impl   *pImpl = (DigestMD5_Impl *)Digest;
883 	sal_uInt8        *p     = pBuffer;
884 
885 	DigestContextMD5 *ctx;
886 
887 	if ((pImpl == NULL) || (pBuffer == NULL))
888 		return rtl_Digest_E_Argument;
889 
890 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
891 		return rtl_Digest_E_Algorithm;
892 
893 	if (!(pImpl->m_digest.m_length <= nBufLen))
894 		return rtl_Digest_E_BufferSize;
895 
896 	ctx = &(pImpl->m_context);
897 
898 	/* __rtl_digest_endMD5 (ctx); *//* not finalized */
899 	RTL_DIGEST_LTOC (ctx->m_nA, p);
900 	RTL_DIGEST_LTOC (ctx->m_nB, p);
901 	RTL_DIGEST_LTOC (ctx->m_nC, p);
902 	RTL_DIGEST_LTOC (ctx->m_nD, p);
903 	__rtl_digest_initMD5 (ctx);
904 
905 	return rtl_Digest_E_None;
906 }
907 
908 /*
909  * rtl_digest_destroyMD5.
910  */
911 void SAL_CALL rtl_digest_destroyMD5 (rtlDigest Digest)
912 {
913 	DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
914 	if (pImpl)
915 	{
916 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5)
917 			rtl_freeZeroMemory (pImpl, sizeof (DigestMD5_Impl));
918 		else
919 			rtl_freeMemory (pImpl);
920 	}
921 }
922 
923 /*========================================================================
924  *
925  * rtl_digest_(SHA|SHA1) common internals.
926  *
927  *======================================================================*/
928 #define DIGEST_CBLOCK_SHA 64
929 #define DIGEST_LBLOCK_SHA 16
930 
931 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x);
932 
933 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x);
934 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x);
935 
936 typedef struct digestSHA_context_st
937 {
938 	DigestSHA_update_t *m_update;
939 	sal_uInt32          m_nDatLen;
940 	sal_uInt32          m_pData[DIGEST_LBLOCK_SHA];
941 	sal_uInt32          m_nA, m_nB, m_nC, m_nD, m_nE;
942 	sal_uInt32          m_nL, m_nH;
943 } DigestContextSHA;
944 
945 typedef struct digestSHA_impl_st
946 {
947 	Digest_Impl      m_digest;
948 	DigestContextSHA m_context;
949 } DigestSHA_Impl;
950 
951 static void __rtl_digest_initSHA (
952 	DigestContextSHA *ctx, DigestSHA_update_t *fct);
953 
954 static void __rtl_digest_updateSHA (DigestContextSHA *ctx);
955 static void __rtl_digest_endSHA    (DigestContextSHA *ctx);
956 
957 #define K_00_19 (sal_uInt32)0x5a827999L
958 #define K_20_39 (sal_uInt32)0x6ed9eba1L
959 #define K_40_59 (sal_uInt32)0x8f1bbcdcL
960 #define K_60_79 (sal_uInt32)0xca62c1d6L
961 
962 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
963 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
964 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
965 #define F_60_79(b,c,d) F_20_39(b,c,d)
966 
967 #define BODY_X(i) \
968     (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
969 
970 #define BODY_00_15(u,i,a,b,c,d,e,f) \
971 	(f)  = X[i]; \
972 	(f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
973 	(b)  = RTL_DIGEST_ROTL((b), 30);
974 
975 #define BODY_16_19(u,i,a,b,c,d,e,f) \
976     (f)  = BODY_X((i)); \
977 	(f)  = X[(i)&0x0f] = (u)((f)); \
978 	(f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
979 	(b)  = RTL_DIGEST_ROTL((b), 30);
980 
981 #define BODY_20_39(u,i,a,b,c,d,e,f) \
982     (f)  = BODY_X((i)); \
983 	(f)  = X[(i)&0x0f] = (u)((f)); \
984 	(f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
985 	(b)  = RTL_DIGEST_ROTL((b), 30);
986 
987 #define BODY_40_59(u,i,a,b,c,d,e,f) \
988     (f)  = BODY_X((i)); \
989 	(f)  = X[(i)&0x0f] = (u)((f)); \
990 	(f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
991 	(b)  = RTL_DIGEST_ROTL((b), 30);
992 
993 #define BODY_60_79(u,i,a,b,c,d,e,f) \
994     (f)  = BODY_X((i)); \
995 	(f)  = X[(i)&0x0f] = (u)((f)); \
996 	(f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
997 	(b)  = RTL_DIGEST_ROTL((b), 30);
998 
999 /*
1000  * __rtl_digest_initSHA.
1001  */
1002 static void __rtl_digest_initSHA (
1003 	DigestContextSHA *ctx, DigestSHA_update_t *fct)
1004 {
1005 	rtl_zeroMemory (ctx, sizeof (DigestContextSHA));
1006 	ctx->m_update = fct;
1007 
1008 	ctx->m_nA = (sal_uInt32)0x67452301L;
1009 	ctx->m_nB = (sal_uInt32)0xefcdab89L;
1010 	ctx->m_nC = (sal_uInt32)0x98badcfeL;
1011 	ctx->m_nD = (sal_uInt32)0x10325476L;
1012 	ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
1013 }
1014 
1015 /*
1016  * __rtl_digest_updateSHA.
1017  */
1018 static void __rtl_digest_updateSHA (DigestContextSHA *ctx)
1019 {
1020 	register sal_uInt32  A, B, C, D, E, T;
1021 	register sal_uInt32 *X;
1022 
1023 	register DigestSHA_update_t *U;
1024 	U = ctx->m_update;
1025 
1026 	A = ctx->m_nA;
1027 	B = ctx->m_nB;
1028 	C = ctx->m_nC;
1029 	D = ctx->m_nD;
1030 	E = ctx->m_nE;
1031 	X = ctx->m_pData;
1032 
1033 	BODY_00_15 (U,  0, A, B, C, D, E, T);
1034 	BODY_00_15 (U,  1, T, A, B, C, D, E);
1035 	BODY_00_15 (U,  2, E, T, A, B, C, D);
1036 	BODY_00_15 (U,  3, D, E, T, A, B, C);
1037 	BODY_00_15 (U,  4, C, D, E, T, A, B);
1038 	BODY_00_15 (U,  5, B, C, D, E, T, A);
1039 	BODY_00_15 (U,  6, A, B, C, D, E, T);
1040 	BODY_00_15 (U,  7, T, A, B, C, D, E);
1041 	BODY_00_15 (U,  8, E, T, A, B, C, D);
1042 	BODY_00_15 (U,  9, D, E, T, A, B, C);
1043 	BODY_00_15 (U, 10, C, D, E, T, A, B);
1044 	BODY_00_15 (U, 11, B, C, D, E, T, A);
1045 	BODY_00_15 (U, 12, A, B, C, D, E, T);
1046 	BODY_00_15 (U, 13, T, A, B, C, D, E);
1047 	BODY_00_15 (U, 14, E, T, A, B, C, D);
1048 	BODY_00_15 (U, 15, D, E, T, A, B, C);
1049 	BODY_16_19 (U, 16, C, D, E, T, A, B);
1050 	BODY_16_19 (U, 17, B, C, D, E, T, A);
1051 	BODY_16_19 (U, 18, A, B, C, D, E, T);
1052 	BODY_16_19 (U, 19, T, A, B, C, D, E);
1053 
1054 	BODY_20_39 (U, 20, E, T, A, B, C, D);
1055 	BODY_20_39 (U, 21, D, E, T, A, B, C);
1056 	BODY_20_39 (U, 22, C, D, E, T, A, B);
1057 	BODY_20_39 (U, 23, B, C, D, E, T, A);
1058 	BODY_20_39 (U, 24, A, B, C, D, E, T);
1059 	BODY_20_39 (U, 25, T, A, B, C, D, E);
1060 	BODY_20_39 (U, 26, E, T, A, B, C, D);
1061 	BODY_20_39 (U, 27, D, E, T, A, B, C);
1062 	BODY_20_39 (U, 28, C, D, E, T, A, B);
1063 	BODY_20_39 (U, 29, B, C, D, E, T, A);
1064 	BODY_20_39 (U, 30, A, B, C, D, E, T);
1065 	BODY_20_39 (U, 31, T, A, B, C, D, E);
1066 	BODY_20_39 (U, 32, E, T, A, B, C, D);
1067 	BODY_20_39 (U, 33, D, E, T, A, B, C);
1068 	BODY_20_39 (U, 34, C, D, E, T, A, B);
1069 	BODY_20_39 (U, 35, B, C, D, E, T, A);
1070 	BODY_20_39 (U, 36, A, B, C, D, E, T);
1071 	BODY_20_39 (U, 37, T, A, B, C, D, E);
1072 	BODY_20_39 (U, 38, E, T, A, B, C, D);
1073 	BODY_20_39 (U, 39, D, E, T, A, B, C);
1074 
1075 	BODY_40_59 (U, 40, C, D, E, T, A, B);
1076 	BODY_40_59 (U, 41, B, C, D, E, T, A);
1077 	BODY_40_59 (U, 42, A, B, C, D, E, T);
1078 	BODY_40_59 (U, 43, T, A, B, C, D, E);
1079 	BODY_40_59 (U, 44, E, T, A, B, C, D);
1080 	BODY_40_59 (U, 45, D, E, T, A, B, C);
1081 	BODY_40_59 (U, 46, C, D, E, T, A, B);
1082 	BODY_40_59 (U, 47, B, C, D, E, T, A);
1083 	BODY_40_59 (U, 48, A, B, C, D, E, T);
1084 	BODY_40_59 (U, 49, T, A, B, C, D, E);
1085 	BODY_40_59 (U, 50, E, T, A, B, C, D);
1086 	BODY_40_59 (U, 51, D, E, T, A, B, C);
1087 	BODY_40_59 (U, 52, C, D, E, T, A, B);
1088 	BODY_40_59 (U, 53, B, C, D, E, T, A);
1089 	BODY_40_59 (U, 54, A, B, C, D, E, T);
1090 	BODY_40_59 (U, 55, T, A, B, C, D, E);
1091 	BODY_40_59 (U, 56, E, T, A, B, C, D);
1092 	BODY_40_59 (U, 57, D, E, T, A, B, C);
1093 	BODY_40_59 (U, 58, C, D, E, T, A, B);
1094 	BODY_40_59 (U, 59, B, C, D, E, T, A);
1095 
1096 	BODY_60_79 (U, 60, A, B, C, D, E, T);
1097 	BODY_60_79 (U, 61, T, A, B, C, D, E);
1098 	BODY_60_79 (U, 62, E, T, A, B, C, D);
1099 	BODY_60_79 (U, 63, D, E, T, A, B, C);
1100 	BODY_60_79 (U, 64, C, D, E, T, A, B);
1101 	BODY_60_79 (U, 65, B, C, D, E, T, A);
1102 	BODY_60_79 (U, 66, A, B, C, D, E, T);
1103 	BODY_60_79 (U, 67, T, A, B, C, D, E);
1104 	BODY_60_79 (U, 68, E, T, A, B, C, D);
1105 	BODY_60_79 (U, 69, D, E, T, A, B, C);
1106 	BODY_60_79 (U, 70, C, D, E, T, A, B);
1107 	BODY_60_79 (U, 71, B, C, D, E, T, A);
1108 	BODY_60_79 (U, 72, A, B, C, D, E, T);
1109 	BODY_60_79 (U, 73, T, A, B, C, D, E);
1110 	BODY_60_79 (U, 74, E, T, A, B, C, D);
1111 	BODY_60_79 (U, 75, D, E, T, A, B, C);
1112 	BODY_60_79 (U, 76, C, D, E, T, A, B);
1113 	BODY_60_79 (U, 77, B, C, D, E, T, A);
1114 	BODY_60_79 (U, 78, A, B, C, D, E, T);
1115 	BODY_60_79 (U, 79, T, A, B, C, D, E);
1116 
1117 	ctx->m_nA += E;
1118 	ctx->m_nB += T;
1119 	ctx->m_nC += A;
1120 	ctx->m_nD += B;
1121 	ctx->m_nE += C;
1122 }
1123 
1124 /*
1125  * __rtl_digest_endSHA.
1126  */
1127 static void __rtl_digest_endSHA (DigestContextSHA *ctx)
1128 {
1129 	static const sal_uInt8 end[4] =
1130 	{
1131 		0x80, 0x00, 0x00, 0x00
1132 	};
1133 	register const sal_uInt8 *p = end;
1134 
1135 	register sal_uInt32 *X;
1136 	register int         i;
1137 
1138 	X = ctx->m_pData;
1139 	i = (ctx->m_nDatLen >> 2);
1140 
1141 #ifdef OSL_BIGENDIAN
1142 	__rtl_digest_swapLong (X, i + 1);
1143 #endif /* OSL_BIGENDIAN */
1144 
1145 	switch (ctx->m_nDatLen & 0x03)
1146 	{
1147 		case 1: X[i] &= 0x000000ff; break;
1148 		case 2: X[i] &= 0x0000ffff; break;
1149 		case 3: X[i] &= 0x00ffffff; break;
1150 	}
1151 
1152 	switch (ctx->m_nDatLen & 0x03)
1153 	{
1154 		case 0: X[i]  = ((sal_uInt32)(*(p++))) <<  0L;
1155 		case 1: X[i] |= ((sal_uInt32)(*(p++))) <<  8L;
1156 		case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
1157 		case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
1158 	}
1159 
1160 	__rtl_digest_swapLong (X, i + 1);
1161 
1162 	i += 1;
1163 
1164 	if (i >= (DIGEST_LBLOCK_SHA - 2))
1165 	{
1166 		for (; i < DIGEST_LBLOCK_SHA; i++)
1167 			X[i] = 0;
1168 		__rtl_digest_updateSHA (ctx);
1169 		i = 0;
1170 	}
1171 
1172 	for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
1173 		X[i] = 0;
1174 
1175 	X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
1176 	X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
1177 
1178 	__rtl_digest_updateSHA (ctx);
1179 }
1180 
1181 /*========================================================================
1182  *
1183  * rtl_digest_SHA internals.
1184  *
1185  *======================================================================*/
1186 /*
1187  * __rtl_digest_SHA_0.
1188  */
1189 static const Digest_Impl __rtl_digest_SHA_0 =
1190 {
1191 	rtl_Digest_AlgorithmSHA,
1192 	RTL_DIGEST_LENGTH_SHA,
1193 
1194 	NULL,
1195 	rtl_digest_destroySHA,
1196 	rtl_digest_updateSHA,
1197 	rtl_digest_getSHA
1198 };
1199 
1200 /*
1201  * __rtl_digest_updateSHA_0.
1202  */
1203 static sal_uInt32 __rtl_digest_updateSHA_0 (sal_uInt32 x)
1204 {
1205 	return x;
1206 }
1207 
1208 /*========================================================================
1209  *
1210  * rtl_digest_SHA implementation.
1211  *
1212  *======================================================================*/
1213 /*
1214  * rtl_digest_SHA.
1215  */
1216 rtlDigestError SAL_CALL rtl_digest_SHA (
1217 	const void *pData,   sal_uInt32 nDatLen,
1218 	sal_uInt8  *pBuffer, sal_uInt32 nBufLen)
1219 {
1220 	DigestSHA_Impl digest;
1221 	rtlDigestError result;
1222 
1223 	digest.m_digest = __rtl_digest_SHA_0;
1224 	__rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_0);
1225 
1226 	result = rtl_digest_updateSHA (&digest, pData, nDatLen);
1227 	if (result == rtl_Digest_E_None)
1228 		result = rtl_digest_getSHA (&digest, pBuffer, nBufLen);
1229 
1230 	rtl_zeroMemory (&digest, sizeof (digest));
1231 	return (result);
1232 }
1233 
1234 /*
1235  * rtl_digest_createSHA.
1236  */
1237 rtlDigest SAL_CALL rtl_digest_createSHA (void)
1238 {
1239 	DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1240 	pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1241 	if (pImpl)
1242 	{
1243 		pImpl->m_digest = __rtl_digest_SHA_0;
1244 		__rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_0);
1245 	}
1246 	return ((rtlDigest)pImpl);
1247 }
1248 
1249 /*
1250  * rtl_digest_updateSHA.
1251  */
1252 rtlDigestError SAL_CALL rtl_digest_updateSHA (
1253 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1254 {
1255 	DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
1256 	const sal_uInt8  *d     = (const sal_uInt8 *)pData;
1257 
1258 	DigestContextSHA *ctx;
1259 	sal_uInt32        len;
1260 
1261 	if ((pImpl == NULL) || (pData == NULL))
1262 		return rtl_Digest_E_Argument;
1263 
1264 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1265 		return rtl_Digest_E_Algorithm;
1266 
1267 	if (nDatLen == 0)
1268 		return rtl_Digest_E_None;
1269 
1270 	ctx = &(pImpl->m_context);
1271 
1272 	len = ctx->m_nL + (nDatLen << 3);
1273 	if (len < ctx->m_nL) ctx->m_nH += 1;
1274 	ctx->m_nH += (nDatLen >> 29);
1275 	ctx->m_nL  = len;
1276 
1277 	if (ctx->m_nDatLen)
1278 	{
1279 		sal_uInt8  *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
1280 		sal_uInt32  n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1281 
1282 		if (nDatLen < n)
1283 		{
1284 			rtl_copyMemory (p, d, nDatLen);
1285 			ctx->m_nDatLen += nDatLen;
1286 
1287 			return rtl_Digest_E_None;
1288 		}
1289 
1290 		rtl_copyMemory (p, d, n);
1291 		d       += n;
1292 		nDatLen -= n;
1293 
1294 #ifndef OSL_BIGENDIAN
1295 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1296 #endif /* OSL_BIGENDIAN */
1297 
1298 		__rtl_digest_updateSHA (ctx);
1299 		ctx->m_nDatLen = 0;
1300 	}
1301 
1302 	while (nDatLen >= DIGEST_CBLOCK_SHA)
1303 	{
1304 		rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1305 		d       += DIGEST_CBLOCK_SHA;
1306 		nDatLen -= DIGEST_CBLOCK_SHA;
1307 
1308 #ifndef OSL_BIGENDIAN
1309 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1310 #endif /* OSL_BIGENDIAN */
1311 
1312 		__rtl_digest_updateSHA (ctx);
1313 	}
1314 
1315 	rtl_copyMemory (ctx->m_pData, d, nDatLen);
1316 	ctx->m_nDatLen = nDatLen;
1317 
1318 	return rtl_Digest_E_None;
1319 }
1320 
1321 /*
1322  * rtl_digest_getSHA.
1323  */
1324 rtlDigestError SAL_CALL rtl_digest_getSHA (
1325 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1326 {
1327 	DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
1328 	sal_uInt8        *p     = pBuffer;
1329 
1330 	DigestContextSHA *ctx;
1331 
1332 	if ((pImpl == NULL) || (pBuffer == NULL))
1333 		return rtl_Digest_E_Argument;
1334 
1335 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA))
1336 		return rtl_Digest_E_Algorithm;
1337 
1338 	if (!(pImpl->m_digest.m_length <= nBufLen))
1339 		return rtl_Digest_E_BufferSize;
1340 
1341 	ctx = &(pImpl->m_context);
1342 
1343 	__rtl_digest_endSHA (ctx);
1344 	RTL_DIGEST_HTONL (ctx->m_nA, p);
1345 	RTL_DIGEST_HTONL (ctx->m_nB, p);
1346 	RTL_DIGEST_HTONL (ctx->m_nC, p);
1347 	RTL_DIGEST_HTONL (ctx->m_nD, p);
1348 	RTL_DIGEST_HTONL (ctx->m_nE, p);
1349 	__rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_0);
1350 
1351 	return rtl_Digest_E_None;
1352 }
1353 
1354 /*
1355  * rtl_digest_destroySHA.
1356  */
1357 void SAL_CALL rtl_digest_destroySHA (rtlDigest Digest)
1358 {
1359 	DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1360 	if (pImpl)
1361 	{
1362 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA)
1363 			rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1364 		else
1365 			rtl_freeMemory (pImpl);
1366 	}
1367 }
1368 
1369 /*========================================================================
1370  *
1371  * rtl_digest_SHA1 internals.
1372  *
1373  *======================================================================*/
1374 /*
1375  * __rtl_digest_SHA_1.
1376  */
1377 static const Digest_Impl __rtl_digest_SHA_1 =
1378 {
1379 	rtl_Digest_AlgorithmSHA1,
1380 	RTL_DIGEST_LENGTH_SHA1,
1381 
1382 	NULL,
1383 	rtl_digest_destroySHA1,
1384 	rtl_digest_updateSHA1,
1385 	rtl_digest_getSHA1
1386 };
1387 
1388 /*
1389  * __rtl_digest_updateSHA_1.
1390  */
1391 static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
1392 {
1393 	return RTL_DIGEST_ROTL (x, 1);
1394 }
1395 
1396 /*========================================================================
1397  *
1398  * rtl_digest_SHA1 implementation.
1399  *
1400  *======================================================================*/
1401 /*
1402  * rtl_digest_SHA1.
1403  */
1404 rtlDigestError SAL_CALL rtl_digest_SHA1 (
1405 	const void *pData,   sal_uInt32 nDatLen,
1406 	sal_uInt8  *pBuffer, sal_uInt32 nBufLen)
1407 {
1408 	DigestSHA_Impl digest;
1409 	rtlDigestError result;
1410 
1411 	digest.m_digest = __rtl_digest_SHA_1;
1412 	__rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
1413 
1414 	result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
1415 	if (result == rtl_Digest_E_None)
1416 		result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
1417 
1418 	rtl_zeroMemory (&digest, sizeof (digest));
1419 	return (result);
1420 }
1421 
1422 /*
1423  * rtl_digest_createSHA1.
1424  */
1425 rtlDigest SAL_CALL rtl_digest_createSHA1 (void)
1426 {
1427 	DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
1428 	pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
1429 	if (pImpl)
1430 	{
1431 		pImpl->m_digest = __rtl_digest_SHA_1;
1432 		__rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1433 	}
1434 	return ((rtlDigest)pImpl);
1435 }
1436 
1437 /*
1438  * rtl_digest_updateSHA1.
1439  */
1440 rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
1441 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1442 {
1443 	DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
1444 	const sal_uInt8  *d     = (const sal_uInt8 *)pData;
1445 
1446 	DigestContextSHA *ctx;
1447 	sal_uInt32        len;
1448 
1449 	if ((pImpl == NULL) || (pData == NULL))
1450 		return rtl_Digest_E_Argument;
1451 
1452 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1453 		return rtl_Digest_E_Algorithm;
1454 
1455 	if (nDatLen == 0)
1456 		return rtl_Digest_E_None;
1457 
1458 	ctx = &(pImpl->m_context);
1459 
1460 	len = ctx->m_nL + (nDatLen << 3);
1461 	if (len < ctx->m_nL) ctx->m_nH += 1;
1462 	ctx->m_nH += (nDatLen >> 29);
1463 	ctx->m_nL  = len;
1464 
1465 	if (ctx->m_nDatLen)
1466 	{
1467 		sal_uInt8  *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
1468 		sal_uInt32  n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
1469 
1470 		if (nDatLen < n)
1471 		{
1472 			rtl_copyMemory (p, d, nDatLen);
1473 			ctx->m_nDatLen += nDatLen;
1474 
1475 			return rtl_Digest_E_None;
1476 		}
1477 
1478 		rtl_copyMemory (p, d, n);
1479 		d       += n;
1480 		nDatLen -= n;
1481 
1482 #ifndef OSL_BIGENDIAN
1483 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1484 #endif /* OSL_BIGENDIAN */
1485 
1486 		__rtl_digest_updateSHA (ctx);
1487 		ctx->m_nDatLen = 0;
1488 	}
1489 
1490 	while (nDatLen >= DIGEST_CBLOCK_SHA)
1491 	{
1492 		rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
1493 		d       += DIGEST_CBLOCK_SHA;
1494 		nDatLen -= DIGEST_CBLOCK_SHA;
1495 
1496 #ifndef OSL_BIGENDIAN
1497 		__rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
1498 #endif /* OSL_BIGENDIAN */
1499 
1500 		__rtl_digest_updateSHA (ctx);
1501 	}
1502 
1503 	rtl_copyMemory (ctx->m_pData, d, nDatLen);
1504 	ctx->m_nDatLen = nDatLen;
1505 
1506 	return rtl_Digest_E_None;
1507 }
1508 
1509 /*
1510  * rtl_digest_getSHA1.
1511  */
1512 rtlDigestError SAL_CALL rtl_digest_getSHA1 (
1513 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1514 {
1515 	DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
1516 	sal_uInt8        *p     = pBuffer;
1517 
1518 	DigestContextSHA *ctx;
1519 
1520 	if ((pImpl == NULL) || (pBuffer == NULL))
1521 		return rtl_Digest_E_Argument;
1522 
1523 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
1524 		return rtl_Digest_E_Algorithm;
1525 
1526 	if (!(pImpl->m_digest.m_length <= nBufLen))
1527 		return rtl_Digest_E_BufferSize;
1528 
1529 	ctx = &(pImpl->m_context);
1530 
1531 	__rtl_digest_endSHA (ctx);
1532 	RTL_DIGEST_HTONL (ctx->m_nA, p);
1533 	RTL_DIGEST_HTONL (ctx->m_nB, p);
1534 	RTL_DIGEST_HTONL (ctx->m_nC, p);
1535 	RTL_DIGEST_HTONL (ctx->m_nD, p);
1536 	RTL_DIGEST_HTONL (ctx->m_nE, p);
1537 	__rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
1538 
1539 	return rtl_Digest_E_None;
1540 }
1541 
1542 /*
1543  * rtl_digest_destroySHA1.
1544  */
1545 void SAL_CALL rtl_digest_destroySHA1 (rtlDigest Digest)
1546 {
1547 	DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
1548 	if (pImpl)
1549 	{
1550 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
1551 			rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
1552 		else
1553 			rtl_freeMemory (pImpl);
1554 	}
1555 }
1556 
1557 /*========================================================================
1558  *
1559  * rtl_digest_HMAC_MD5 internals.
1560  *
1561  *======================================================================*/
1562 #define DIGEST_CBLOCK_HMAC_MD5 64
1563 
1564 typedef struct _contextHMAC_MD5_st
1565 {
1566 	DigestMD5_Impl m_hash;
1567 	sal_uInt8      m_opad[DIGEST_CBLOCK_HMAC_MD5];
1568 } ContextHMAC_MD5;
1569 
1570 typedef struct _digestHMAC_MD5_impl_st
1571 {
1572 	Digest_Impl     m_digest;
1573 	ContextHMAC_MD5 m_context;
1574 } DigestHMAC_MD5_Impl;
1575 
1576 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx);
1577 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1578 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx);
1579 
1580 /*
1581  * __rtl_digest_HMAC_MD5.
1582  */
1583 static const Digest_Impl __rtl_digest_HMAC_MD5 =
1584 {
1585 	rtl_Digest_AlgorithmHMAC_MD5,
1586 	RTL_DIGEST_LENGTH_MD5,
1587 
1588 	rtl_digest_initHMAC_MD5,
1589 	rtl_digest_destroyHMAC_MD5,
1590 	rtl_digest_updateHMAC_MD5,
1591 	rtl_digest_getHMAC_MD5
1592 };
1593 
1594 /*
1595  * __rtl_digest_initHMAC_MD5.
1596  */
1597 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5 * ctx)
1598 {
1599 	DigestMD5_Impl *pImpl = &(ctx->m_hash);
1600 
1601 	pImpl->m_digest = __rtl_digest_MD5;
1602 	__rtl_digest_initMD5 (&(pImpl->m_context));
1603 
1604 	rtl_zeroMemory (ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1605 }
1606 
1607 /*
1608  * __rtl_digest_ipadHMAC_MD5.
1609  */
1610 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1611 {
1612 	register sal_uInt32 i;
1613 
1614 	for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1615 		ctx->m_opad[i] ^= 0x36;
1616 	rtl_digest_updateMD5 (
1617 		&(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
1618 	for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1619 		ctx->m_opad[i] ^= 0x36;
1620 }
1621 
1622 /*
1623  * __rtl_digest_opadHMAC_MD5.
1624  */
1625 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5 * ctx)
1626 {
1627 	register sal_uInt32 i;
1628 
1629 	for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
1630 		ctx->m_opad[i] ^= 0x5c;
1631 }
1632 
1633 /*========================================================================
1634  *
1635  * rtl_digest_HMAC_MD5 implementation.
1636  *
1637  *======================================================================*/
1638 /*
1639  * rtl_digest_HMAC_MD5.
1640  */
1641 rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
1642 	const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1643 	const void      *pData,    sal_uInt32 nDatLen,
1644 	sal_uInt8       *pBuffer,  sal_uInt32 nBufLen)
1645 {
1646 	DigestHMAC_MD5_Impl digest;
1647 	rtlDigestError      result;
1648 
1649 	digest.m_digest = __rtl_digest_HMAC_MD5;
1650 
1651 	result = rtl_digest_initHMAC_MD5 (&digest, pKeyData, nKeyLen);
1652 	if (result == rtl_Digest_E_None)
1653 	{
1654 		result = rtl_digest_updateHMAC_MD5 (&digest, pData, nDatLen);
1655 		if (result == rtl_Digest_E_None)
1656 			result = rtl_digest_getHMAC_MD5 (&digest, pBuffer, nBufLen);
1657 	}
1658 
1659 	rtl_zeroMemory (&digest, sizeof (digest));
1660 	return (result);
1661 }
1662 
1663 /*
1664  * rtl_digest_createHMAC_MD5.
1665  */
1666 rtlDigest SAL_CALL rtl_digest_createHMAC_MD5 (void)
1667 {
1668 	DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)NULL;
1669 	pImpl = RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl);
1670 	if (pImpl)
1671 	{
1672 		pImpl->m_digest = __rtl_digest_HMAC_MD5;
1673 		__rtl_digest_initHMAC_MD5 (&(pImpl->m_context));
1674 	}
1675 	return ((rtlDigest)pImpl);
1676 }
1677 
1678 /*
1679  * rtl_digest_initHMAC_MD5.
1680  */
1681 rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
1682 	rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1683 {
1684 	DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1685 	ContextHMAC_MD5     *ctx;
1686 
1687 	if ((pImpl == NULL) || (pKeyData == NULL))
1688 		return rtl_Digest_E_Argument;
1689 
1690 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1691 		return rtl_Digest_E_Algorithm;
1692 
1693 	ctx = &(pImpl->m_context);
1694 	__rtl_digest_initHMAC_MD5 (ctx);
1695 
1696 	if (nKeyLen > DIGEST_CBLOCK_HMAC_MD5)
1697 	{
1698 		/* Initialize 'opad' with hashed 'KeyData' */
1699 		rtl_digest_updateMD5 (
1700 			&(ctx->m_hash), pKeyData, nKeyLen);
1701 		rtl_digest_getMD5 (
1702 			&(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_MD5);
1703 	}
1704 	else
1705 	{
1706 		/* Initialize 'opad' with plain 'KeyData' */
1707 		rtl_copyMemory (ctx->m_opad, pKeyData, nKeyLen);
1708 	}
1709 
1710 	__rtl_digest_ipadHMAC_MD5 (ctx);
1711 	__rtl_digest_opadHMAC_MD5 (ctx);
1712 
1713 	return rtl_Digest_E_None;
1714 }
1715 
1716 /*
1717  * rtl_digest_updateHMAC_MD5.
1718  */
1719 rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
1720 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1721 {
1722 	DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1723 	ContextHMAC_MD5     *ctx;
1724 
1725 	if ((pImpl == NULL) || (pData == NULL))
1726 		return rtl_Digest_E_Argument;
1727 
1728 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1729 		return rtl_Digest_E_Algorithm;
1730 
1731 	ctx = &(pImpl->m_context);
1732 	rtl_digest_updateMD5 (&(ctx->m_hash), pData, nDatLen);
1733 
1734 	return rtl_Digest_E_None;
1735 }
1736 
1737 /*
1738  * rtl_digest_getHMAC_MD5.
1739  */
1740 rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
1741 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1742 {
1743 	DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1744 	ContextHMAC_MD5     *ctx;
1745 
1746 	if ((pImpl == NULL) || (pBuffer == NULL))
1747 		return rtl_Digest_E_Argument;
1748 
1749 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5))
1750 		return rtl_Digest_E_Algorithm;
1751 
1752 	if (!(pImpl->m_digest.m_length <= nBufLen))
1753 		return rtl_Digest_E_BufferSize;
1754 
1755 	nBufLen = pImpl->m_digest.m_length;
1756 
1757 	ctx = &(pImpl->m_context);
1758 	rtl_digest_getMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1759 
1760 	rtl_digest_updateMD5 (&(ctx->m_hash), ctx->m_opad, 64);
1761 	rtl_digest_updateMD5 (&(ctx->m_hash), pBuffer, nBufLen);
1762 	rtl_digest_getMD5    (&(ctx->m_hash), pBuffer, nBufLen);
1763 
1764 	__rtl_digest_opadHMAC_MD5 (ctx);
1765 	__rtl_digest_ipadHMAC_MD5 (ctx);
1766 	__rtl_digest_opadHMAC_MD5 (ctx);
1767 
1768 	return rtl_Digest_E_None;
1769 }
1770 
1771 /*
1772  * rtl_digest_destroyHMAC_MD5.
1773  */
1774 void SAL_CALL rtl_digest_destroyHMAC_MD5 (rtlDigest Digest)
1775 {
1776 	DigestHMAC_MD5_Impl *pImpl = (DigestHMAC_MD5_Impl*)Digest;
1777 	if (pImpl)
1778 	{
1779 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5)
1780 			rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_MD5_Impl));
1781 		else
1782 			rtl_freeMemory (pImpl);
1783 	}
1784 }
1785 
1786 /*========================================================================
1787  *
1788  * rtl_digest_HMAC_SHA1 internals.
1789  *
1790  *======================================================================*/
1791 #define DIGEST_CBLOCK_HMAC_SHA1 64
1792 
1793 typedef struct _contextHMAC_SHA1_st
1794 {
1795 	DigestSHA_Impl m_hash;
1796 	sal_uInt8      m_opad[DIGEST_CBLOCK_HMAC_SHA1];
1797 } ContextHMAC_SHA1;
1798 
1799 typedef struct _digestHMAC_SHA1_impl_st
1800 {
1801 	Digest_Impl      m_digest;
1802 	ContextHMAC_SHA1 m_context;
1803 } DigestHMAC_SHA1_Impl;
1804 
1805 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1806 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1807 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx);
1808 
1809 /*
1810  * __rtl_digest_HMAC_SHA1.
1811  */
1812 static const Digest_Impl __rtl_digest_HMAC_SHA1 =
1813 {
1814 	rtl_Digest_AlgorithmHMAC_SHA1,
1815 	RTL_DIGEST_LENGTH_SHA1,
1816 
1817 	rtl_digest_initHMAC_SHA1,
1818 	rtl_digest_destroyHMAC_SHA1,
1819 	rtl_digest_updateHMAC_SHA1,
1820 	rtl_digest_getHMAC_SHA1
1821 };
1822 
1823 /*
1824  * __rtl_digest_initHMAC_SHA1.
1825  */
1826 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1827 {
1828 	DigestSHA_Impl *pImpl = &(ctx->m_hash);
1829 
1830 	pImpl->m_digest = __rtl_digest_SHA_1;
1831 	__rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
1832 
1833 	rtl_zeroMemory (ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1834 }
1835 
1836 /*
1837  * __rtl_digest_ipadHMAC_SHA1.
1838  */
1839 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1840 {
1841 	register sal_uInt32 i;
1842 
1843 	for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1844 		ctx->m_opad[i] ^= 0x36;
1845 	rtl_digest_updateSHA1 (
1846 		&(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
1847 	for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1848 		ctx->m_opad[i] ^= 0x36;
1849 }
1850 
1851 /*
1852  * __rtl_digest_opadHMAC_SHA1.
1853  */
1854 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
1855 {
1856 	register sal_uInt32 i;
1857 
1858 	for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
1859 		ctx->m_opad[i] ^= 0x5c;
1860 }
1861 
1862 /*========================================================================
1863  *
1864  * rtl_digest_HMAC_SHA1 implementation.
1865  *
1866  *======================================================================*/
1867 /*
1868  * rtl_digest_HMAC_SHA1.
1869  */
1870 rtlDigestError SAL_CALL rtl_digest_HMAC_SHA1 (
1871 	const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
1872 	const void      *pData,    sal_uInt32 nDatLen,
1873 	sal_uInt8       *pBuffer,  sal_uInt32 nBufLen)
1874 {
1875 	DigestHMAC_SHA1_Impl digest;
1876 	rtlDigestError       result;
1877 
1878 	digest.m_digest = __rtl_digest_HMAC_SHA1;
1879 
1880 	result = rtl_digest_initHMAC_SHA1 (&digest, pKeyData, nKeyLen);
1881 	if (result == rtl_Digest_E_None)
1882 	{
1883 		result = rtl_digest_updateHMAC_SHA1 (&digest, pData, nDatLen);
1884 		if (result == rtl_Digest_E_None)
1885 			result = rtl_digest_getHMAC_SHA1 (&digest, pBuffer, nBufLen);
1886 	}
1887 
1888 	rtl_zeroMemory (&digest, sizeof (digest));
1889 	return (result);
1890 }
1891 
1892 /*
1893  * rtl_digest_createHMAC_SHA1.
1894  */
1895 rtlDigest SAL_CALL rtl_digest_createHMAC_SHA1 (void)
1896 {
1897 	DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)NULL;
1898 	pImpl = RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl);
1899 	if (pImpl)
1900 	{
1901 		pImpl->m_digest = __rtl_digest_HMAC_SHA1;
1902 		__rtl_digest_initHMAC_SHA1 (&(pImpl->m_context));
1903 	}
1904 	return ((rtlDigest)pImpl);
1905 }
1906 
1907 /*
1908  * rtl_digest_initHMAC_SHA1.
1909  */
1910 rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
1911 	rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
1912 {
1913 	DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1914 	ContextHMAC_SHA1     *ctx;
1915 
1916 	if ((pImpl == NULL) || (pKeyData == NULL))
1917 		return rtl_Digest_E_Argument;
1918 
1919 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1920 		return rtl_Digest_E_Algorithm;
1921 
1922 	ctx = &(pImpl->m_context);
1923 	__rtl_digest_initHMAC_SHA1 (ctx);
1924 
1925 	if (nKeyLen > DIGEST_CBLOCK_HMAC_SHA1)
1926 	{
1927 		/* Initialize 'opad' with hashed 'KeyData' */
1928 		rtl_digest_updateSHA1 (
1929 			&(ctx->m_hash), pKeyData, nKeyLen);
1930 		rtl_digest_getSHA1 (
1931 			&(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_SHA1);
1932 	}
1933 	else
1934 	{
1935 		/* Initialize 'opad' with plain 'KeyData' */
1936 		rtl_copyMemory (ctx->m_opad, pKeyData, nKeyLen);
1937 	}
1938 
1939 	__rtl_digest_ipadHMAC_SHA1 (ctx);
1940 	__rtl_digest_opadHMAC_SHA1 (ctx);
1941 
1942 	return rtl_Digest_E_None;
1943 }
1944 
1945 /*
1946  * rtl_digest_updateHMAC_SHA1.
1947  */
1948 rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
1949 	rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
1950 {
1951 	DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1952 	ContextHMAC_SHA1     *ctx;
1953 
1954 	if ((pImpl == NULL) || (pData == NULL))
1955 		return rtl_Digest_E_Argument;
1956 
1957 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1958 		return rtl_Digest_E_Algorithm;
1959 
1960 	ctx = &(pImpl->m_context);
1961 	rtl_digest_updateSHA1 (&(ctx->m_hash), pData, nDatLen);
1962 
1963 	return rtl_Digest_E_None;
1964 }
1965 
1966 /*
1967  * rtl_digest_getHMAC_SHA1.
1968  */
1969 rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
1970 	rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
1971 {
1972 	DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
1973 	ContextHMAC_SHA1     *ctx;
1974 
1975 	if ((pImpl == NULL) || (pBuffer == NULL))
1976 		return rtl_Digest_E_Argument;
1977 
1978 	if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
1979 		return rtl_Digest_E_Algorithm;
1980 
1981 	if (!(pImpl->m_digest.m_length <= nBufLen))
1982 		return rtl_Digest_E_BufferSize;
1983 
1984 	nBufLen = pImpl->m_digest.m_length;
1985 
1986 	ctx = &(pImpl->m_context);
1987 	rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
1988 
1989 	rtl_digest_updateSHA1 (&(ctx->m_hash), ctx->m_opad, sizeof(ctx->m_opad));
1990 	rtl_digest_updateSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
1991 	rtl_digest_getSHA1    (&(ctx->m_hash), pBuffer, nBufLen);
1992 
1993 	__rtl_digest_opadHMAC_SHA1 (ctx);
1994 	__rtl_digest_ipadHMAC_SHA1 (ctx);
1995 	__rtl_digest_opadHMAC_SHA1 (ctx);
1996 
1997 	return rtl_Digest_E_None;
1998 }
1999 
2000 /*
2001  * rtl_digest_destroyHMAC_SHA1.
2002  */
2003 void SAL_CALL rtl_digest_destroyHMAC_SHA1 (rtlDigest Digest)
2004 {
2005 	DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
2006 	if (pImpl)
2007 	{
2008 		if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1)
2009 			rtl_freeZeroMemory (pImpl, sizeof (DigestHMAC_SHA1_Impl));
2010 		else
2011 			rtl_freeMemory (pImpl);
2012 	}
2013 }
2014 
2015 /*========================================================================
2016  *
2017  * rtl_digest_PBKDF2 internals.
2018  *
2019  *======================================================================*/
2020 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
2021 
2022 /*
2023  * __rtl_digest_updatePBKDF2.
2024  */
2025 static void __rtl_digest_updatePBKDF2 (
2026 	rtlDigest        hDigest,
2027 	sal_uInt8        T[DIGEST_CBLOCK_PBKDF2],
2028 	const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2029 	sal_uInt32       nCount,    sal_uInt32 nIndex)
2030 {
2031 	/* T_i = F (P, S, c, i) */
2032 	sal_uInt8 U[DIGEST_CBLOCK_PBKDF2];
2033 	register  sal_uInt32 i, k;
2034 
2035 	/* U_(1) = PRF (P, S || INDEX) */
2036 	rtl_digest_updateHMAC_SHA1 (hDigest, pSaltData, nSaltLen);
2037 	rtl_digest_updateHMAC_SHA1 (hDigest, &nIndex, sizeof(nIndex));
2038 	rtl_digest_getHMAC_SHA1    (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2039 
2040 	/* T = U_(1) */
2041 	for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] = U[k];
2042 
2043 	/* T ^= U_(2) ^ ... ^ U_(c) */
2044 	for (i = 1; i < nCount; i++)
2045 	{
2046 		/* U_(i) = PRF (P, U_(i-1)) */
2047 		rtl_digest_updateHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2048 		rtl_digest_getHMAC_SHA1    (hDigest, U, DIGEST_CBLOCK_PBKDF2);
2049 
2050 		/* T ^= U_(i) */
2051 		for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] ^= U[k];
2052 	}
2053 
2054 	rtl_zeroMemory (U, DIGEST_CBLOCK_PBKDF2);
2055 }
2056 
2057 /*========================================================================
2058  *
2059  * rtl_digest_PBKDF2 implementation.
2060  *
2061  *======================================================================*/
2062 /*
2063  * rtl_digest_PBKDF2.
2064  */
2065 rtlDigestError SAL_CALL rtl_digest_PBKDF2 (
2066 	sal_uInt8       *pKeyData , sal_uInt32 nKeyLen,
2067 	const sal_uInt8 *pPassData, sal_uInt32 nPassLen,
2068 	const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
2069 	sal_uInt32       nCount)
2070 {
2071 	DigestHMAC_SHA1_Impl digest;
2072 	sal_uInt32           i = 1;
2073 
2074 	if ((pKeyData == NULL) || (pPassData == NULL) || (pSaltData == NULL))
2075 		return rtl_Digest_E_Argument;
2076 
2077 	digest.m_digest = __rtl_digest_HMAC_SHA1;
2078 	rtl_digest_initHMAC_SHA1 (&digest, pPassData, nPassLen);
2079 
2080 	/* DK = T_(1) || T_(2) || ... || T_(l) */
2081 	while (nKeyLen >= DIGEST_CBLOCK_PBKDF2)
2082 	{
2083 		/* T_(i) = F (P, S, c, i); DK ||= T_(i) */
2084 		__rtl_digest_updatePBKDF2 (
2085 			&digest, pKeyData,
2086 			pSaltData, nSaltLen,
2087 			nCount, OSL_NETDWORD(i));
2088 
2089 		/* Next 'KeyData' block */
2090 		pKeyData += DIGEST_CBLOCK_PBKDF2;
2091 		nKeyLen  -= DIGEST_CBLOCK_PBKDF2;
2092 		i += 1;
2093 	}
2094 	if (nKeyLen > 0)
2095 	{
2096 		/* Last 'KeyData' block */
2097 		sal_uInt8 T[DIGEST_CBLOCK_PBKDF2];
2098 
2099 		/* T_i = F (P, S, c, i) */
2100 		__rtl_digest_updatePBKDF2 (
2101 			&digest, T,
2102 			pSaltData, nSaltLen,
2103 			nCount, OSL_NETDWORD(i));
2104 
2105 		/* DK ||= T_(i) */
2106 		rtl_copyMemory (pKeyData, T, nKeyLen);
2107 		rtl_zeroMemory (T, DIGEST_CBLOCK_PBKDF2);
2108 	}
2109 
2110 	rtl_zeroMemory (&digest, sizeof (digest));
2111 	return rtl_Digest_E_None;
2112 }
2113 
2114 /*========================================================================
2115  *
2116  * The End.
2117  *
2118  *======================================================================*/
2119