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