xref: /trunk/main/sal/rtl/source/digest.c (revision b9fd132da95c5b7cd02adea621f953e2999de0b8)
1647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5647f063dSAndrew Rist  * distributed with this work for additional information
6647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14647f063dSAndrew Rist  * software distributed under the License is distributed on an
15647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17647f063dSAndrew Rist  * specific language governing permissions and limitations
18647f063dSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20647f063dSAndrew Rist  *************************************************************/
21647f063dSAndrew Rist 
22647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24*b9fd132dSpfg #define _RTL_DIGEST_C_ "$Revision$"
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
290cdf0e10cSrcweir static void __rtl_digest_initMD2 (DigestContextMD2 *ctx)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     rtl_zeroMemory (ctx, sizeof (DigestContextMD2));
293cdf0e10cSrcweir }
294cdf0e10cSrcweir 
295cdf0e10cSrcweir /*
296cdf0e10cSrcweir  * __rtl_digest_updateMD2.
297cdf0e10cSrcweir  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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