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