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