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