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$"
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