1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <sal/types.h>
24 #include <osl/endian.h>
25 #include <rtl/alloc.h>
26 #include <rtl/digest.h>
28 #define RTL_DIGEST_CREATE(T) (static_cast<T*>(rtl_allocateZeroMemory(sizeof(T))))
30 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
32 #define RTL_DIGEST_HTONL(l,c) \
33 (*((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff), \
34 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff), \
35 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff), \
36 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff))
38 #define RTL_DIGEST_LTOC(l,c) \
39 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff); \
40 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff); \
41 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff); \
42 *((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff);
44 typedef rtlDigestError (Digest_init_t
) (
45 void *ctx
, const sal_uInt8
*Data
, sal_uInt32 DatLen
);
47 typedef void (Digest_delete_t
) (void *ctx
);
49 typedef rtlDigestError (Digest_update_t
) (
50 void *ctx
, const void *Data
, sal_uInt32 DatLen
);
52 typedef rtlDigestError (Digest_get_t
) (
53 void *ctx
, sal_uInt8
*Buffer
, sal_uInt32 BufLen
);
59 rtlDigestAlgorithm m_algorithm
;
62 Digest_init_t
*m_init
;
63 Digest_delete_t
*m_delete
;
64 Digest_update_t
*m_update
;
70 static void swapLong(sal_uInt32
*pData
, sal_uInt32 nDatLen
)
78 for (i
= 0; i
< n
; i
++)
80 X
[i
] = OSL_SWAPDWORD(X
[i
]);
84 rtlDigest SAL_CALL
rtl_digest_create(rtlDigestAlgorithm Algorithm
)
87 rtlDigest Digest
= nullptr;
90 case rtl_Digest_AlgorithmMD2
:
91 Digest
= rtl_digest_createMD2();
94 case rtl_Digest_AlgorithmMD5
:
95 Digest
= rtl_digest_createMD5();
98 case rtl_Digest_AlgorithmSHA
:
99 Digest
= rtl_digest_createSHA();
102 case rtl_Digest_AlgorithmSHA1
:
103 Digest
= rtl_digest_createSHA1();
106 case rtl_Digest_AlgorithmHMAC_MD5
:
107 Digest
= rtl_digest_createHMAC_MD5();
110 case rtl_Digest_AlgorithmHMAC_SHA1
:
111 Digest
= rtl_digest_createHMAC_SHA1();
114 default: /* rtl_Digest_AlgorithmInvalid */
120 rtlDigestAlgorithm SAL_CALL
rtl_digest_queryAlgorithm(rtlDigest Digest
)
123 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
125 return pImpl
->m_algorithm
;
126 return rtl_Digest_AlgorithmInvalid
;
129 sal_uInt32 SAL_CALL
rtl_digest_queryLength(rtlDigest Digest
)
132 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
134 return pImpl
->m_length
;
138 rtlDigestError SAL_CALL
rtl_digest_init(
139 rtlDigest Digest
, const sal_uInt8
*pData
, sal_uInt32 nDatLen
)
142 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
146 return pImpl
->m_init (Digest
, pData
, nDatLen
);
147 return rtl_Digest_E_None
;
149 return rtl_Digest_E_Argument
;
152 rtlDigestError SAL_CALL
rtl_digest_update(
153 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
156 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
157 if (pImpl
&& pImpl
->m_update
)
158 return pImpl
->m_update(Digest
, pData
, nDatLen
);
159 return rtl_Digest_E_Argument
;
162 rtlDigestError SAL_CALL
rtl_digest_get(
163 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
166 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
167 if (pImpl
&& pImpl
->m_get
)
168 return pImpl
->m_get(Digest
, pBuffer
, nBufLen
);
169 return rtl_Digest_E_Argument
;
172 void SAL_CALL
rtl_digest_destroy(rtlDigest Digest
) SAL_THROW_EXTERN_C()
174 Digest_Impl
*pImpl
= static_cast<Digest_Impl
*>(Digest
);
175 if (pImpl
&& pImpl
->m_delete
)
176 pImpl
->m_delete(Digest
);
179 constexpr auto DIGEST_CBLOCK_MD2
= 16;
180 constexpr auto DIGEST_LBLOCK_MD2
= 16;
184 struct DigestContextMD2
186 sal_uInt32 m_nDatLen
;
187 sal_uInt8 m_pData
[DIGEST_CBLOCK_MD2
];
188 sal_uInt32 m_state
[DIGEST_LBLOCK_MD2
];
189 sal_uInt32 m_chksum
[DIGEST_LBLOCK_MD2
];
192 struct DigestMD2_Impl
194 Digest_Impl m_digest
;
195 DigestContextMD2 m_context
;
200 static void initMD2 (DigestContextMD2
*ctx
);
201 static void updateMD2 (DigestContextMD2
*ctx
);
202 static void endMD2 (DigestContextMD2
*ctx
);
204 const sal_uInt32 S
[256] =
206 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
207 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
208 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
209 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
210 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
211 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
212 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
213 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
214 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
215 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
216 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
217 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
218 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
219 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
220 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
221 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
222 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
223 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
224 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
225 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
226 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
227 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
228 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
229 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
230 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
231 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
232 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
233 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
234 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
235 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
236 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
237 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
240 const Digest_Impl MD2
=
242 rtl_Digest_AlgorithmMD2
,
243 RTL_DIGEST_LENGTH_MD2
,
245 rtl_digest_destroyMD2
,
246 rtl_digest_updateMD2
,
250 static void initMD2(DigestContextMD2
*ctx
)
252 memset(ctx
, 0, sizeof(DigestContextMD2
));
255 static void updateMD2(DigestContextMD2
*ctx
)
258 sal_uInt32
*sp1
, *sp2
;
261 sal_uInt32 state
[48];
267 k
= sp2
[DIGEST_LBLOCK_MD2
- 1];
268 for (i
= 0; i
< 16; i
++)
270 state
[i
+ 0] = sp1
[i
];
271 state
[i
+ 16] = t
= X
[i
];
272 state
[i
+ 32] = t
^ sp1
[i
];
273 k
= sp2
[i
] ^= S
[t
^k
];
277 for (i
= 0; i
< 18; i
++)
279 for (k
= 0; k
< 48; k
+= 8)
281 t
= state
[k
+ 0] ^= S
[t
];
282 t
= state
[k
+ 1] ^= S
[t
];
283 t
= state
[k
+ 2] ^= S
[t
];
284 t
= state
[k
+ 3] ^= S
[t
];
285 t
= state
[k
+ 4] ^= S
[t
];
286 t
= state
[k
+ 5] ^= S
[t
];
287 t
= state
[k
+ 6] ^= S
[t
];
288 t
= state
[k
+ 7] ^= S
[t
];
290 t
= ((t
+ i
) & 0xff);
293 memcpy(sp1
, state
, 16 * sizeof(sal_uInt32
));
294 rtl_secureZeroMemory(state
, 48 * sizeof(sal_uInt32
));
297 static void endMD2(DigestContextMD2
*ctx
)
305 n
= DIGEST_CBLOCK_MD2
- ctx
->m_nDatLen
;
307 for (i
= ctx
->m_nDatLen
; i
< DIGEST_CBLOCK_MD2
; i
++)
308 X
[i
] = static_cast<sal_uInt8
>(n
& 0xff);
312 for (i
= 0; i
< DIGEST_CBLOCK_MD2
; i
++)
313 X
[i
] = static_cast<sal_uInt8
>(C
[i
] & 0xff);
317 rtlDigestError SAL_CALL
rtl_digest_MD2(
318 const void *pData
, sal_uInt32 nDatLen
,
319 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
321 DigestMD2_Impl digest
;
322 rtlDigestError result
;
324 digest
.m_digest
= MD2
;
325 initMD2(&(digest
.m_context
));
327 result
= rtl_digest_updateMD2(&digest
, pData
, nDatLen
);
328 if (result
== rtl_Digest_E_None
)
329 result
= rtl_digest_getMD2(&digest
, pBuffer
, nBufLen
);
331 rtl_secureZeroMemory(&digest
, sizeof(digest
));
335 rtlDigest SAL_CALL
rtl_digest_createMD2() SAL_THROW_EXTERN_C()
337 DigestMD2_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestMD2_Impl
);
340 pImpl
->m_digest
= MD2
;
341 initMD2(&(pImpl
->m_context
));
343 return static_cast<rtlDigest
>(pImpl
);
346 rtlDigestError SAL_CALL
rtl_digest_updateMD2(
347 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
350 DigestMD2_Impl
*pImpl
= static_cast<DigestMD2_Impl
*>(Digest
);
351 const sal_uInt8
*d
= static_cast<const sal_uInt8
*>(pData
);
353 DigestContextMD2
*ctx
;
355 if (!pImpl
|| !pData
)
356 return rtl_Digest_E_Argument
;
358 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmMD2
)
359 return rtl_Digest_E_Algorithm
;
362 return rtl_Digest_E_None
;
364 ctx
= &(pImpl
->m_context
);
368 sal_uInt8
*p
= ctx
->m_pData
+ ctx
->m_nDatLen
;
369 sal_uInt32 n
= DIGEST_CBLOCK_MD2
- ctx
->m_nDatLen
;
373 memcpy(p
, d
, nDatLen
);
374 ctx
->m_nDatLen
+= nDatLen
;
376 return rtl_Digest_E_None
;
387 while (nDatLen
>= DIGEST_CBLOCK_MD2
)
389 memcpy(ctx
->m_pData
, d
, DIGEST_CBLOCK_MD2
);
390 d
+= DIGEST_CBLOCK_MD2
;
391 nDatLen
-= DIGEST_CBLOCK_MD2
;
396 memcpy(ctx
->m_pData
, d
, nDatLen
);
397 ctx
->m_nDatLen
= nDatLen
;
399 return rtl_Digest_E_None
;
402 rtlDigestError SAL_CALL
rtl_digest_getMD2(
403 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
406 DigestMD2_Impl
*pImpl
= static_cast<DigestMD2_Impl
*>(Digest
);
409 DigestContextMD2
*ctx
;
411 if (!pImpl
|| !pBuffer
)
412 return rtl_Digest_E_Argument
;
414 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmMD2
)
415 return rtl_Digest_E_Algorithm
;
417 if (pImpl
->m_digest
.m_length
> nBufLen
)
418 return rtl_Digest_E_BufferSize
;
420 ctx
= &(pImpl
->m_context
);
423 for (i
= 0; i
< DIGEST_CBLOCK_MD2
; i
++)
425 pBuffer
[i
] = static_cast<sal_uInt8
>(ctx
->m_state
[i
] & 0xff);
430 return rtl_Digest_E_None
;
433 void SAL_CALL
rtl_digest_destroyMD2(rtlDigest Digest
) SAL_THROW_EXTERN_C()
435 DigestMD2_Impl
*pImpl
= static_cast<DigestMD2_Impl
*>(Digest
);
438 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD2
)
439 rtl_freeZeroMemory(pImpl
, sizeof(DigestMD2_Impl
));
445 #define DIGEST_CBLOCK_MD5 64
446 #define DIGEST_LBLOCK_MD5 16
450 struct DigestContextMD5
452 sal_uInt32 m_nDatLen
;
453 sal_uInt32 m_pData
[DIGEST_LBLOCK_MD5
];
454 sal_uInt32 m_nA
, m_nB
, m_nC
, m_nD
;
455 sal_uInt32 m_nL
, m_nH
;
458 struct DigestMD5_Impl
460 Digest_Impl m_digest
;
461 DigestContextMD5 m_context
;
466 static void initMD5 (DigestContextMD5
*ctx
);
467 static void updateMD5 (DigestContextMD5
*ctx
);
468 static void endMD5 (DigestContextMD5
*ctx
);
470 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
471 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
472 #define H(x,y,z) ((x) ^ (y) ^ (z))
473 #define I(x,y,z) (((x) | (~(z))) ^ (y))
475 #define R0(a,b,c,d,k,s,t) { \
476 a += ((k) + (t) + F((b), (c), (d))); \
477 a = RTL_DIGEST_ROTL(a, s); \
480 #define R1(a,b,c,d,k,s,t) { \
481 a += ((k) + (t) + G((b), (c), (d))); \
482 a = RTL_DIGEST_ROTL(a, s); \
485 #define R2(a,b,c,d,k,s,t) { \
486 a += ((k) + (t) + H((b), (c), (d))); \
487 a = RTL_DIGEST_ROTL(a, s); \
490 #define R3(a,b,c,d,k,s,t) { \
491 a += ((k) + (t) + I((b), (c), (d))); \
492 a = RTL_DIGEST_ROTL(a, s); \
495 const Digest_Impl MD5
=
497 rtl_Digest_AlgorithmMD5
,
498 RTL_DIGEST_LENGTH_MD5
,
500 rtl_digest_destroyMD5
,
501 rtl_digest_updateMD5
,
505 static void initMD5(DigestContextMD5
*ctx
)
507 memset(ctx
, 0, sizeof(DigestContextMD5
));
509 ctx
->m_nA
= sal_uInt32(0x67452301L
);
510 ctx
->m_nB
= sal_uInt32(0xefcdab89L
);
511 ctx
->m_nC
= sal_uInt32(0x98badcfeL
);
512 ctx
->m_nD
= sal_uInt32(0x10325476L
);
515 static void updateMD5(DigestContextMD5
*ctx
)
517 sal_uInt32 A
, B
, C
, D
;
526 R0 (A
, B
, C
, D
, X
[ 0], 7, 0xd76aa478L
);
527 R0 (D
, A
, B
, C
, X
[ 1], 12, 0xe8c7b756L
);
528 R0 (C
, D
, A
, B
, X
[ 2], 17, 0x242070dbL
);
529 R0 (B
, C
, D
, A
, X
[ 3], 22, 0xc1bdceeeL
);
530 R0 (A
, B
, C
, D
, X
[ 4], 7, 0xf57c0fafL
);
531 R0 (D
, A
, B
, C
, X
[ 5], 12, 0x4787c62aL
);
532 R0 (C
, D
, A
, B
, X
[ 6], 17, 0xa8304613L
);
533 R0 (B
, C
, D
, A
, X
[ 7], 22, 0xfd469501L
);
534 R0 (A
, B
, C
, D
, X
[ 8], 7, 0x698098d8L
);
535 R0 (D
, A
, B
, C
, X
[ 9], 12, 0x8b44f7afL
);
536 R0 (C
, D
, A
, B
, X
[10], 17, 0xffff5bb1L
);
537 R0 (B
, C
, D
, A
, X
[11], 22, 0x895cd7beL
);
538 R0 (A
, B
, C
, D
, X
[12], 7, 0x6b901122L
);
539 R0 (D
, A
, B
, C
, X
[13], 12, 0xfd987193L
);
540 R0 (C
, D
, A
, B
, X
[14], 17, 0xa679438eL
);
541 R0 (B
, C
, D
, A
, X
[15], 22, 0x49b40821L
);
543 R1 (A
, B
, C
, D
, X
[ 1], 5, 0xf61e2562L
);
544 R1 (D
, A
, B
, C
, X
[ 6], 9, 0xc040b340L
);
545 R1 (C
, D
, A
, B
, X
[11], 14, 0x265e5a51L
);
546 R1 (B
, C
, D
, A
, X
[ 0], 20, 0xe9b6c7aaL
);
547 R1 (A
, B
, C
, D
, X
[ 5], 5, 0xd62f105dL
);
548 R1 (D
, A
, B
, C
, X
[10], 9, 0x02441453L
);
549 R1 (C
, D
, A
, B
, X
[15], 14, 0xd8a1e681L
);
550 R1 (B
, C
, D
, A
, X
[ 4], 20, 0xe7d3fbc8L
);
551 R1 (A
, B
, C
, D
, X
[ 9], 5, 0x21e1cde6L
);
552 R1 (D
, A
, B
, C
, X
[14], 9, 0xc33707d6L
);
553 R1 (C
, D
, A
, B
, X
[ 3], 14, 0xf4d50d87L
);
554 R1 (B
, C
, D
, A
, X
[ 8], 20, 0x455a14edL
);
555 R1 (A
, B
, C
, D
, X
[13], 5, 0xa9e3e905L
);
556 R1 (D
, A
, B
, C
, X
[ 2], 9, 0xfcefa3f8L
);
557 R1 (C
, D
, A
, B
, X
[ 7], 14, 0x676f02d9L
);
558 R1 (B
, C
, D
, A
, X
[12], 20, 0x8d2a4c8aL
);
560 R2 (A
, B
, C
, D
, X
[ 5], 4, 0xfffa3942L
);
561 R2 (D
, A
, B
, C
, X
[ 8], 11, 0x8771f681L
);
562 R2 (C
, D
, A
, B
, X
[11], 16, 0x6d9d6122L
);
563 R2 (B
, C
, D
, A
, X
[14], 23, 0xfde5380cL
);
564 R2 (A
, B
, C
, D
, X
[ 1], 4, 0xa4beea44L
);
565 R2 (D
, A
, B
, C
, X
[ 4], 11, 0x4bdecfa9L
);
566 R2 (C
, D
, A
, B
, X
[ 7], 16, 0xf6bb4b60L
);
567 R2 (B
, C
, D
, A
, X
[10], 23, 0xbebfbc70L
);
568 R2 (A
, B
, C
, D
, X
[13], 4, 0x289b7ec6L
);
569 R2 (D
, A
, B
, C
, X
[ 0], 11, 0xeaa127faL
);
570 R2 (C
, D
, A
, B
, X
[ 3], 16, 0xd4ef3085L
);
571 R2 (B
, C
, D
, A
, X
[ 6], 23, 0x04881d05L
);
572 R2 (A
, B
, C
, D
, X
[ 9], 4, 0xd9d4d039L
);
573 R2 (D
, A
, B
, C
, X
[12], 11, 0xe6db99e5L
);
574 R2 (C
, D
, A
, B
, X
[15], 16, 0x1fa27cf8L
);
575 R2 (B
, C
, D
, A
, X
[ 2], 23, 0xc4ac5665L
);
577 R3 (A
, B
, C
, D
, X
[ 0], 6, 0xf4292244L
);
578 R3 (D
, A
, B
, C
, X
[ 7], 10, 0x432aff97L
);
579 R3 (C
, D
, A
, B
, X
[14], 15, 0xab9423a7L
);
580 R3 (B
, C
, D
, A
, X
[ 5], 21, 0xfc93a039L
);
581 R3 (A
, B
, C
, D
, X
[12], 6, 0x655b59c3L
);
582 R3 (D
, A
, B
, C
, X
[ 3], 10, 0x8f0ccc92L
);
583 R3 (C
, D
, A
, B
, X
[10], 15, 0xffeff47dL
);
584 R3 (B
, C
, D
, A
, X
[ 1], 21, 0x85845dd1L
);
585 R3 (A
, B
, C
, D
, X
[ 8], 6, 0x6fa87e4fL
);
586 R3 (D
, A
, B
, C
, X
[15], 10, 0xfe2ce6e0L
);
587 R3 (C
, D
, A
, B
, X
[ 6], 15, 0xa3014314L
);
588 R3 (B
, C
, D
, A
, X
[13], 21, 0x4e0811a1L
);
589 R3 (A
, B
, C
, D
, X
[ 4], 6, 0xf7537e82L
);
590 R3 (D
, A
, B
, C
, X
[11], 10, 0xbd3af235L
);
591 R3 (C
, D
, A
, B
, X
[ 2], 15, 0x2ad7d2bbL
);
592 R3 (B
, C
, D
, A
, X
[ 9], 21, 0xeb86d391L
);
600 static void endMD5(DigestContextMD5
*ctx
)
602 static const sal_uInt8 end
[4] =
604 0x80, 0x00, 0x00, 0x00
606 const sal_uInt8
*p
= end
;
612 i
= (ctx
->m_nDatLen
>> 2);
616 #endif /* OSL_BIGENDIAN */
618 switch (ctx
->m_nDatLen
& 0x03)
620 case 1: X
[i
] &= 0x000000ff; break;
621 case 2: X
[i
] &= 0x0000ffff; break;
622 case 3: X
[i
] &= 0x00ffffff; break;
625 switch (ctx
->m_nDatLen
& 0x03)
627 case 0: X
[i
] = static_cast<sal_uInt32
>(*(p
++)) << 0;
629 case 1: X
[i
] |= static_cast<sal_uInt32
>(*(p
++)) << 8;
631 case 2: X
[i
] |= static_cast<sal_uInt32
>(*(p
++)) << 16;
633 case 3: X
[i
] |= static_cast<sal_uInt32
>(*p
) << 24;
638 if (i
> (DIGEST_LBLOCK_MD5
- 2))
640 for (; i
< DIGEST_LBLOCK_MD5
; i
++)
649 for (; i
< (DIGEST_LBLOCK_MD5
- 2); i
++)
652 X
[DIGEST_LBLOCK_MD5
- 2] = ctx
->m_nL
;
653 X
[DIGEST_LBLOCK_MD5
- 1] = ctx
->m_nH
;
658 rtlDigestError SAL_CALL
rtl_digest_MD5(
659 const void *pData
, sal_uInt32 nDatLen
,
660 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
662 DigestMD5_Impl digest
;
663 rtlDigestError result
;
665 digest
.m_digest
= MD5
;
666 initMD5(&(digest
.m_context
));
668 result
= rtl_digest_update(&digest
, pData
, nDatLen
);
669 if (result
== rtl_Digest_E_None
)
670 result
= rtl_digest_getMD5(&digest
, pBuffer
, nBufLen
);
672 rtl_secureZeroMemory(&digest
, sizeof(digest
));
676 rtlDigest SAL_CALL
rtl_digest_createMD5() SAL_THROW_EXTERN_C()
678 DigestMD5_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestMD5_Impl
);
681 pImpl
->m_digest
= MD5
;
682 initMD5(&(pImpl
->m_context
));
684 return static_cast<rtlDigest
>(pImpl
);
687 rtlDigestError SAL_CALL
rtl_digest_updateMD5(
688 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
691 DigestMD5_Impl
*pImpl
= static_cast<DigestMD5_Impl
*>(Digest
);
692 const sal_uInt8
*d
= static_cast<const sal_uInt8
*>(pData
);
694 DigestContextMD5
*ctx
;
697 if (!pImpl
|| !pData
)
698 return rtl_Digest_E_Argument
;
700 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmMD5
)
701 return rtl_Digest_E_Algorithm
;
704 return rtl_Digest_E_None
;
706 ctx
= &(pImpl
->m_context
);
708 len
= ctx
->m_nL
+ (nDatLen
<< 3);
712 ctx
->m_nH
+= (nDatLen
>> 29);
717 sal_uInt8
*p
= reinterpret_cast<sal_uInt8
*>(ctx
->m_pData
) + ctx
->m_nDatLen
;
718 sal_uInt32 n
= DIGEST_CBLOCK_MD5
- ctx
->m_nDatLen
;
722 memcpy(p
, d
, nDatLen
);
723 ctx
->m_nDatLen
+= nDatLen
;
725 return rtl_Digest_E_None
;
733 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_MD5
);
734 #endif /* OSL_BIGENDIAN */
740 while (nDatLen
>= DIGEST_CBLOCK_MD5
)
742 memcpy(ctx
->m_pData
, d
, DIGEST_CBLOCK_MD5
);
743 d
+= DIGEST_CBLOCK_MD5
;
744 nDatLen
-= DIGEST_CBLOCK_MD5
;
747 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_MD5
);
748 #endif /* OSL_BIGENDIAN */
753 memcpy(ctx
->m_pData
, d
, nDatLen
);
754 ctx
->m_nDatLen
= nDatLen
;
756 return rtl_Digest_E_None
;
759 rtlDigestError SAL_CALL
rtl_digest_getMD5(
760 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
763 DigestMD5_Impl
*pImpl
= static_cast<DigestMD5_Impl
*>(Digest
);
764 sal_uInt8
*p
= pBuffer
;
766 DigestContextMD5
*ctx
;
768 if (!pImpl
|| !pBuffer
)
769 return rtl_Digest_E_Argument
;
771 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmMD5
)
772 return rtl_Digest_E_Algorithm
;
774 if (pImpl
->m_digest
.m_length
> nBufLen
)
775 return rtl_Digest_E_BufferSize
;
777 ctx
= &(pImpl
->m_context
);
780 RTL_DIGEST_LTOC(ctx
->m_nA
, p
);
781 RTL_DIGEST_LTOC(ctx
->m_nB
, p
);
782 RTL_DIGEST_LTOC(ctx
->m_nC
, p
);
783 RTL_DIGEST_LTOC(ctx
->m_nD
, p
);
786 return rtl_Digest_E_None
;
789 rtlDigestError SAL_CALL
rtl_digest_rawMD5(
790 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
793 DigestMD5_Impl
*pImpl
= static_cast<DigestMD5_Impl
*>(Digest
);
794 sal_uInt8
*p
= pBuffer
;
796 DigestContextMD5
*ctx
;
798 if (!pImpl
|| !pBuffer
)
799 return rtl_Digest_E_Argument
;
801 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmMD5
)
802 return rtl_Digest_E_Algorithm
;
804 if (pImpl
->m_digest
.m_length
> nBufLen
)
805 return rtl_Digest_E_BufferSize
;
807 ctx
= &(pImpl
->m_context
);
810 RTL_DIGEST_LTOC(ctx
->m_nA
, p
);
811 RTL_DIGEST_LTOC(ctx
->m_nB
, p
);
812 RTL_DIGEST_LTOC(ctx
->m_nC
, p
);
813 RTL_DIGEST_LTOC(ctx
->m_nD
, p
);
816 return rtl_Digest_E_None
;
819 void SAL_CALL
rtl_digest_destroyMD5(rtlDigest Digest
) SAL_THROW_EXTERN_C()
821 DigestMD5_Impl
*pImpl
= static_cast<DigestMD5_Impl
*>(Digest
);
824 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD5
)
825 rtl_freeZeroMemory(pImpl
, sizeof(DigestMD5_Impl
));
831 #define DIGEST_CBLOCK_SHA 64
832 #define DIGEST_LBLOCK_SHA 16
834 typedef sal_uInt32
DigestSHA_update_t(sal_uInt32 x
);
836 static sal_uInt32
updateSHA_0(sal_uInt32 x
);
837 static sal_uInt32
updateSHA_1(sal_uInt32 x
);
841 struct DigestContextSHA
843 DigestSHA_update_t
*m_update
;
844 sal_uInt32 m_nDatLen
;
845 sal_uInt32 m_pData
[DIGEST_LBLOCK_SHA
];
846 sal_uInt32 m_nA
, m_nB
, m_nC
, m_nD
, m_nE
;
847 sal_uInt32 m_nL
, m_nH
;
850 struct DigestSHA_Impl
852 Digest_Impl m_digest
;
853 DigestContextSHA m_context
;
859 DigestContextSHA
*ctx
, DigestSHA_update_t
*fct
);
861 static void updateSHA(DigestContextSHA
*ctx
);
862 static void endSHA(DigestContextSHA
*ctx
);
864 #define K_00_19 sal_uInt32(0x5a827999L)
865 #define K_20_39 sal_uInt32(0x6ed9eba1L)
866 #define K_40_59 sal_uInt32(0x8f1bbcdcL)
867 #define K_60_79 sal_uInt32(0xca62c1d6L)
869 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
870 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
871 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
872 #define F_60_79(b,c,d) F_20_39(b,c,d)
875 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
877 #define BODY_00_15(u,i,a,b,c,d,e,f) \
879 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
880 (b) = RTL_DIGEST_ROTL((b), 30);
882 #define BODY_16_19(u,i,a,b,c,d,e,f) \
884 (f) = X[(i)&0x0f] = (u)((f)); \
885 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
886 (b) = RTL_DIGEST_ROTL((b), 30);
888 #define BODY_20_39(u,i,a,b,c,d,e,f) \
890 (f) = X[(i)&0x0f] = (u)((f)); \
891 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
892 (b) = RTL_DIGEST_ROTL((b), 30);
894 #define BODY_40_59(u,i,a,b,c,d,e,f) \
896 (f) = X[(i)&0x0f] = (u)((f)); \
897 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
898 (b) = RTL_DIGEST_ROTL((b), 30);
900 #define BODY_60_79(u,i,a,b,c,d,e,f) \
902 (f) = X[(i)&0x0f] = (u)((f)); \
903 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
904 (b) = RTL_DIGEST_ROTL((b), 30);
907 DigestContextSHA
*ctx
, DigestSHA_update_t
*fct
)
909 memset(ctx
, 0, sizeof(DigestContextSHA
));
912 ctx
->m_nA
= sal_uInt32(0x67452301L
);
913 ctx
->m_nB
= sal_uInt32(0xefcdab89L
);
914 ctx
->m_nC
= sal_uInt32(0x98badcfeL
);
915 ctx
->m_nD
= sal_uInt32(0x10325476L
);
916 ctx
->m_nE
= sal_uInt32(0xc3d2e1f0L
);
919 static void updateSHA(DigestContextSHA
*ctx
)
921 sal_uInt32 A
, B
, C
, D
, E
, T
;
924 DigestSHA_update_t
*U
;
934 BODY_00_15 (U
, 0, A
, B
, C
, D
, E
, T
);
935 BODY_00_15 (U
, 1, T
, A
, B
, C
, D
, E
);
936 BODY_00_15 (U
, 2, E
, T
, A
, B
, C
, D
);
937 BODY_00_15 (U
, 3, D
, E
, T
, A
, B
, C
);
938 BODY_00_15 (U
, 4, C
, D
, E
, T
, A
, B
);
939 BODY_00_15 (U
, 5, B
, C
, D
, E
, T
, A
);
940 BODY_00_15 (U
, 6, A
, B
, C
, D
, E
, T
);
941 BODY_00_15 (U
, 7, T
, A
, B
, C
, D
, E
);
942 BODY_00_15 (U
, 8, E
, T
, A
, B
, C
, D
);
943 BODY_00_15 (U
, 9, D
, E
, T
, A
, B
, C
);
944 BODY_00_15 (U
, 10, C
, D
, E
, T
, A
, B
);
945 BODY_00_15 (U
, 11, B
, C
, D
, E
, T
, A
);
946 BODY_00_15 (U
, 12, A
, B
, C
, D
, E
, T
);
947 BODY_00_15 (U
, 13, T
, A
, B
, C
, D
, E
);
948 BODY_00_15 (U
, 14, E
, T
, A
, B
, C
, D
);
949 BODY_00_15 (U
, 15, D
, E
, T
, A
, B
, C
);
950 BODY_16_19 (U
, 16, C
, D
, E
, T
, A
, B
);
951 BODY_16_19 (U
, 17, B
, C
, D
, E
, T
, A
);
952 BODY_16_19 (U
, 18, A
, B
, C
, D
, E
, T
);
953 BODY_16_19 (U
, 19, T
, A
, B
, C
, D
, E
);
955 BODY_20_39 (U
, 20, E
, T
, A
, B
, C
, D
);
956 BODY_20_39 (U
, 21, D
, E
, T
, A
, B
, C
);
957 BODY_20_39 (U
, 22, C
, D
, E
, T
, A
, B
);
958 BODY_20_39 (U
, 23, B
, C
, D
, E
, T
, A
);
959 BODY_20_39 (U
, 24, A
, B
, C
, D
, E
, T
);
960 BODY_20_39 (U
, 25, T
, A
, B
, C
, D
, E
);
961 BODY_20_39 (U
, 26, E
, T
, A
, B
, C
, D
);
962 BODY_20_39 (U
, 27, D
, E
, T
, A
, B
, C
);
963 BODY_20_39 (U
, 28, C
, D
, E
, T
, A
, B
);
964 BODY_20_39 (U
, 29, B
, C
, D
, E
, T
, A
);
965 BODY_20_39 (U
, 30, A
, B
, C
, D
, E
, T
);
966 BODY_20_39 (U
, 31, T
, A
, B
, C
, D
, E
);
967 BODY_20_39 (U
, 32, E
, T
, A
, B
, C
, D
);
968 BODY_20_39 (U
, 33, D
, E
, T
, A
, B
, C
);
969 BODY_20_39 (U
, 34, C
, D
, E
, T
, A
, B
);
970 BODY_20_39 (U
, 35, B
, C
, D
, E
, T
, A
);
971 BODY_20_39 (U
, 36, A
, B
, C
, D
, E
, T
);
972 BODY_20_39 (U
, 37, T
, A
, B
, C
, D
, E
);
973 BODY_20_39 (U
, 38, E
, T
, A
, B
, C
, D
);
974 BODY_20_39 (U
, 39, D
, E
, T
, A
, B
, C
);
976 BODY_40_59 (U
, 40, C
, D
, E
, T
, A
, B
);
977 BODY_40_59 (U
, 41, B
, C
, D
, E
, T
, A
);
978 BODY_40_59 (U
, 42, A
, B
, C
, D
, E
, T
);
979 BODY_40_59 (U
, 43, T
, A
, B
, C
, D
, E
);
980 BODY_40_59 (U
, 44, E
, T
, A
, B
, C
, D
);
981 BODY_40_59 (U
, 45, D
, E
, T
, A
, B
, C
);
982 BODY_40_59 (U
, 46, C
, D
, E
, T
, A
, B
);
983 BODY_40_59 (U
, 47, B
, C
, D
, E
, T
, A
);
984 BODY_40_59 (U
, 48, A
, B
, C
, D
, E
, T
);
985 BODY_40_59 (U
, 49, T
, A
, B
, C
, D
, E
);
986 BODY_40_59 (U
, 50, E
, T
, A
, B
, C
, D
);
987 BODY_40_59 (U
, 51, D
, E
, T
, A
, B
, C
);
988 BODY_40_59 (U
, 52, C
, D
, E
, T
, A
, B
);
989 BODY_40_59 (U
, 53, B
, C
, D
, E
, T
, A
);
990 BODY_40_59 (U
, 54, A
, B
, C
, D
, E
, T
);
991 BODY_40_59 (U
, 55, T
, A
, B
, C
, D
, E
);
992 BODY_40_59 (U
, 56, E
, T
, A
, B
, C
, D
);
993 BODY_40_59 (U
, 57, D
, E
, T
, A
, B
, C
);
994 BODY_40_59 (U
, 58, C
, D
, E
, T
, A
, B
);
995 BODY_40_59 (U
, 59, B
, C
, D
, E
, T
, A
);
997 BODY_60_79 (U
, 60, A
, B
, C
, D
, E
, T
);
998 BODY_60_79 (U
, 61, T
, A
, B
, C
, D
, E
);
999 BODY_60_79 (U
, 62, E
, T
, A
, B
, C
, D
);
1000 BODY_60_79 (U
, 63, D
, E
, T
, A
, B
, C
);
1001 BODY_60_79 (U
, 64, C
, D
, E
, T
, A
, B
);
1002 BODY_60_79 (U
, 65, B
, C
, D
, E
, T
, A
);
1003 BODY_60_79 (U
, 66, A
, B
, C
, D
, E
, T
);
1004 BODY_60_79 (U
, 67, T
, A
, B
, C
, D
, E
);
1005 BODY_60_79 (U
, 68, E
, T
, A
, B
, C
, D
);
1006 BODY_60_79 (U
, 69, D
, E
, T
, A
, B
, C
);
1007 BODY_60_79 (U
, 70, C
, D
, E
, T
, A
, B
);
1008 BODY_60_79 (U
, 71, B
, C
, D
, E
, T
, A
);
1009 BODY_60_79 (U
, 72, A
, B
, C
, D
, E
, T
);
1010 BODY_60_79 (U
, 73, T
, A
, B
, C
, D
, E
);
1011 BODY_60_79 (U
, 74, E
, T
, A
, B
, C
, D
);
1012 BODY_60_79 (U
, 75, D
, E
, T
, A
, B
, C
);
1013 BODY_60_79 (U
, 76, C
, D
, E
, T
, A
, B
);
1014 BODY_60_79 (U
, 77, B
, C
, D
, E
, T
, A
);
1015 BODY_60_79 (U
, 78, A
, B
, C
, D
, E
, T
);
1016 BODY_60_79 (U
, 79, T
, A
, B
, C
, D
, E
);
1025 static void endSHA(DigestContextSHA
*ctx
)
1027 static const sal_uInt8 end
[4] =
1029 0x80, 0x00, 0x00, 0x00
1031 const sal_uInt8
*p
= end
;
1037 i
= (ctx
->m_nDatLen
>> 2);
1039 #ifdef OSL_BIGENDIAN
1041 #endif /* OSL_BIGENDIAN */
1043 switch (ctx
->m_nDatLen
& 0x03)
1045 case 1: X
[i
] &= 0x000000ff; break;
1046 case 2: X
[i
] &= 0x0000ffff; break;
1047 case 3: X
[i
] &= 0x00ffffff; break;
1050 switch (ctx
->m_nDatLen
& 0x03)
1052 case 0: X
[i
] = static_cast<sal_uInt32
>(*(p
++)) << 0;
1054 case 1: X
[i
] |= static_cast<sal_uInt32
>(*(p
++)) << 8;
1056 case 2: X
[i
] |= static_cast<sal_uInt32
>(*(p
++)) << 16;
1058 case 3: X
[i
] |= static_cast<sal_uInt32
>(*(p
++)) << 24;
1065 // tdf#114939 NB: this is WRONG and should be ">" not ">=" but is not
1066 // fixed as this buggy SHA1 implementation is needed for compatibility
1067 if (i
>= (DIGEST_LBLOCK_SHA
- 2))
1069 for (; i
< DIGEST_LBLOCK_SHA
; i
++)
1078 for (; i
< (DIGEST_LBLOCK_SHA
- 2); i
++)
1083 X
[DIGEST_LBLOCK_SHA
- 2] = ctx
->m_nH
;
1084 X
[DIGEST_LBLOCK_SHA
- 1] = ctx
->m_nL
;
1089 const Digest_Impl SHA_0
=
1091 rtl_Digest_AlgorithmSHA
,
1092 RTL_DIGEST_LENGTH_SHA
,
1094 rtl_digest_destroySHA
,
1095 rtl_digest_updateSHA
,
1099 static sal_uInt32
updateSHA_0(sal_uInt32 x
)
1104 rtlDigestError SAL_CALL
rtl_digest_SHA(
1105 const void *pData
, sal_uInt32 nDatLen
,
1106 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1108 DigestSHA_Impl digest
;
1109 rtlDigestError result
;
1111 digest
.m_digest
= SHA_0
;
1112 initSHA(&(digest
.m_context
), updateSHA_0
);
1114 result
= rtl_digest_updateSHA(&digest
, pData
, nDatLen
);
1115 if (result
== rtl_Digest_E_None
)
1116 result
= rtl_digest_getSHA(&digest
, pBuffer
, nBufLen
);
1118 rtl_secureZeroMemory(&digest
, sizeof(digest
));
1122 rtlDigest SAL_CALL
rtl_digest_createSHA() SAL_THROW_EXTERN_C()
1124 DigestSHA_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestSHA_Impl
);
1127 pImpl
->m_digest
= SHA_0
;
1128 initSHA(&(pImpl
->m_context
), updateSHA_0
);
1130 return static_cast<rtlDigest
>(pImpl
);
1133 rtlDigestError SAL_CALL
rtl_digest_updateSHA(
1134 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1135 SAL_THROW_EXTERN_C()
1137 DigestSHA_Impl
*pImpl
= static_cast<DigestSHA_Impl
*>(Digest
);
1138 const sal_uInt8
*d
= static_cast<const sal_uInt8
*>(pData
);
1140 DigestContextSHA
*ctx
;
1143 if (!pImpl
|| !pData
)
1144 return rtl_Digest_E_Argument
;
1146 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmSHA
)
1147 return rtl_Digest_E_Algorithm
;
1150 return rtl_Digest_E_None
;
1152 ctx
= &(pImpl
->m_context
);
1154 len
= ctx
->m_nL
+ (nDatLen
<< 3);
1155 if (len
< ctx
->m_nL
)
1158 ctx
->m_nH
+= (nDatLen
>> 29);
1163 sal_uInt8
*p
= reinterpret_cast<sal_uInt8
*>(ctx
->m_pData
) + ctx
->m_nDatLen
;
1164 sal_uInt32 n
= DIGEST_CBLOCK_SHA
- ctx
->m_nDatLen
;
1168 memcpy(p
, d
, nDatLen
);
1169 ctx
->m_nDatLen
+= nDatLen
;
1171 return rtl_Digest_E_None
;
1178 #ifndef OSL_BIGENDIAN
1179 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1180 #endif /* OSL_BIGENDIAN */
1186 while (nDatLen
>= DIGEST_CBLOCK_SHA
)
1188 memcpy(ctx
->m_pData
, d
, DIGEST_CBLOCK_SHA
);
1189 d
+= DIGEST_CBLOCK_SHA
;
1190 nDatLen
-= DIGEST_CBLOCK_SHA
;
1192 #ifndef OSL_BIGENDIAN
1193 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1194 #endif /* OSL_BIGENDIAN */
1199 memcpy(ctx
->m_pData
, d
, nDatLen
);
1200 ctx
->m_nDatLen
= nDatLen
;
1202 return rtl_Digest_E_None
;
1205 rtlDigestError SAL_CALL
rtl_digest_getSHA(
1206 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1207 SAL_THROW_EXTERN_C()
1209 DigestSHA_Impl
*pImpl
= static_cast<DigestSHA_Impl
*>(Digest
);
1210 sal_uInt8
*p
= pBuffer
;
1212 DigestContextSHA
*ctx
;
1214 if (!pImpl
|| !pBuffer
)
1215 return rtl_Digest_E_Argument
;
1217 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmSHA
)
1218 return rtl_Digest_E_Algorithm
;
1220 if (pImpl
->m_digest
.m_length
> nBufLen
)
1221 return rtl_Digest_E_BufferSize
;
1223 ctx
= &(pImpl
->m_context
);
1226 RTL_DIGEST_HTONL(ctx
->m_nA
, p
);
1227 RTL_DIGEST_HTONL(ctx
->m_nB
, p
);
1228 RTL_DIGEST_HTONL(ctx
->m_nC
, p
);
1229 RTL_DIGEST_HTONL(ctx
->m_nD
, p
);
1230 RTL_DIGEST_HTONL(ctx
->m_nE
, p
);
1231 initSHA(ctx
, updateSHA_0
);
1233 return rtl_Digest_E_None
;
1236 void SAL_CALL
rtl_digest_destroySHA(rtlDigest Digest
) SAL_THROW_EXTERN_C()
1238 DigestSHA_Impl
*pImpl
= static_cast< DigestSHA_Impl
* >(Digest
);
1241 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA
)
1242 rtl_freeZeroMemory(pImpl
, sizeof(DigestSHA_Impl
));
1248 const Digest_Impl SHA_1
=
1250 rtl_Digest_AlgorithmSHA1
,
1251 RTL_DIGEST_LENGTH_SHA1
,
1253 rtl_digest_destroySHA1
,
1254 rtl_digest_updateSHA1
,
1258 static sal_uInt32
updateSHA_1(sal_uInt32 x
)
1260 return RTL_DIGEST_ROTL(x
, 1);
1263 rtlDigestError SAL_CALL
rtl_digest_SHA1(
1264 const void *pData
, sal_uInt32 nDatLen
,
1265 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1267 DigestSHA_Impl digest
;
1268 rtlDigestError result
;
1270 digest
.m_digest
= SHA_1
;
1271 initSHA(&(digest
.m_context
), updateSHA_1
);
1273 result
= rtl_digest_updateSHA1(&digest
, pData
, nDatLen
);
1274 if (result
== rtl_Digest_E_None
)
1275 result
= rtl_digest_getSHA1(&digest
, pBuffer
, nBufLen
);
1277 rtl_secureZeroMemory(&digest
, sizeof(digest
));
1281 rtlDigest SAL_CALL
rtl_digest_createSHA1() SAL_THROW_EXTERN_C()
1283 DigestSHA_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestSHA_Impl
);
1286 pImpl
->m_digest
= SHA_1
;
1287 initSHA(&(pImpl
->m_context
), updateSHA_1
);
1289 return static_cast<rtlDigest
>(pImpl
);
1292 rtlDigestError SAL_CALL
rtl_digest_updateSHA1(
1293 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1294 SAL_THROW_EXTERN_C()
1296 DigestSHA_Impl
*pImpl
= static_cast< DigestSHA_Impl
* >(Digest
);
1297 const sal_uInt8
*d
= static_cast< const sal_uInt8
* >(pData
);
1299 DigestContextSHA
*ctx
;
1302 if (!pImpl
|| !pData
)
1303 return rtl_Digest_E_Argument
;
1305 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmSHA1
)
1306 return rtl_Digest_E_Algorithm
;
1309 return rtl_Digest_E_None
;
1311 ctx
= &(pImpl
->m_context
);
1313 len
= ctx
->m_nL
+ (nDatLen
<< 3);
1314 if (len
< ctx
->m_nL
)
1317 ctx
->m_nH
+= (nDatLen
>> 29);
1322 sal_uInt8
*p
= reinterpret_cast<sal_uInt8
*>(ctx
->m_pData
) + ctx
->m_nDatLen
;
1323 sal_uInt32 n
= DIGEST_CBLOCK_SHA
- ctx
->m_nDatLen
;
1327 memcpy(p
, d
, nDatLen
);
1328 ctx
->m_nDatLen
+= nDatLen
;
1330 return rtl_Digest_E_None
;
1337 #ifndef OSL_BIGENDIAN
1338 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1339 #endif /* OSL_BIGENDIAN */
1345 while (nDatLen
>= DIGEST_CBLOCK_SHA
)
1347 memcpy(ctx
->m_pData
, d
, DIGEST_CBLOCK_SHA
);
1348 d
+= DIGEST_CBLOCK_SHA
;
1349 nDatLen
-= DIGEST_CBLOCK_SHA
;
1351 #ifndef OSL_BIGENDIAN
1352 swapLong(ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1353 #endif /* OSL_BIGENDIAN */
1358 memcpy(ctx
->m_pData
, d
, nDatLen
);
1359 ctx
->m_nDatLen
= nDatLen
;
1361 return rtl_Digest_E_None
;
1364 rtlDigestError SAL_CALL
rtl_digest_getSHA1 (
1365 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1366 SAL_THROW_EXTERN_C()
1368 DigestSHA_Impl
*pImpl
= static_cast<DigestSHA_Impl
*>(Digest
);
1369 sal_uInt8
*p
= pBuffer
;
1371 DigestContextSHA
*ctx
;
1373 if (!pImpl
|| !pBuffer
)
1374 return rtl_Digest_E_Argument
;
1376 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmSHA1
)
1377 return rtl_Digest_E_Algorithm
;
1379 if (pImpl
->m_digest
.m_length
> nBufLen
)
1380 return rtl_Digest_E_BufferSize
;
1382 ctx
= &(pImpl
->m_context
);
1385 RTL_DIGEST_HTONL(ctx
->m_nA
, p
);
1386 RTL_DIGEST_HTONL(ctx
->m_nB
, p
);
1387 RTL_DIGEST_HTONL(ctx
->m_nC
, p
);
1388 RTL_DIGEST_HTONL(ctx
->m_nD
, p
);
1389 RTL_DIGEST_HTONL(ctx
->m_nE
, p
);
1390 initSHA(ctx
, updateSHA_1
);
1392 return rtl_Digest_E_None
;
1395 void SAL_CALL
rtl_digest_destroySHA1(rtlDigest Digest
) SAL_THROW_EXTERN_C()
1397 DigestSHA_Impl
*pImpl
= static_cast< DigestSHA_Impl
* >(Digest
);
1400 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA1
)
1401 rtl_freeZeroMemory(pImpl
, sizeof(DigestSHA_Impl
));
1407 #define DIGEST_CBLOCK_HMAC_MD5 64
1411 struct ContextHMAC_MD5
1413 DigestMD5_Impl m_hash
;
1414 sal_uInt8 m_opad
[DIGEST_CBLOCK_HMAC_MD5
];
1417 struct DigestHMAC_MD5_Impl
1419 Digest_Impl m_digest
;
1420 ContextHMAC_MD5 m_context
;
1425 static void initHMAC_MD5(ContextHMAC_MD5
* ctx
);
1426 static void ipadHMAC_MD5(ContextHMAC_MD5
* ctx
);
1427 static void opadHMAC_MD5(ContextHMAC_MD5
* ctx
);
1429 const Digest_Impl HMAC_MD5
=
1431 rtl_Digest_AlgorithmHMAC_MD5
,
1432 RTL_DIGEST_LENGTH_MD5
,
1434 rtl_digest_initHMAC_MD5
,
1435 rtl_digest_destroyHMAC_MD5
,
1436 rtl_digest_updateHMAC_MD5
,
1437 rtl_digest_getHMAC_MD5
1440 static void initHMAC_MD5(ContextHMAC_MD5
* ctx
)
1442 DigestMD5_Impl
*pImpl
= &(ctx
->m_hash
);
1444 pImpl
->m_digest
= MD5
;
1445 initMD5(&(pImpl
->m_context
));
1447 memset(ctx
->m_opad
, 0, DIGEST_CBLOCK_HMAC_MD5
);
1450 static void ipadHMAC_MD5(ContextHMAC_MD5
* ctx
)
1454 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1456 ctx
->m_opad
[i
] ^= 0x36;
1459 rtl_digest_updateMD5(&(ctx
->m_hash
), ctx
->m_opad
, DIGEST_CBLOCK_HMAC_MD5
);
1461 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1463 ctx
->m_opad
[i
] ^= 0x36;
1467 static void opadHMAC_MD5(ContextHMAC_MD5
* ctx
)
1471 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1473 ctx
->m_opad
[i
] ^= 0x5c;
1477 rtlDigestError SAL_CALL
rtl_digest_HMAC_MD5(
1478 const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
1479 const void *pData
, sal_uInt32 nDatLen
,
1480 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1482 DigestHMAC_MD5_Impl digest
;
1483 rtlDigestError result
;
1485 digest
.m_digest
= HMAC_MD5
;
1487 result
= rtl_digest_initHMAC_MD5(&digest
, pKeyData
, nKeyLen
);
1488 if (result
== rtl_Digest_E_None
)
1490 result
= rtl_digest_updateHMAC_MD5(&digest
, pData
, nDatLen
);
1491 if (result
== rtl_Digest_E_None
)
1492 result
= rtl_digest_getHMAC_MD5(&digest
, pBuffer
, nBufLen
);
1495 rtl_secureZeroMemory(&digest
, sizeof(digest
));
1499 rtlDigest SAL_CALL
rtl_digest_createHMAC_MD5() SAL_THROW_EXTERN_C()
1501 DigestHMAC_MD5_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl
);
1504 pImpl
->m_digest
= HMAC_MD5
;
1505 initHMAC_MD5(&(pImpl
->m_context
));
1507 return static_cast< rtlDigest
>(pImpl
);
1510 rtlDigestError SAL_CALL
rtl_digest_initHMAC_MD5(
1511 rtlDigest Digest
, const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
)
1512 SAL_THROW_EXTERN_C()
1514 DigestHMAC_MD5_Impl
*pImpl
= static_cast< DigestHMAC_MD5_Impl
* >(Digest
);
1515 ContextHMAC_MD5
*ctx
;
1517 if (!pImpl
|| !pKeyData
)
1518 return rtl_Digest_E_Argument
;
1520 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_MD5
)
1521 return rtl_Digest_E_Algorithm
;
1523 ctx
= &(pImpl
->m_context
);
1526 if (nKeyLen
> DIGEST_CBLOCK_HMAC_MD5
)
1528 /* Initialize 'opad' with hashed 'KeyData' */
1529 rtl_digest_updateMD5(&(ctx
->m_hash
), pKeyData
, nKeyLen
);
1530 rtl_digest_getMD5(&(ctx
->m_hash
), ctx
->m_opad
, RTL_DIGEST_LENGTH_MD5
);
1534 /* Initialize 'opad' with plain 'KeyData' */
1535 memcpy(ctx
->m_opad
, pKeyData
, nKeyLen
);
1541 return rtl_Digest_E_None
;
1544 rtlDigestError SAL_CALL
rtl_digest_updateHMAC_MD5(
1545 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1546 SAL_THROW_EXTERN_C()
1548 DigestHMAC_MD5_Impl
*pImpl
= static_cast< DigestHMAC_MD5_Impl
* >(Digest
);
1549 ContextHMAC_MD5
*ctx
;
1551 if (!pImpl
|| !pData
)
1552 return rtl_Digest_E_Argument
;
1554 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_MD5
)
1555 return rtl_Digest_E_Algorithm
;
1557 ctx
= &(pImpl
->m_context
);
1558 rtl_digest_updateMD5(&(ctx
->m_hash
), pData
, nDatLen
);
1560 return rtl_Digest_E_None
;
1563 rtlDigestError SAL_CALL
rtl_digest_getHMAC_MD5(
1564 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1565 SAL_THROW_EXTERN_C()
1567 DigestHMAC_MD5_Impl
*pImpl
= static_cast<DigestHMAC_MD5_Impl
*>(Digest
);
1568 ContextHMAC_MD5
*ctx
;
1570 if (!pImpl
|| !pBuffer
)
1571 return rtl_Digest_E_Argument
;
1573 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_MD5
)
1574 return rtl_Digest_E_Algorithm
;
1576 if (pImpl
->m_digest
.m_length
> nBufLen
)
1577 return rtl_Digest_E_BufferSize
;
1579 nBufLen
= pImpl
->m_digest
.m_length
;
1581 ctx
= &(pImpl
->m_context
);
1582 rtl_digest_getMD5(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1584 rtl_digest_updateMD5(&(ctx
->m_hash
), ctx
->m_opad
, 64);
1585 rtl_digest_updateMD5(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1586 rtl_digest_getMD5(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1592 return rtl_Digest_E_None
;
1595 void SAL_CALL
rtl_digest_destroyHMAC_MD5(rtlDigest Digest
) SAL_THROW_EXTERN_C()
1597 DigestHMAC_MD5_Impl
*pImpl
= static_cast< DigestHMAC_MD5_Impl
* >(Digest
);
1600 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_MD5
)
1601 rtl_freeZeroMemory(pImpl
, sizeof(DigestHMAC_MD5_Impl
));
1607 #define DIGEST_CBLOCK_HMAC_SHA1 64
1611 struct ContextHMAC_SHA1
1613 DigestSHA_Impl m_hash
;
1614 sal_uInt8 m_opad
[DIGEST_CBLOCK_HMAC_SHA1
];
1617 struct DigestHMAC_SHA1_Impl
1619 Digest_Impl m_digest
;
1620 ContextHMAC_SHA1 m_context
;
1625 static void initHMAC_SHA1(ContextHMAC_SHA1
* ctx
);
1626 static void ipadHMAC_SHA1(ContextHMAC_SHA1
* ctx
);
1627 static void opadHMAC_SHA1(ContextHMAC_SHA1
* ctx
);
1629 const Digest_Impl HMAC_SHA1
=
1631 rtl_Digest_AlgorithmHMAC_SHA1
,
1632 RTL_DIGEST_LENGTH_SHA1
,
1633 rtl_digest_initHMAC_SHA1
,
1634 rtl_digest_destroyHMAC_SHA1
,
1635 rtl_digest_updateHMAC_SHA1
,
1636 rtl_digest_getHMAC_SHA1
1639 static void initHMAC_SHA1(ContextHMAC_SHA1
* ctx
)
1641 DigestSHA_Impl
*pImpl
= &(ctx
->m_hash
);
1643 pImpl
->m_digest
= SHA_1
;
1644 initSHA(&(pImpl
->m_context
), updateSHA_1
);
1646 memset(ctx
->m_opad
, 0, DIGEST_CBLOCK_HMAC_SHA1
);
1649 static void ipadHMAC_SHA1(ContextHMAC_SHA1
* ctx
)
1653 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1655 ctx
->m_opad
[i
] ^= 0x36;
1658 rtl_digest_updateSHA1(&(ctx
->m_hash
), ctx
->m_opad
, DIGEST_CBLOCK_HMAC_SHA1
);
1660 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1662 ctx
->m_opad
[i
] ^= 0x36;
1666 static void opadHMAC_SHA1(ContextHMAC_SHA1
* ctx
)
1670 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1672 ctx
->m_opad
[i
] ^= 0x5c;
1676 rtlDigestError SAL_CALL
rtl_digest_HMAC_SHA1(
1677 const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
1678 const void *pData
, sal_uInt32 nDatLen
,
1679 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1681 DigestHMAC_SHA1_Impl digest
;
1682 rtlDigestError result
;
1684 digest
.m_digest
= HMAC_SHA1
;
1686 result
= rtl_digest_initHMAC_SHA1(&digest
, pKeyData
, nKeyLen
);
1687 if (result
== rtl_Digest_E_None
)
1689 result
= rtl_digest_updateHMAC_SHA1(&digest
, pData
, nDatLen
);
1690 if (result
== rtl_Digest_E_None
)
1691 result
= rtl_digest_getHMAC_SHA1(&digest
, pBuffer
, nBufLen
);
1694 rtl_secureZeroMemory(&digest
, sizeof(digest
));
1698 rtlDigest SAL_CALL
rtl_digest_createHMAC_SHA1() SAL_THROW_EXTERN_C()
1700 DigestHMAC_SHA1_Impl
*pImpl
= RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl
);
1703 pImpl
->m_digest
= HMAC_SHA1
;
1704 initHMAC_SHA1(&(pImpl
->m_context
));
1706 return static_cast<rtlDigest
>(pImpl
);
1709 rtlDigestError SAL_CALL
rtl_digest_initHMAC_SHA1(
1710 rtlDigest Digest
, const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
)
1711 SAL_THROW_EXTERN_C()
1713 DigestHMAC_SHA1_Impl
*pImpl
= static_cast<DigestHMAC_SHA1_Impl
*>(Digest
);
1714 ContextHMAC_SHA1
*ctx
;
1716 if (!pImpl
|| !pKeyData
)
1717 return rtl_Digest_E_Argument
;
1719 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_SHA1
)
1720 return rtl_Digest_E_Algorithm
;
1722 ctx
= &(pImpl
->m_context
);
1725 if (nKeyLen
> DIGEST_CBLOCK_HMAC_SHA1
)
1727 /* Initialize 'opad' with hashed 'KeyData' */
1728 rtl_digest_updateSHA1(&(ctx
->m_hash
), pKeyData
, nKeyLen
);
1729 rtl_digest_getSHA1(&(ctx
->m_hash
), ctx
->m_opad
, RTL_DIGEST_LENGTH_SHA1
);
1733 /* Initialize 'opad' with plain 'KeyData' */
1734 memcpy(ctx
->m_opad
, pKeyData
, nKeyLen
);
1740 return rtl_Digest_E_None
;
1743 rtlDigestError SAL_CALL
rtl_digest_updateHMAC_SHA1(
1744 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1745 SAL_THROW_EXTERN_C()
1747 DigestHMAC_SHA1_Impl
*pImpl
= static_cast<DigestHMAC_SHA1_Impl
*>(Digest
);
1748 ContextHMAC_SHA1
*ctx
;
1750 if (!pImpl
|| !pData
)
1751 return rtl_Digest_E_Argument
;
1753 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_SHA1
)
1754 return rtl_Digest_E_Algorithm
;
1756 ctx
= &(pImpl
->m_context
);
1757 rtl_digest_updateSHA1(&(ctx
->m_hash
), pData
, nDatLen
);
1759 return rtl_Digest_E_None
;
1762 rtlDigestError SAL_CALL
rtl_digest_getHMAC_SHA1(
1763 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1764 SAL_THROW_EXTERN_C()
1766 DigestHMAC_SHA1_Impl
*pImpl
= static_cast<DigestHMAC_SHA1_Impl
*>(Digest
);
1767 ContextHMAC_SHA1
*ctx
;
1769 if (!pImpl
|| !pBuffer
)
1770 return rtl_Digest_E_Argument
;
1772 if (pImpl
->m_digest
.m_algorithm
!= rtl_Digest_AlgorithmHMAC_SHA1
)
1773 return rtl_Digest_E_Algorithm
;
1775 if (pImpl
->m_digest
.m_length
> nBufLen
)
1776 return rtl_Digest_E_BufferSize
;
1778 nBufLen
= pImpl
->m_digest
.m_length
;
1780 ctx
= &(pImpl
->m_context
);
1781 rtl_digest_getSHA1(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1783 rtl_digest_updateSHA1(&(ctx
->m_hash
), ctx
->m_opad
, sizeof(ctx
->m_opad
));
1784 rtl_digest_updateSHA1(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1785 rtl_digest_getSHA1(&(ctx
->m_hash
), pBuffer
, nBufLen
);
1791 return rtl_Digest_E_None
;
1794 void SAL_CALL
rtl_digest_destroyHMAC_SHA1(rtlDigest Digest
)
1795 SAL_THROW_EXTERN_C()
1797 DigestHMAC_SHA1_Impl
*pImpl
= static_cast<DigestHMAC_SHA1_Impl
*>(Digest
);
1800 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_SHA1
)
1801 rtl_freeZeroMemory(pImpl
, sizeof(DigestHMAC_SHA1_Impl
));
1807 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
1809 static void updatePBKDF2(
1811 sal_uInt8 T
[DIGEST_CBLOCK_PBKDF2
],
1812 const sal_uInt8
*pSaltData
, sal_uInt32 nSaltLen
,
1813 sal_uInt32 nCount
, sal_uInt32 nIndex
)
1815 /* T_i = F (P, S, c, i) */
1816 sal_uInt8 U
[DIGEST_CBLOCK_PBKDF2
];
1819 /* U_(1) = PRF (P, S || INDEX) */
1820 rtl_digest_updateHMAC_SHA1(hDigest
, pSaltData
, nSaltLen
);
1821 rtl_digest_updateHMAC_SHA1(hDigest
, &nIndex
, sizeof(nIndex
));
1822 rtl_digest_getHMAC_SHA1(hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
1825 for (k
= 0; k
< DIGEST_CBLOCK_PBKDF2
; k
++)
1830 /* T ^= U_(2) ^ ... ^ U_(c) */
1831 for (i
= 1; i
< nCount
; i
++)
1833 /* U_(i) = PRF (P, U_(i-1)) */
1834 rtl_digest_updateHMAC_SHA1(hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
1835 rtl_digest_getHMAC_SHA1(hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
1838 for (k
= 0; k
< DIGEST_CBLOCK_PBKDF2
; k
++)
1844 rtl_secureZeroMemory(U
, DIGEST_CBLOCK_PBKDF2
);
1847 rtlDigestError SAL_CALL
rtl_digest_PBKDF2(
1848 sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
1849 const sal_uInt8
*pPassData
, sal_uInt32 nPassLen
,
1850 const sal_uInt8
*pSaltData
, sal_uInt32 nSaltLen
,
1851 sal_uInt32 nCount
) SAL_THROW_EXTERN_C()
1853 DigestHMAC_SHA1_Impl digest
;
1856 if (!pKeyData
|| !pPassData
|| !pSaltData
)
1857 return rtl_Digest_E_Argument
;
1859 digest
.m_digest
= HMAC_SHA1
;
1860 rtl_digest_initHMAC_SHA1(&digest
, pPassData
, nPassLen
);
1862 /* DK = T_(1) || T_(2) || ... || T_(l) */
1863 while (nKeyLen
>= DIGEST_CBLOCK_PBKDF2
)
1865 /* T_(i) = F (P, S, c, i); DK ||= T_(i) */
1868 pSaltData
, nSaltLen
,
1869 nCount
, OSL_NETDWORD(i
));
1871 /* Next 'KeyData' block */
1872 pKeyData
+= DIGEST_CBLOCK_PBKDF2
;
1873 nKeyLen
-= DIGEST_CBLOCK_PBKDF2
;
1879 /* Last 'KeyData' block */
1880 sal_uInt8 T
[DIGEST_CBLOCK_PBKDF2
];
1882 /* T_i = F (P, S, c, i) */
1885 pSaltData
, nSaltLen
,
1886 nCount
, OSL_NETDWORD(i
));
1889 memcpy(pKeyData
, T
, nKeyLen
);
1890 rtl_secureZeroMemory(T
, DIGEST_CBLOCK_PBKDF2
);
1893 rtl_secureZeroMemory(&digest
, sizeof(digest
));
1894 return rtl_Digest_E_None
;
1897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */