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