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