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 .
22 #include <sal/types.h>
23 #include <sal/macros.h>
24 #include <osl/endian.h>
25 #include <rtl/alloc.h>
26 #include <rtl/digest.h>
28 /*========================================================================
30 * rtlDigest internals.
32 *======================================================================*/
33 #define RTL_DIGEST_CREATE(T) ((T*)(rtl_allocateZeroMemory(sizeof(T))))
35 #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n))))
37 #define RTL_DIGEST_HTONL(l,c) \
38 (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
39 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
40 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
41 *((c)++) = (sal_uInt8)(((l) ) & 0xff))
43 #define RTL_DIGEST_LTOC(l,c) \
44 (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \
45 *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \
46 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
47 *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff))
49 typedef rtlDigestError (SAL_CALL Digest_init_t
) (
50 void *ctx
, const sal_uInt8
*Data
, sal_uInt32 DatLen
);
52 typedef void (SAL_CALL Digest_delete_t
) (void *ctx
);
54 typedef rtlDigestError (SAL_CALL Digest_update_t
) (
55 void *ctx
, const void *Data
, sal_uInt32 DatLen
);
57 typedef rtlDigestError (SAL_CALL Digest_get_t
) (
58 void *ctx
, sal_uInt8
*Buffer
, sal_uInt32 BufLen
);
62 rtlDigestAlgorithm m_algorithm
;
65 Digest_init_t
*m_init
;
66 Digest_delete_t
*m_delete
;
67 Digest_update_t
*m_update
;
72 * __rtl_digest_swapLong.
74 static void __rtl_digest_swapLong (sal_uInt32
*pData
, sal_uInt32 nDatLen
)
82 for (i
= 0; i
< n
; i
++)
83 X
[i
] = OSL_SWAPDWORD(X
[i
]);
86 /*========================================================================
88 * rtlDigest implementation.
90 *======================================================================*/
94 rtlDigest SAL_CALL
rtl_digest_create (rtlDigestAlgorithm Algorithm
)
97 rtlDigest Digest
= (rtlDigest
)NULL
;
100 case rtl_Digest_AlgorithmMD2
:
101 Digest
= rtl_digest_createMD2();
104 case rtl_Digest_AlgorithmMD5
:
105 Digest
= rtl_digest_createMD5();
108 case rtl_Digest_AlgorithmSHA
:
109 Digest
= rtl_digest_createSHA();
112 case rtl_Digest_AlgorithmSHA1
:
113 Digest
= rtl_digest_createSHA1();
116 case rtl_Digest_AlgorithmHMAC_MD5
:
117 Digest
= rtl_digest_createHMAC_MD5();
120 case rtl_Digest_AlgorithmHMAC_SHA1
:
121 Digest
= rtl_digest_createHMAC_SHA1();
124 default: /* rtl_Digest_AlgorithmInvalid */
131 * rtl_digest_queryAlgorithm.
133 rtlDigestAlgorithm SAL_CALL
rtl_digest_queryAlgorithm (rtlDigest Digest
)
136 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
138 return pImpl
->m_algorithm
;
140 return rtl_Digest_AlgorithmInvalid
;
144 * rtl_digest_queryLength.
146 sal_uInt32 SAL_CALL
rtl_digest_queryLength (rtlDigest Digest
)
149 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
151 return pImpl
->m_length
;
159 rtlDigestError SAL_CALL
rtl_digest_init (
160 rtlDigest Digest
, const sal_uInt8
*pData
, sal_uInt32 nDatLen
)
163 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
167 return pImpl
->m_init (Digest
, pData
, nDatLen
);
169 return rtl_Digest_E_None
;
171 return rtl_Digest_E_Argument
;
177 rtlDigestError SAL_CALL
rtl_digest_update (
178 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
181 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
182 if (pImpl
&& pImpl
->m_update
)
183 return pImpl
->m_update (Digest
, pData
, nDatLen
);
185 return rtl_Digest_E_Argument
;
191 rtlDigestError SAL_CALL
rtl_digest_get (
192 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
195 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
196 if (pImpl
&& pImpl
->m_get
)
197 return pImpl
->m_get (Digest
, pBuffer
, nBufLen
);
199 return rtl_Digest_E_Argument
;
203 * rtl_digest_destroy.
205 void SAL_CALL
rtl_digest_destroy (rtlDigest Digest
) SAL_THROW_EXTERN_C()
207 Digest_Impl
*pImpl
= (Digest_Impl
*)Digest
;
208 if (pImpl
&& pImpl
->m_delete
)
209 pImpl
->m_delete (Digest
);
212 /*========================================================================
214 * rtl_digest_MD2 internals.
216 *======================================================================*/
217 #define DIGEST_CBLOCK_MD2 16
218 #define DIGEST_LBLOCK_MD2 16
220 struct DigestContextMD2
222 sal_uInt32 m_nDatLen
;
223 sal_uInt8 m_pData
[DIGEST_CBLOCK_MD2
];
224 sal_uInt32 m_state
[DIGEST_LBLOCK_MD2
];
225 sal_uInt32 m_chksum
[DIGEST_LBLOCK_MD2
];
228 struct DigestMD2_Impl
230 Digest_Impl m_digest
;
231 DigestContextMD2 m_context
;
234 static void __rtl_digest_initMD2 (DigestContextMD2
*ctx
);
235 static void __rtl_digest_updateMD2 (DigestContextMD2
*ctx
);
236 static void __rtl_digest_endMD2 (DigestContextMD2
*ctx
);
238 static const sal_uInt32 S
[256] =
240 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
241 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
242 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
243 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
244 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
245 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
246 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
247 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
248 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
249 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
250 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
251 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
252 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
253 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
254 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
255 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
256 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
257 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
258 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
259 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
260 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
261 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
262 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
263 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
264 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
265 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
266 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
267 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
268 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
269 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
270 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
271 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
277 static const Digest_Impl __rtl_digest_MD2
=
279 rtl_Digest_AlgorithmMD2
,
280 RTL_DIGEST_LENGTH_MD2
,
283 rtl_digest_destroyMD2
,
284 rtl_digest_updateMD2
,
289 * __rtl_digest_initMD2.
291 static void __rtl_digest_initMD2 (DigestContextMD2
*ctx
)
293 memset (ctx
, 0, sizeof (DigestContextMD2
));
297 * __rtl_digest_updateMD2.
299 static void __rtl_digest_updateMD2 (DigestContextMD2
*ctx
)
302 sal_uInt32
*sp1
, *sp2
;
305 sal_uInt32 state
[48];
311 k
= sp2
[DIGEST_LBLOCK_MD2
- 1];
312 for (i
= 0; i
< 16; i
++)
314 state
[i
+ 0] = sp1
[i
];
315 state
[i
+ 16] = t
= X
[i
];
316 state
[i
+ 32] = t
^ sp1
[i
];
317 k
= sp2
[i
] ^= S
[t
^k
];
321 for (i
= 0; i
< 18; i
++)
323 for (k
= 0; k
< 48; k
+= 8)
325 t
= state
[k
+ 0] ^= S
[t
];
326 t
= state
[k
+ 1] ^= S
[t
];
327 t
= state
[k
+ 2] ^= S
[t
];
328 t
= state
[k
+ 3] ^= S
[t
];
329 t
= state
[k
+ 4] ^= S
[t
];
330 t
= state
[k
+ 5] ^= S
[t
];
331 t
= state
[k
+ 6] ^= S
[t
];
332 t
= state
[k
+ 7] ^= S
[t
];
334 t
= ((t
+ i
) & 0xff);
337 memcpy (sp1
, state
, 16 * sizeof(sal_uInt32
));
338 memset (state
, 0, 48 * sizeof(sal_uInt32
));
342 * __rtl_digest_endMD2.
344 static void __rtl_digest_endMD2 (DigestContextMD2
*ctx
)
352 n
= DIGEST_CBLOCK_MD2
- ctx
->m_nDatLen
;
354 for (i
= ctx
->m_nDatLen
; i
< DIGEST_CBLOCK_MD2
; i
++)
355 X
[i
] = (sal_uInt8
)(n
& 0xff);
356 __rtl_digest_updateMD2 (ctx
);
358 for (i
= 0; i
< DIGEST_CBLOCK_MD2
; i
++)
359 X
[i
] = (sal_uInt8
)(C
[i
] & 0xff);
360 __rtl_digest_updateMD2 (ctx
);
363 /*========================================================================
365 * rtl_digest_MD2 implementation.
367 *======================================================================*/
371 rtlDigestError SAL_CALL
rtl_digest_MD2 (
372 const void *pData
, sal_uInt32 nDatLen
,
373 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
375 DigestMD2_Impl digest
;
376 rtlDigestError result
;
378 digest
.m_digest
= __rtl_digest_MD2
;
379 __rtl_digest_initMD2 (&(digest
.m_context
));
381 result
= rtl_digest_updateMD2 (&digest
, pData
, nDatLen
);
382 if (result
== rtl_Digest_E_None
)
383 result
= rtl_digest_getMD2 (&digest
, pBuffer
, nBufLen
);
385 memset (&digest
, 0, sizeof (digest
));
390 * rtl_digest_createMD2.
392 rtlDigest SAL_CALL
rtl_digest_createMD2() SAL_THROW_EXTERN_C()
394 DigestMD2_Impl
*pImpl
= (DigestMD2_Impl
*)NULL
;
395 pImpl
= RTL_DIGEST_CREATE(DigestMD2_Impl
);
398 pImpl
->m_digest
= __rtl_digest_MD2
;
399 __rtl_digest_initMD2 (&(pImpl
->m_context
));
401 return ((rtlDigest
)pImpl
);
405 * rtl_digest_updateMD2.
407 rtlDigestError SAL_CALL
rtl_digest_updateMD2 (
408 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
411 DigestMD2_Impl
*pImpl
= (DigestMD2_Impl
*)Digest
;
412 const sal_uInt8
*d
= (const sal_uInt8
*)pData
;
414 DigestContextMD2
*ctx
;
416 if ((pImpl
== NULL
) || (pData
== NULL
))
417 return rtl_Digest_E_Argument
;
419 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD2
))
420 return rtl_Digest_E_Algorithm
;
423 return rtl_Digest_E_None
;
425 ctx
= &(pImpl
->m_context
);
429 sal_uInt8
*p
= ctx
->m_pData
+ ctx
->m_nDatLen
;
430 sal_uInt32 n
= DIGEST_CBLOCK_MD2
- ctx
->m_nDatLen
;
434 memcpy (p
, d
, nDatLen
);
435 ctx
->m_nDatLen
+= nDatLen
;
437 return rtl_Digest_E_None
;
444 __rtl_digest_updateMD2 (ctx
);
448 while (nDatLen
>= DIGEST_CBLOCK_MD2
)
450 memcpy (ctx
->m_pData
, d
, DIGEST_CBLOCK_MD2
);
451 d
+= DIGEST_CBLOCK_MD2
;
452 nDatLen
-= DIGEST_CBLOCK_MD2
;
454 __rtl_digest_updateMD2 (ctx
);
457 memcpy (ctx
->m_pData
, d
, nDatLen
);
458 ctx
->m_nDatLen
= nDatLen
;
460 return rtl_Digest_E_None
;
466 rtlDigestError SAL_CALL
rtl_digest_getMD2 (
467 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
470 DigestMD2_Impl
*pImpl
= (DigestMD2_Impl
*)Digest
;
473 DigestContextMD2
*ctx
;
475 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
476 return rtl_Digest_E_Argument
;
478 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD2
))
479 return rtl_Digest_E_Algorithm
;
481 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
482 return rtl_Digest_E_BufferSize
;
484 ctx
= &(pImpl
->m_context
);
486 __rtl_digest_endMD2 (ctx
);
487 for (i
= 0; i
< DIGEST_CBLOCK_MD2
; i
++)
488 pBuffer
[i
] = (sal_uInt8
)(ctx
->m_state
[i
] & 0xff);
489 __rtl_digest_initMD2 (ctx
);
491 return rtl_Digest_E_None
;
495 * rtl_digest_destroyMD2.
497 void SAL_CALL
rtl_digest_destroyMD2 (rtlDigest Digest
) SAL_THROW_EXTERN_C()
499 DigestMD2_Impl
*pImpl
= (DigestMD2_Impl
*)Digest
;
502 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD2
)
503 rtl_freeZeroMemory (pImpl
, sizeof (DigestMD2_Impl
));
505 rtl_freeMemory (pImpl
);
509 /*========================================================================
511 * rtl_digest_MD5 internals.
513 *======================================================================*/
514 #define DIGEST_CBLOCK_MD5 64
515 #define DIGEST_LBLOCK_MD5 16
517 struct DigestContextMD5
519 sal_uInt32 m_nDatLen
;
520 sal_uInt32 m_pData
[DIGEST_LBLOCK_MD5
];
521 sal_uInt32 m_nA
, m_nB
, m_nC
, m_nD
;
522 sal_uInt32 m_nL
, m_nH
;
525 struct DigestMD5_Impl
527 Digest_Impl m_digest
;
528 DigestContextMD5 m_context
;
531 static void __rtl_digest_initMD5 (DigestContextMD5
*ctx
);
532 static void __rtl_digest_updateMD5 (DigestContextMD5
*ctx
);
533 static void __rtl_digest_endMD5 (DigestContextMD5
*ctx
);
535 #define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
536 #define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
537 #define H(x,y,z) ((x) ^ (y) ^ (z))
538 #define I(x,y,z) (((x) | (~(z))) ^ (y))
540 #define R0(a,b,c,d,k,s,t) { \
541 a += ((k) + (t) + F((b), (c), (d))); \
542 a = RTL_DIGEST_ROTL(a, s); \
545 #define R1(a,b,c,d,k,s,t) { \
546 a += ((k) + (t) + G((b), (c), (d))); \
547 a = RTL_DIGEST_ROTL(a, s); \
550 #define R2(a,b,c,d,k,s,t) { \
551 a += ((k) + (t) + H((b), (c), (d))); \
552 a = RTL_DIGEST_ROTL(a, s); \
555 #define R3(a,b,c,d,k,s,t) { \
556 a += ((k) + (t) + I((b), (c), (d))); \
557 a = RTL_DIGEST_ROTL(a, s); \
563 static const Digest_Impl __rtl_digest_MD5
=
565 rtl_Digest_AlgorithmMD5
,
566 RTL_DIGEST_LENGTH_MD5
,
569 rtl_digest_destroyMD5
,
570 rtl_digest_updateMD5
,
575 * __rtl_digest_initMD5.
577 static void __rtl_digest_initMD5 (DigestContextMD5
*ctx
)
579 memset (ctx
, 0, sizeof (DigestContextMD5
));
581 ctx
->m_nA
= (sal_uInt32
)0x67452301L
;
582 ctx
->m_nB
= (sal_uInt32
)0xefcdab89L
;
583 ctx
->m_nC
= (sal_uInt32
)0x98badcfeL
;
584 ctx
->m_nD
= (sal_uInt32
)0x10325476L
;
588 * __rtl_digest_updateMD5.
590 static void __rtl_digest_updateMD5 (DigestContextMD5
*ctx
)
592 sal_uInt32 A
, B
, C
, D
;
601 R0 (A
, B
, C
, D
, X
[ 0], 7, 0xd76aa478L
);
602 R0 (D
, A
, B
, C
, X
[ 1], 12, 0xe8c7b756L
);
603 R0 (C
, D
, A
, B
, X
[ 2], 17, 0x242070dbL
);
604 R0 (B
, C
, D
, A
, X
[ 3], 22, 0xc1bdceeeL
);
605 R0 (A
, B
, C
, D
, X
[ 4], 7, 0xf57c0fafL
);
606 R0 (D
, A
, B
, C
, X
[ 5], 12, 0x4787c62aL
);
607 R0 (C
, D
, A
, B
, X
[ 6], 17, 0xa8304613L
);
608 R0 (B
, C
, D
, A
, X
[ 7], 22, 0xfd469501L
);
609 R0 (A
, B
, C
, D
, X
[ 8], 7, 0x698098d8L
);
610 R0 (D
, A
, B
, C
, X
[ 9], 12, 0x8b44f7afL
);
611 R0 (C
, D
, A
, B
, X
[10], 17, 0xffff5bb1L
);
612 R0 (B
, C
, D
, A
, X
[11], 22, 0x895cd7beL
);
613 R0 (A
, B
, C
, D
, X
[12], 7, 0x6b901122L
);
614 R0 (D
, A
, B
, C
, X
[13], 12, 0xfd987193L
);
615 R0 (C
, D
, A
, B
, X
[14], 17, 0xa679438eL
);
616 R0 (B
, C
, D
, A
, X
[15], 22, 0x49b40821L
);
618 R1 (A
, B
, C
, D
, X
[ 1], 5, 0xf61e2562L
);
619 R1 (D
, A
, B
, C
, X
[ 6], 9, 0xc040b340L
);
620 R1 (C
, D
, A
, B
, X
[11], 14, 0x265e5a51L
);
621 R1 (B
, C
, D
, A
, X
[ 0], 20, 0xe9b6c7aaL
);
622 R1 (A
, B
, C
, D
, X
[ 5], 5, 0xd62f105dL
);
623 R1 (D
, A
, B
, C
, X
[10], 9, 0x02441453L
);
624 R1 (C
, D
, A
, B
, X
[15], 14, 0xd8a1e681L
);
625 R1 (B
, C
, D
, A
, X
[ 4], 20, 0xe7d3fbc8L
);
626 R1 (A
, B
, C
, D
, X
[ 9], 5, 0x21e1cde6L
);
627 R1 (D
, A
, B
, C
, X
[14], 9, 0xc33707d6L
);
628 R1 (C
, D
, A
, B
, X
[ 3], 14, 0xf4d50d87L
);
629 R1 (B
, C
, D
, A
, X
[ 8], 20, 0x455a14edL
);
630 R1 (A
, B
, C
, D
, X
[13], 5, 0xa9e3e905L
);
631 R1 (D
, A
, B
, C
, X
[ 2], 9, 0xfcefa3f8L
);
632 R1 (C
, D
, A
, B
, X
[ 7], 14, 0x676f02d9L
);
633 R1 (B
, C
, D
, A
, X
[12], 20, 0x8d2a4c8aL
);
635 R2 (A
, B
, C
, D
, X
[ 5], 4, 0xfffa3942L
);
636 R2 (D
, A
, B
, C
, X
[ 8], 11, 0x8771f681L
);
637 R2 (C
, D
, A
, B
, X
[11], 16, 0x6d9d6122L
);
638 R2 (B
, C
, D
, A
, X
[14], 23, 0xfde5380cL
);
639 R2 (A
, B
, C
, D
, X
[ 1], 4, 0xa4beea44L
);
640 R2 (D
, A
, B
, C
, X
[ 4], 11, 0x4bdecfa9L
);
641 R2 (C
, D
, A
, B
, X
[ 7], 16, 0xf6bb4b60L
);
642 R2 (B
, C
, D
, A
, X
[10], 23, 0xbebfbc70L
);
643 R2 (A
, B
, C
, D
, X
[13], 4, 0x289b7ec6L
);
644 R2 (D
, A
, B
, C
, X
[ 0], 11, 0xeaa127faL
);
645 R2 (C
, D
, A
, B
, X
[ 3], 16, 0xd4ef3085L
);
646 R2 (B
, C
, D
, A
, X
[ 6], 23, 0x04881d05L
);
647 R2 (A
, B
, C
, D
, X
[ 9], 4, 0xd9d4d039L
);
648 R2 (D
, A
, B
, C
, X
[12], 11, 0xe6db99e5L
);
649 R2 (C
, D
, A
, B
, X
[15], 16, 0x1fa27cf8L
);
650 R2 (B
, C
, D
, A
, X
[ 2], 23, 0xc4ac5665L
);
652 R3 (A
, B
, C
, D
, X
[ 0], 6, 0xf4292244L
);
653 R3 (D
, A
, B
, C
, X
[ 7], 10, 0x432aff97L
);
654 R3 (C
, D
, A
, B
, X
[14], 15, 0xab9423a7L
);
655 R3 (B
, C
, D
, A
, X
[ 5], 21, 0xfc93a039L
);
656 R3 (A
, B
, C
, D
, X
[12], 6, 0x655b59c3L
);
657 R3 (D
, A
, B
, C
, X
[ 3], 10, 0x8f0ccc92L
);
658 R3 (C
, D
, A
, B
, X
[10], 15, 0xffeff47dL
);
659 R3 (B
, C
, D
, A
, X
[ 1], 21, 0x85845dd1L
);
660 R3 (A
, B
, C
, D
, X
[ 8], 6, 0x6fa87e4fL
);
661 R3 (D
, A
, B
, C
, X
[15], 10, 0xfe2ce6e0L
);
662 R3 (C
, D
, A
, B
, X
[ 6], 15, 0xa3014314L
);
663 R3 (B
, C
, D
, A
, X
[13], 21, 0x4e0811a1L
);
664 R3 (A
, B
, C
, D
, X
[ 4], 6, 0xf7537e82L
);
665 R3 (D
, A
, B
, C
, X
[11], 10, 0xbd3af235L
);
666 R3 (C
, D
, A
, B
, X
[ 2], 15, 0x2ad7d2bbL
);
667 R3 (B
, C
, D
, A
, X
[ 9], 21, 0xeb86d391L
);
676 * __rtl_digest_endMD5.
678 static void __rtl_digest_endMD5 (DigestContextMD5
*ctx
)
680 static const sal_uInt8 end
[4] =
682 0x80, 0x00, 0x00, 0x00
684 const sal_uInt8
*p
= end
;
690 i
= (ctx
->m_nDatLen
>> 2);
693 __rtl_digest_swapLong (X
, i
+ 1);
694 #endif /* OSL_BIGENDIAN */
696 switch (ctx
->m_nDatLen
& 0x03)
698 case 1: X
[i
] &= 0x000000ff; break;
699 case 2: X
[i
] &= 0x0000ffff; break;
700 case 3: X
[i
] &= 0x00ffffff; break;
703 switch (ctx
->m_nDatLen
& 0x03)
705 case 0: X
[i
] = ((sal_uInt32
)(*(p
++))) << 0L;
707 case 1: X
[i
] |= ((sal_uInt32
)(*(p
++))) << 8L;
709 case 2: X
[i
] |= ((sal_uInt32
)(*(p
++))) << 16L;
711 case 3: X
[i
] |= ((sal_uInt32
)(*p
)) << 24L;
717 if (i
>= (DIGEST_LBLOCK_MD5
- 2))
719 for (; i
< DIGEST_LBLOCK_MD5
; i
++)
721 __rtl_digest_updateMD5 (ctx
);
725 for (; i
< (DIGEST_LBLOCK_MD5
- 2); i
++)
728 X
[DIGEST_LBLOCK_MD5
- 2] = ctx
->m_nL
;
729 X
[DIGEST_LBLOCK_MD5
- 1] = ctx
->m_nH
;
731 __rtl_digest_updateMD5 (ctx
);
734 /*========================================================================
736 * rtl_digest_MD5 implementation.
738 *======================================================================*/
742 rtlDigestError SAL_CALL
rtl_digest_MD5 (
743 const void *pData
, sal_uInt32 nDatLen
,
744 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
746 DigestMD5_Impl digest
;
747 rtlDigestError result
;
749 digest
.m_digest
= __rtl_digest_MD5
;
750 __rtl_digest_initMD5 (&(digest
.m_context
));
752 result
= rtl_digest_update (&digest
, pData
, nDatLen
);
753 if (result
== rtl_Digest_E_None
)
754 result
= rtl_digest_getMD5 (&digest
, pBuffer
, nBufLen
);
756 memset (&digest
, 0, sizeof (digest
));
761 * rtl_digest_createMD5.
763 rtlDigest SAL_CALL
rtl_digest_createMD5() SAL_THROW_EXTERN_C()
765 DigestMD5_Impl
*pImpl
= (DigestMD5_Impl
*)NULL
;
766 pImpl
= RTL_DIGEST_CREATE(DigestMD5_Impl
);
769 pImpl
->m_digest
= __rtl_digest_MD5
;
770 __rtl_digest_initMD5 (&(pImpl
->m_context
));
772 return ((rtlDigest
)pImpl
);
776 * rtl_digest_updateMD5.
778 rtlDigestError SAL_CALL
rtl_digest_updateMD5 (
779 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
782 DigestMD5_Impl
*pImpl
= (DigestMD5_Impl
*)Digest
;
783 const sal_uInt8
*d
= (const sal_uInt8
*)pData
;
785 DigestContextMD5
*ctx
;
788 if ((pImpl
== NULL
) || (pData
== NULL
))
789 return rtl_Digest_E_Argument
;
791 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD5
))
792 return rtl_Digest_E_Algorithm
;
795 return rtl_Digest_E_None
;
797 ctx
= &(pImpl
->m_context
);
799 len
= ctx
->m_nL
+ (nDatLen
<< 3);
800 if (len
< ctx
->m_nL
) ctx
->m_nH
+= 1;
801 ctx
->m_nH
+= (nDatLen
>> 29);
806 sal_uInt8
*p
= (sal_uInt8
*)(ctx
->m_pData
) + ctx
->m_nDatLen
;
807 sal_uInt32 n
= DIGEST_CBLOCK_MD5
- ctx
->m_nDatLen
;
811 memcpy (p
, d
, nDatLen
);
812 ctx
->m_nDatLen
+= nDatLen
;
814 return rtl_Digest_E_None
;
822 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_MD5
);
823 #endif /* OSL_BIGENDIAN */
825 __rtl_digest_updateMD5 (ctx
);
829 while (nDatLen
>= DIGEST_CBLOCK_MD5
)
831 memcpy (ctx
->m_pData
, d
, DIGEST_CBLOCK_MD5
);
832 d
+= DIGEST_CBLOCK_MD5
;
833 nDatLen
-= DIGEST_CBLOCK_MD5
;
836 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_MD5
);
837 #endif /* OSL_BIGENDIAN */
839 __rtl_digest_updateMD5 (ctx
);
842 memcpy (ctx
->m_pData
, d
, nDatLen
);
843 ctx
->m_nDatLen
= nDatLen
;
845 return rtl_Digest_E_None
;
851 rtlDigestError SAL_CALL
rtl_digest_getMD5 (
852 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
855 DigestMD5_Impl
*pImpl
= (DigestMD5_Impl
*)Digest
;
856 sal_uInt8
*p
= pBuffer
;
858 DigestContextMD5
*ctx
;
860 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
861 return rtl_Digest_E_Argument
;
863 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD5
))
864 return rtl_Digest_E_Algorithm
;
866 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
867 return rtl_Digest_E_BufferSize
;
869 ctx
= &(pImpl
->m_context
);
871 __rtl_digest_endMD5 (ctx
);
872 RTL_DIGEST_LTOC (ctx
->m_nA
, p
);
873 RTL_DIGEST_LTOC (ctx
->m_nB
, p
);
874 RTL_DIGEST_LTOC (ctx
->m_nC
, p
);
875 RTL_DIGEST_LTOC (ctx
->m_nD
, p
);
876 __rtl_digest_initMD5 (ctx
);
878 return rtl_Digest_E_None
;
884 rtlDigestError SAL_CALL
rtl_digest_rawMD5 (
885 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
888 DigestMD5_Impl
*pImpl
= (DigestMD5_Impl
*)Digest
;
889 sal_uInt8
*p
= pBuffer
;
891 DigestContextMD5
*ctx
;
893 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
894 return rtl_Digest_E_Argument
;
896 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD5
))
897 return rtl_Digest_E_Algorithm
;
899 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
900 return rtl_Digest_E_BufferSize
;
902 ctx
= &(pImpl
->m_context
);
904 /* __rtl_digest_endMD5 (ctx); *//* not finalized */
905 RTL_DIGEST_LTOC (ctx
->m_nA
, p
);
906 RTL_DIGEST_LTOC (ctx
->m_nB
, p
);
907 RTL_DIGEST_LTOC (ctx
->m_nC
, p
);
908 RTL_DIGEST_LTOC (ctx
->m_nD
, p
);
909 __rtl_digest_initMD5 (ctx
);
911 return rtl_Digest_E_None
;
915 * rtl_digest_destroyMD5.
917 void SAL_CALL
rtl_digest_destroyMD5 (rtlDigest Digest
) SAL_THROW_EXTERN_C()
919 DigestMD5_Impl
*pImpl
= (DigestMD5_Impl
*)Digest
;
922 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmMD5
)
923 rtl_freeZeroMemory (pImpl
, sizeof (DigestMD5_Impl
));
925 rtl_freeMemory (pImpl
);
929 /*========================================================================
931 * rtl_digest_(SHA|SHA1) common internals.
933 *======================================================================*/
934 #define DIGEST_CBLOCK_SHA 64
935 #define DIGEST_LBLOCK_SHA 16
937 typedef sal_uInt32
DigestSHA_update_t (sal_uInt32 x
);
939 static sal_uInt32
__rtl_digest_updateSHA_0 (sal_uInt32 x
);
940 static sal_uInt32
__rtl_digest_updateSHA_1 (sal_uInt32 x
);
942 struct DigestContextSHA
944 DigestSHA_update_t
*m_update
;
945 sal_uInt32 m_nDatLen
;
946 sal_uInt32 m_pData
[DIGEST_LBLOCK_SHA
];
947 sal_uInt32 m_nA
, m_nB
, m_nC
, m_nD
, m_nE
;
948 sal_uInt32 m_nL
, m_nH
;
951 struct DigestSHA_Impl
953 Digest_Impl m_digest
;
954 DigestContextSHA m_context
;
957 static void __rtl_digest_initSHA (
958 DigestContextSHA
*ctx
, DigestSHA_update_t
*fct
);
960 static void __rtl_digest_updateSHA (DigestContextSHA
*ctx
);
961 static void __rtl_digest_endSHA (DigestContextSHA
*ctx
);
963 #define K_00_19 (sal_uInt32)0x5a827999L
964 #define K_20_39 (sal_uInt32)0x6ed9eba1L
965 #define K_40_59 (sal_uInt32)0x8f1bbcdcL
966 #define K_60_79 (sal_uInt32)0xca62c1d6L
968 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
969 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
970 #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
971 #define F_60_79(b,c,d) F_20_39(b,c,d)
974 (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f])
976 #define BODY_00_15(u,i,a,b,c,d,e,f) \
978 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
979 (b) = RTL_DIGEST_ROTL((b), 30);
981 #define BODY_16_19(u,i,a,b,c,d,e,f) \
983 (f) = X[(i)&0x0f] = (u)((f)); \
984 (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \
985 (b) = RTL_DIGEST_ROTL((b), 30);
987 #define BODY_20_39(u,i,a,b,c,d,e,f) \
989 (f) = X[(i)&0x0f] = (u)((f)); \
990 (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \
991 (b) = RTL_DIGEST_ROTL((b), 30);
993 #define BODY_40_59(u,i,a,b,c,d,e,f) \
995 (f) = X[(i)&0x0f] = (u)((f)); \
996 (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \
997 (b) = RTL_DIGEST_ROTL((b), 30);
999 #define BODY_60_79(u,i,a,b,c,d,e,f) \
1000 (f) = BODY_X((i)); \
1001 (f) = X[(i)&0x0f] = (u)((f)); \
1002 (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \
1003 (b) = RTL_DIGEST_ROTL((b), 30);
1006 * __rtl_digest_initSHA.
1008 static void __rtl_digest_initSHA (
1009 DigestContextSHA
*ctx
, DigestSHA_update_t
*fct
)
1011 memset (ctx
, 0, sizeof (DigestContextSHA
));
1012 ctx
->m_update
= fct
;
1014 ctx
->m_nA
= (sal_uInt32
)0x67452301L
;
1015 ctx
->m_nB
= (sal_uInt32
)0xefcdab89L
;
1016 ctx
->m_nC
= (sal_uInt32
)0x98badcfeL
;
1017 ctx
->m_nD
= (sal_uInt32
)0x10325476L
;
1018 ctx
->m_nE
= (sal_uInt32
)0xc3d2e1f0L
;
1022 * __rtl_digest_updateSHA.
1024 static void __rtl_digest_updateSHA (DigestContextSHA
*ctx
)
1026 sal_uInt32 A
, B
, C
, D
, E
, T
;
1029 DigestSHA_update_t
*U
;
1039 BODY_00_15 (U
, 0, A
, B
, C
, D
, E
, T
);
1040 BODY_00_15 (U
, 1, T
, A
, B
, C
, D
, E
);
1041 BODY_00_15 (U
, 2, E
, T
, A
, B
, C
, D
);
1042 BODY_00_15 (U
, 3, D
, E
, T
, A
, B
, C
);
1043 BODY_00_15 (U
, 4, C
, D
, E
, T
, A
, B
);
1044 BODY_00_15 (U
, 5, B
, C
, D
, E
, T
, A
);
1045 BODY_00_15 (U
, 6, A
, B
, C
, D
, E
, T
);
1046 BODY_00_15 (U
, 7, T
, A
, B
, C
, D
, E
);
1047 BODY_00_15 (U
, 8, E
, T
, A
, B
, C
, D
);
1048 BODY_00_15 (U
, 9, D
, E
, T
, A
, B
, C
);
1049 BODY_00_15 (U
, 10, C
, D
, E
, T
, A
, B
);
1050 BODY_00_15 (U
, 11, B
, C
, D
, E
, T
, A
);
1051 BODY_00_15 (U
, 12, A
, B
, C
, D
, E
, T
);
1052 BODY_00_15 (U
, 13, T
, A
, B
, C
, D
, E
);
1053 BODY_00_15 (U
, 14, E
, T
, A
, B
, C
, D
);
1054 BODY_00_15 (U
, 15, D
, E
, T
, A
, B
, C
);
1055 BODY_16_19 (U
, 16, C
, D
, E
, T
, A
, B
);
1056 BODY_16_19 (U
, 17, B
, C
, D
, E
, T
, A
);
1057 BODY_16_19 (U
, 18, A
, B
, C
, D
, E
, T
);
1058 BODY_16_19 (U
, 19, T
, A
, B
, C
, D
, E
);
1060 BODY_20_39 (U
, 20, E
, T
, A
, B
, C
, D
);
1061 BODY_20_39 (U
, 21, D
, E
, T
, A
, B
, C
);
1062 BODY_20_39 (U
, 22, C
, D
, E
, T
, A
, B
);
1063 BODY_20_39 (U
, 23, B
, C
, D
, E
, T
, A
);
1064 BODY_20_39 (U
, 24, A
, B
, C
, D
, E
, T
);
1065 BODY_20_39 (U
, 25, T
, A
, B
, C
, D
, E
);
1066 BODY_20_39 (U
, 26, E
, T
, A
, B
, C
, D
);
1067 BODY_20_39 (U
, 27, D
, E
, T
, A
, B
, C
);
1068 BODY_20_39 (U
, 28, C
, D
, E
, T
, A
, B
);
1069 BODY_20_39 (U
, 29, B
, C
, D
, E
, T
, A
);
1070 BODY_20_39 (U
, 30, A
, B
, C
, D
, E
, T
);
1071 BODY_20_39 (U
, 31, T
, A
, B
, C
, D
, E
);
1072 BODY_20_39 (U
, 32, E
, T
, A
, B
, C
, D
);
1073 BODY_20_39 (U
, 33, D
, E
, T
, A
, B
, C
);
1074 BODY_20_39 (U
, 34, C
, D
, E
, T
, A
, B
);
1075 BODY_20_39 (U
, 35, B
, C
, D
, E
, T
, A
);
1076 BODY_20_39 (U
, 36, A
, B
, C
, D
, E
, T
);
1077 BODY_20_39 (U
, 37, T
, A
, B
, C
, D
, E
);
1078 BODY_20_39 (U
, 38, E
, T
, A
, B
, C
, D
);
1079 BODY_20_39 (U
, 39, D
, E
, T
, A
, B
, C
);
1081 BODY_40_59 (U
, 40, C
, D
, E
, T
, A
, B
);
1082 BODY_40_59 (U
, 41, B
, C
, D
, E
, T
, A
);
1083 BODY_40_59 (U
, 42, A
, B
, C
, D
, E
, T
);
1084 BODY_40_59 (U
, 43, T
, A
, B
, C
, D
, E
);
1085 BODY_40_59 (U
, 44, E
, T
, A
, B
, C
, D
);
1086 BODY_40_59 (U
, 45, D
, E
, T
, A
, B
, C
);
1087 BODY_40_59 (U
, 46, C
, D
, E
, T
, A
, B
);
1088 BODY_40_59 (U
, 47, B
, C
, D
, E
, T
, A
);
1089 BODY_40_59 (U
, 48, A
, B
, C
, D
, E
, T
);
1090 BODY_40_59 (U
, 49, T
, A
, B
, C
, D
, E
);
1091 BODY_40_59 (U
, 50, E
, T
, A
, B
, C
, D
);
1092 BODY_40_59 (U
, 51, D
, E
, T
, A
, B
, C
);
1093 BODY_40_59 (U
, 52, C
, D
, E
, T
, A
, B
);
1094 BODY_40_59 (U
, 53, B
, C
, D
, E
, T
, A
);
1095 BODY_40_59 (U
, 54, A
, B
, C
, D
, E
, T
);
1096 BODY_40_59 (U
, 55, T
, A
, B
, C
, D
, E
);
1097 BODY_40_59 (U
, 56, E
, T
, A
, B
, C
, D
);
1098 BODY_40_59 (U
, 57, D
, E
, T
, A
, B
, C
);
1099 BODY_40_59 (U
, 58, C
, D
, E
, T
, A
, B
);
1100 BODY_40_59 (U
, 59, B
, C
, D
, E
, T
, A
);
1102 BODY_60_79 (U
, 60, A
, B
, C
, D
, E
, T
);
1103 BODY_60_79 (U
, 61, T
, A
, B
, C
, D
, E
);
1104 BODY_60_79 (U
, 62, E
, T
, A
, B
, C
, D
);
1105 BODY_60_79 (U
, 63, D
, E
, T
, A
, B
, C
);
1106 BODY_60_79 (U
, 64, C
, D
, E
, T
, A
, B
);
1107 BODY_60_79 (U
, 65, B
, C
, D
, E
, T
, A
);
1108 BODY_60_79 (U
, 66, A
, B
, C
, D
, E
, T
);
1109 BODY_60_79 (U
, 67, T
, A
, B
, C
, D
, E
);
1110 BODY_60_79 (U
, 68, E
, T
, A
, B
, C
, D
);
1111 BODY_60_79 (U
, 69, D
, E
, T
, A
, B
, C
);
1112 BODY_60_79 (U
, 70, C
, D
, E
, T
, A
, B
);
1113 BODY_60_79 (U
, 71, B
, C
, D
, E
, T
, A
);
1114 BODY_60_79 (U
, 72, A
, B
, C
, D
, E
, T
);
1115 BODY_60_79 (U
, 73, T
, A
, B
, C
, D
, E
);
1116 BODY_60_79 (U
, 74, E
, T
, A
, B
, C
, D
);
1117 BODY_60_79 (U
, 75, D
, E
, T
, A
, B
, C
);
1118 BODY_60_79 (U
, 76, C
, D
, E
, T
, A
, B
);
1119 BODY_60_79 (U
, 77, B
, C
, D
, E
, T
, A
);
1120 BODY_60_79 (U
, 78, A
, B
, C
, D
, E
, T
);
1121 BODY_60_79 (U
, 79, T
, A
, B
, C
, D
, E
);
1131 * __rtl_digest_endSHA.
1133 static void __rtl_digest_endSHA (DigestContextSHA
*ctx
)
1135 static const sal_uInt8 end
[4] =
1137 0x80, 0x00, 0x00, 0x00
1139 const sal_uInt8
*p
= end
;
1145 i
= (ctx
->m_nDatLen
>> 2);
1147 #ifdef OSL_BIGENDIAN
1148 __rtl_digest_swapLong (X
, i
+ 1);
1149 #endif /* OSL_BIGENDIAN */
1151 switch (ctx
->m_nDatLen
& 0x03)
1153 case 1: X
[i
] &= 0x000000ff; break;
1154 case 2: X
[i
] &= 0x0000ffff; break;
1155 case 3: X
[i
] &= 0x00ffffff; break;
1158 switch (ctx
->m_nDatLen
& 0x03)
1160 case 0: X
[i
] = ((sal_uInt32
)(*(p
++))) << 0L;
1162 case 1: X
[i
] |= ((sal_uInt32
)(*(p
++))) << 8L;
1164 case 2: X
[i
] |= ((sal_uInt32
)(*(p
++))) << 16L;
1166 case 3: X
[i
] |= ((sal_uInt32
)(*(p
++))) << 24L;
1170 __rtl_digest_swapLong (X
, i
+ 1);
1174 if (i
>= (DIGEST_LBLOCK_SHA
- 2))
1176 for (; i
< DIGEST_LBLOCK_SHA
; i
++)
1178 __rtl_digest_updateSHA (ctx
);
1182 for (; i
< (DIGEST_LBLOCK_SHA
- 2); i
++)
1185 X
[DIGEST_LBLOCK_SHA
- 2] = ctx
->m_nH
;
1186 X
[DIGEST_LBLOCK_SHA
- 1] = ctx
->m_nL
;
1188 __rtl_digest_updateSHA (ctx
);
1191 /*========================================================================
1193 * rtl_digest_SHA internals.
1195 *======================================================================*/
1197 * __rtl_digest_SHA_0.
1199 static const Digest_Impl __rtl_digest_SHA_0
=
1201 rtl_Digest_AlgorithmSHA
,
1202 RTL_DIGEST_LENGTH_SHA
,
1205 rtl_digest_destroySHA
,
1206 rtl_digest_updateSHA
,
1211 * __rtl_digest_updateSHA_0.
1213 static sal_uInt32
__rtl_digest_updateSHA_0 (sal_uInt32 x
)
1218 /*========================================================================
1220 * rtl_digest_SHA implementation.
1222 *======================================================================*/
1226 rtlDigestError SAL_CALL
rtl_digest_SHA (
1227 const void *pData
, sal_uInt32 nDatLen
,
1228 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1230 DigestSHA_Impl digest
;
1231 rtlDigestError result
;
1233 digest
.m_digest
= __rtl_digest_SHA_0
;
1234 __rtl_digest_initSHA (&(digest
.m_context
), __rtl_digest_updateSHA_0
);
1236 result
= rtl_digest_updateSHA (&digest
, pData
, nDatLen
);
1237 if (result
== rtl_Digest_E_None
)
1238 result
= rtl_digest_getSHA (&digest
, pBuffer
, nBufLen
);
1240 memset (&digest
, 0, sizeof (digest
));
1245 * rtl_digest_createSHA.
1247 rtlDigest SAL_CALL
rtl_digest_createSHA() SAL_THROW_EXTERN_C()
1249 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)NULL
;
1250 pImpl
= RTL_DIGEST_CREATE(DigestSHA_Impl
);
1253 pImpl
->m_digest
= __rtl_digest_SHA_0
;
1254 __rtl_digest_initSHA (&(pImpl
->m_context
), __rtl_digest_updateSHA_0
);
1256 return ((rtlDigest
)pImpl
);
1260 * rtl_digest_updateSHA.
1262 rtlDigestError SAL_CALL
rtl_digest_updateSHA (
1263 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1264 SAL_THROW_EXTERN_C()
1266 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1267 const sal_uInt8
*d
= (const sal_uInt8
*)pData
;
1269 DigestContextSHA
*ctx
;
1272 if ((pImpl
== NULL
) || (pData
== NULL
))
1273 return rtl_Digest_E_Argument
;
1275 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA
))
1276 return rtl_Digest_E_Algorithm
;
1279 return rtl_Digest_E_None
;
1281 ctx
= &(pImpl
->m_context
);
1283 len
= ctx
->m_nL
+ (nDatLen
<< 3);
1284 if (len
< ctx
->m_nL
) ctx
->m_nH
+= 1;
1285 ctx
->m_nH
+= (nDatLen
>> 29);
1290 sal_uInt8
*p
= (sal_uInt8
*)(ctx
->m_pData
) + ctx
->m_nDatLen
;
1291 sal_uInt32 n
= DIGEST_CBLOCK_SHA
- ctx
->m_nDatLen
;
1295 memcpy (p
, d
, nDatLen
);
1296 ctx
->m_nDatLen
+= nDatLen
;
1298 return rtl_Digest_E_None
;
1305 #ifndef OSL_BIGENDIAN
1306 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1307 #endif /* OSL_BIGENDIAN */
1309 __rtl_digest_updateSHA (ctx
);
1313 while (nDatLen
>= DIGEST_CBLOCK_SHA
)
1315 memcpy (ctx
->m_pData
, d
, DIGEST_CBLOCK_SHA
);
1316 d
+= DIGEST_CBLOCK_SHA
;
1317 nDatLen
-= DIGEST_CBLOCK_SHA
;
1319 #ifndef OSL_BIGENDIAN
1320 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1321 #endif /* OSL_BIGENDIAN */
1323 __rtl_digest_updateSHA (ctx
);
1326 memcpy (ctx
->m_pData
, d
, nDatLen
);
1327 ctx
->m_nDatLen
= nDatLen
;
1329 return rtl_Digest_E_None
;
1333 * rtl_digest_getSHA.
1335 rtlDigestError SAL_CALL
rtl_digest_getSHA (
1336 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1337 SAL_THROW_EXTERN_C()
1339 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1340 sal_uInt8
*p
= pBuffer
;
1342 DigestContextSHA
*ctx
;
1344 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
1345 return rtl_Digest_E_Argument
;
1347 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA
))
1348 return rtl_Digest_E_Algorithm
;
1350 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
1351 return rtl_Digest_E_BufferSize
;
1353 ctx
= &(pImpl
->m_context
);
1355 __rtl_digest_endSHA (ctx
);
1356 RTL_DIGEST_HTONL (ctx
->m_nA
, p
);
1357 RTL_DIGEST_HTONL (ctx
->m_nB
, p
);
1358 RTL_DIGEST_HTONL (ctx
->m_nC
, p
);
1359 RTL_DIGEST_HTONL (ctx
->m_nD
, p
);
1360 RTL_DIGEST_HTONL (ctx
->m_nE
, p
);
1361 __rtl_digest_initSHA (ctx
, __rtl_digest_updateSHA_0
);
1363 return rtl_Digest_E_None
;
1367 * rtl_digest_destroySHA.
1369 void SAL_CALL
rtl_digest_destroySHA (rtlDigest Digest
) SAL_THROW_EXTERN_C()
1371 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1374 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA
)
1375 rtl_freeZeroMemory (pImpl
, sizeof (DigestSHA_Impl
));
1377 rtl_freeMemory (pImpl
);
1381 /*========================================================================
1383 * rtl_digest_SHA1 internals.
1385 *======================================================================*/
1387 * __rtl_digest_SHA_1.
1389 static const Digest_Impl __rtl_digest_SHA_1
=
1391 rtl_Digest_AlgorithmSHA1
,
1392 RTL_DIGEST_LENGTH_SHA1
,
1395 rtl_digest_destroySHA1
,
1396 rtl_digest_updateSHA1
,
1401 * __rtl_digest_updateSHA_1.
1403 static sal_uInt32
__rtl_digest_updateSHA_1 (sal_uInt32 x
)
1405 return RTL_DIGEST_ROTL (x
, 1);
1408 /*========================================================================
1410 * rtl_digest_SHA1 implementation.
1412 *======================================================================*/
1416 rtlDigestError SAL_CALL
rtl_digest_SHA1 (
1417 const void *pData
, sal_uInt32 nDatLen
,
1418 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1420 DigestSHA_Impl digest
;
1421 rtlDigestError result
;
1423 digest
.m_digest
= __rtl_digest_SHA_1
;
1424 __rtl_digest_initSHA (&(digest
.m_context
), __rtl_digest_updateSHA_1
);
1426 result
= rtl_digest_updateSHA1 (&digest
, pData
, nDatLen
);
1427 if (result
== rtl_Digest_E_None
)
1428 result
= rtl_digest_getSHA1 (&digest
, pBuffer
, nBufLen
);
1430 memset (&digest
, 0, sizeof (digest
));
1435 * rtl_digest_createSHA1.
1437 rtlDigest SAL_CALL
rtl_digest_createSHA1() SAL_THROW_EXTERN_C()
1439 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)NULL
;
1440 pImpl
= RTL_DIGEST_CREATE(DigestSHA_Impl
);
1443 pImpl
->m_digest
= __rtl_digest_SHA_1
;
1444 __rtl_digest_initSHA (&(pImpl
->m_context
), __rtl_digest_updateSHA_1
);
1446 return ((rtlDigest
)pImpl
);
1450 * rtl_digest_updateSHA1.
1452 rtlDigestError SAL_CALL
rtl_digest_updateSHA1 (
1453 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1454 SAL_THROW_EXTERN_C()
1456 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1457 const sal_uInt8
*d
= (const sal_uInt8
*)pData
;
1459 DigestContextSHA
*ctx
;
1462 if ((pImpl
== NULL
) || (pData
== NULL
))
1463 return rtl_Digest_E_Argument
;
1465 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA1
))
1466 return rtl_Digest_E_Algorithm
;
1469 return rtl_Digest_E_None
;
1471 ctx
= &(pImpl
->m_context
);
1473 len
= ctx
->m_nL
+ (nDatLen
<< 3);
1474 if (len
< ctx
->m_nL
) ctx
->m_nH
+= 1;
1475 ctx
->m_nH
+= (nDatLen
>> 29);
1480 sal_uInt8
*p
= (sal_uInt8
*)(ctx
->m_pData
) + ctx
->m_nDatLen
;
1481 sal_uInt32 n
= DIGEST_CBLOCK_SHA
- ctx
->m_nDatLen
;
1485 memcpy (p
, d
, nDatLen
);
1486 ctx
->m_nDatLen
+= nDatLen
;
1488 return rtl_Digest_E_None
;
1495 #ifndef OSL_BIGENDIAN
1496 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1497 #endif /* OSL_BIGENDIAN */
1499 __rtl_digest_updateSHA (ctx
);
1503 while (nDatLen
>= DIGEST_CBLOCK_SHA
)
1505 memcpy (ctx
->m_pData
, d
, DIGEST_CBLOCK_SHA
);
1506 d
+= DIGEST_CBLOCK_SHA
;
1507 nDatLen
-= DIGEST_CBLOCK_SHA
;
1509 #ifndef OSL_BIGENDIAN
1510 __rtl_digest_swapLong (ctx
->m_pData
, DIGEST_LBLOCK_SHA
);
1511 #endif /* OSL_BIGENDIAN */
1513 __rtl_digest_updateSHA (ctx
);
1516 memcpy (ctx
->m_pData
, d
, nDatLen
);
1517 ctx
->m_nDatLen
= nDatLen
;
1519 return rtl_Digest_E_None
;
1523 * rtl_digest_getSHA1.
1525 rtlDigestError SAL_CALL
rtl_digest_getSHA1 (
1526 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1527 SAL_THROW_EXTERN_C()
1529 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1530 sal_uInt8
*p
= pBuffer
;
1532 DigestContextSHA
*ctx
;
1534 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
1535 return rtl_Digest_E_Argument
;
1537 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA1
))
1538 return rtl_Digest_E_Algorithm
;
1540 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
1541 return rtl_Digest_E_BufferSize
;
1543 ctx
= &(pImpl
->m_context
);
1545 __rtl_digest_endSHA (ctx
);
1546 RTL_DIGEST_HTONL (ctx
->m_nA
, p
);
1547 RTL_DIGEST_HTONL (ctx
->m_nB
, p
);
1548 RTL_DIGEST_HTONL (ctx
->m_nC
, p
);
1549 RTL_DIGEST_HTONL (ctx
->m_nD
, p
);
1550 RTL_DIGEST_HTONL (ctx
->m_nE
, p
);
1551 __rtl_digest_initSHA (ctx
, __rtl_digest_updateSHA_1
);
1553 return rtl_Digest_E_None
;
1557 * rtl_digest_destroySHA1.
1559 void SAL_CALL
rtl_digest_destroySHA1 (rtlDigest Digest
) SAL_THROW_EXTERN_C()
1561 DigestSHA_Impl
*pImpl
= (DigestSHA_Impl
*)Digest
;
1564 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmSHA1
)
1565 rtl_freeZeroMemory (pImpl
, sizeof (DigestSHA_Impl
));
1567 rtl_freeMemory (pImpl
);
1571 /*========================================================================
1573 * rtl_digest_HMAC_MD5 internals.
1575 *======================================================================*/
1576 #define DIGEST_CBLOCK_HMAC_MD5 64
1578 struct ContextHMAC_MD5
1580 DigestMD5_Impl m_hash
;
1581 sal_uInt8 m_opad
[DIGEST_CBLOCK_HMAC_MD5
];
1584 struct DigestHMAC_MD5_Impl
1586 Digest_Impl m_digest
;
1587 ContextHMAC_MD5 m_context
;
1590 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5
* ctx
);
1591 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5
* ctx
);
1592 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5
* ctx
);
1595 * __rtl_digest_HMAC_MD5.
1597 static const Digest_Impl __rtl_digest_HMAC_MD5
=
1599 rtl_Digest_AlgorithmHMAC_MD5
,
1600 RTL_DIGEST_LENGTH_MD5
,
1602 rtl_digest_initHMAC_MD5
,
1603 rtl_digest_destroyHMAC_MD5
,
1604 rtl_digest_updateHMAC_MD5
,
1605 rtl_digest_getHMAC_MD5
1609 * __rtl_digest_initHMAC_MD5.
1611 static void __rtl_digest_initHMAC_MD5 (ContextHMAC_MD5
* ctx
)
1613 DigestMD5_Impl
*pImpl
= &(ctx
->m_hash
);
1615 pImpl
->m_digest
= __rtl_digest_MD5
;
1616 __rtl_digest_initMD5 (&(pImpl
->m_context
));
1618 memset (ctx
->m_opad
, 0, DIGEST_CBLOCK_HMAC_MD5
);
1622 * __rtl_digest_ipadHMAC_MD5.
1624 static void __rtl_digest_ipadHMAC_MD5 (ContextHMAC_MD5
* ctx
)
1628 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1629 ctx
->m_opad
[i
] ^= 0x36;
1630 rtl_digest_updateMD5 (
1631 &(ctx
->m_hash
), ctx
->m_opad
, DIGEST_CBLOCK_HMAC_MD5
);
1632 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1633 ctx
->m_opad
[i
] ^= 0x36;
1637 * __rtl_digest_opadHMAC_MD5.
1639 static void __rtl_digest_opadHMAC_MD5 (ContextHMAC_MD5
* ctx
)
1643 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_MD5
; i
++)
1644 ctx
->m_opad
[i
] ^= 0x5c;
1647 /*========================================================================
1649 * rtl_digest_HMAC_MD5 implementation.
1651 *======================================================================*/
1653 * rtl_digest_HMAC_MD5.
1655 rtlDigestError SAL_CALL
rtl_digest_HMAC_MD5 (
1656 const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
1657 const void *pData
, sal_uInt32 nDatLen
,
1658 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1660 DigestHMAC_MD5_Impl digest
;
1661 rtlDigestError result
;
1663 digest
.m_digest
= __rtl_digest_HMAC_MD5
;
1665 result
= rtl_digest_initHMAC_MD5 (&digest
, pKeyData
, nKeyLen
);
1666 if (result
== rtl_Digest_E_None
)
1668 result
= rtl_digest_updateHMAC_MD5 (&digest
, pData
, nDatLen
);
1669 if (result
== rtl_Digest_E_None
)
1670 result
= rtl_digest_getHMAC_MD5 (&digest
, pBuffer
, nBufLen
);
1673 memset (&digest
, 0, sizeof (digest
));
1678 * rtl_digest_createHMAC_MD5.
1680 rtlDigest SAL_CALL
rtl_digest_createHMAC_MD5() SAL_THROW_EXTERN_C()
1682 DigestHMAC_MD5_Impl
*pImpl
= (DigestHMAC_MD5_Impl
*)NULL
;
1683 pImpl
= RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl
);
1686 pImpl
->m_digest
= __rtl_digest_HMAC_MD5
;
1687 __rtl_digest_initHMAC_MD5 (&(pImpl
->m_context
));
1689 return ((rtlDigest
)pImpl
);
1693 * rtl_digest_initHMAC_MD5.
1695 rtlDigestError SAL_CALL
rtl_digest_initHMAC_MD5 (
1696 rtlDigest Digest
, const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
)
1697 SAL_THROW_EXTERN_C()
1699 DigestHMAC_MD5_Impl
*pImpl
= (DigestHMAC_MD5_Impl
*)Digest
;
1700 ContextHMAC_MD5
*ctx
;
1702 if ((pImpl
== NULL
) || (pKeyData
== NULL
))
1703 return rtl_Digest_E_Argument
;
1705 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_MD5
))
1706 return rtl_Digest_E_Algorithm
;
1708 ctx
= &(pImpl
->m_context
);
1709 __rtl_digest_initHMAC_MD5 (ctx
);
1711 if (nKeyLen
> DIGEST_CBLOCK_HMAC_MD5
)
1713 /* Initialize 'opad' with hashed 'KeyData' */
1714 rtl_digest_updateMD5 (
1715 &(ctx
->m_hash
), pKeyData
, nKeyLen
);
1717 &(ctx
->m_hash
), ctx
->m_opad
, RTL_DIGEST_LENGTH_MD5
);
1721 /* Initialize 'opad' with plain 'KeyData' */
1722 memcpy (ctx
->m_opad
, pKeyData
, nKeyLen
);
1725 __rtl_digest_ipadHMAC_MD5 (ctx
);
1726 __rtl_digest_opadHMAC_MD5 (ctx
);
1728 return rtl_Digest_E_None
;
1732 * rtl_digest_updateHMAC_MD5.
1734 rtlDigestError SAL_CALL
rtl_digest_updateHMAC_MD5 (
1735 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1736 SAL_THROW_EXTERN_C()
1738 DigestHMAC_MD5_Impl
*pImpl
= (DigestHMAC_MD5_Impl
*)Digest
;
1739 ContextHMAC_MD5
*ctx
;
1741 if ((pImpl
== NULL
) || (pData
== NULL
))
1742 return rtl_Digest_E_Argument
;
1744 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_MD5
))
1745 return rtl_Digest_E_Algorithm
;
1747 ctx
= &(pImpl
->m_context
);
1748 rtl_digest_updateMD5 (&(ctx
->m_hash
), pData
, nDatLen
);
1750 return rtl_Digest_E_None
;
1754 * rtl_digest_getHMAC_MD5.
1756 rtlDigestError SAL_CALL
rtl_digest_getHMAC_MD5 (
1757 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1758 SAL_THROW_EXTERN_C()
1760 DigestHMAC_MD5_Impl
*pImpl
= (DigestHMAC_MD5_Impl
*)Digest
;
1761 ContextHMAC_MD5
*ctx
;
1763 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
1764 return rtl_Digest_E_Argument
;
1766 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_MD5
))
1767 return rtl_Digest_E_Algorithm
;
1769 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
1770 return rtl_Digest_E_BufferSize
;
1772 nBufLen
= pImpl
->m_digest
.m_length
;
1774 ctx
= &(pImpl
->m_context
);
1775 rtl_digest_getMD5 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
1777 rtl_digest_updateMD5 (&(ctx
->m_hash
), ctx
->m_opad
, 64);
1778 rtl_digest_updateMD5 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
1779 rtl_digest_getMD5 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
1781 __rtl_digest_opadHMAC_MD5 (ctx
);
1782 __rtl_digest_ipadHMAC_MD5 (ctx
);
1783 __rtl_digest_opadHMAC_MD5 (ctx
);
1785 return rtl_Digest_E_None
;
1789 * rtl_digest_destroyHMAC_MD5.
1791 void SAL_CALL
rtl_digest_destroyHMAC_MD5 (rtlDigest Digest
) SAL_THROW_EXTERN_C()
1793 DigestHMAC_MD5_Impl
*pImpl
= (DigestHMAC_MD5_Impl
*)Digest
;
1796 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_MD5
)
1797 rtl_freeZeroMemory (pImpl
, sizeof (DigestHMAC_MD5_Impl
));
1799 rtl_freeMemory (pImpl
);
1803 /*========================================================================
1805 * rtl_digest_HMAC_SHA1 internals.
1807 *======================================================================*/
1808 #define DIGEST_CBLOCK_HMAC_SHA1 64
1810 struct ContextHMAC_SHA1
1812 DigestSHA_Impl m_hash
;
1813 sal_uInt8 m_opad
[DIGEST_CBLOCK_HMAC_SHA1
];
1816 struct DigestHMAC_SHA1_Impl
1818 Digest_Impl m_digest
;
1819 ContextHMAC_SHA1 m_context
;
1822 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1
* ctx
);
1823 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1
* ctx
);
1824 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1
* ctx
);
1827 * __rtl_digest_HMAC_SHA1.
1829 static const Digest_Impl __rtl_digest_HMAC_SHA1
=
1831 rtl_Digest_AlgorithmHMAC_SHA1
,
1832 RTL_DIGEST_LENGTH_SHA1
,
1834 rtl_digest_initHMAC_SHA1
,
1835 rtl_digest_destroyHMAC_SHA1
,
1836 rtl_digest_updateHMAC_SHA1
,
1837 rtl_digest_getHMAC_SHA1
1841 * __rtl_digest_initHMAC_SHA1.
1843 static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1
* ctx
)
1845 DigestSHA_Impl
*pImpl
= &(ctx
->m_hash
);
1847 pImpl
->m_digest
= __rtl_digest_SHA_1
;
1848 __rtl_digest_initSHA (&(pImpl
->m_context
), __rtl_digest_updateSHA_1
);
1850 memset (ctx
->m_opad
, 0, DIGEST_CBLOCK_HMAC_SHA1
);
1854 * __rtl_digest_ipadHMAC_SHA1.
1856 static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1
* ctx
)
1860 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1861 ctx
->m_opad
[i
] ^= 0x36;
1862 rtl_digest_updateSHA1 (
1863 &(ctx
->m_hash
), ctx
->m_opad
, DIGEST_CBLOCK_HMAC_SHA1
);
1864 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1865 ctx
->m_opad
[i
] ^= 0x36;
1869 * __rtl_digest_opadHMAC_SHA1.
1871 static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1
* ctx
)
1875 for (i
= 0; i
< DIGEST_CBLOCK_HMAC_SHA1
; i
++)
1876 ctx
->m_opad
[i
] ^= 0x5c;
1879 /*========================================================================
1881 * rtl_digest_HMAC_SHA1 implementation.
1883 *======================================================================*/
1885 * rtl_digest_HMAC_SHA1.
1887 rtlDigestError SAL_CALL
rtl_digest_HMAC_SHA1 (
1888 const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
1889 const void *pData
, sal_uInt32 nDatLen
,
1890 sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
) SAL_THROW_EXTERN_C()
1892 DigestHMAC_SHA1_Impl digest
;
1893 rtlDigestError result
;
1895 digest
.m_digest
= __rtl_digest_HMAC_SHA1
;
1897 result
= rtl_digest_initHMAC_SHA1 (&digest
, pKeyData
, nKeyLen
);
1898 if (result
== rtl_Digest_E_None
)
1900 result
= rtl_digest_updateHMAC_SHA1 (&digest
, pData
, nDatLen
);
1901 if (result
== rtl_Digest_E_None
)
1902 result
= rtl_digest_getHMAC_SHA1 (&digest
, pBuffer
, nBufLen
);
1905 memset (&digest
, 0, sizeof (digest
));
1910 * rtl_digest_createHMAC_SHA1.
1912 rtlDigest SAL_CALL
rtl_digest_createHMAC_SHA1() SAL_THROW_EXTERN_C()
1914 DigestHMAC_SHA1_Impl
*pImpl
= (DigestHMAC_SHA1_Impl
*)NULL
;
1915 pImpl
= RTL_DIGEST_CREATE(DigestHMAC_SHA1_Impl
);
1918 pImpl
->m_digest
= __rtl_digest_HMAC_SHA1
;
1919 __rtl_digest_initHMAC_SHA1 (&(pImpl
->m_context
));
1921 return ((rtlDigest
)pImpl
);
1925 * rtl_digest_initHMAC_SHA1.
1927 rtlDigestError SAL_CALL
rtl_digest_initHMAC_SHA1 (
1928 rtlDigest Digest
, const sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
)
1929 SAL_THROW_EXTERN_C()
1931 DigestHMAC_SHA1_Impl
*pImpl
= (DigestHMAC_SHA1_Impl
*)Digest
;
1932 ContextHMAC_SHA1
*ctx
;
1934 if ((pImpl
== NULL
) || (pKeyData
== NULL
))
1935 return rtl_Digest_E_Argument
;
1937 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_SHA1
))
1938 return rtl_Digest_E_Algorithm
;
1940 ctx
= &(pImpl
->m_context
);
1941 __rtl_digest_initHMAC_SHA1 (ctx
);
1943 if (nKeyLen
> DIGEST_CBLOCK_HMAC_SHA1
)
1945 /* Initialize 'opad' with hashed 'KeyData' */
1946 rtl_digest_updateSHA1 (
1947 &(ctx
->m_hash
), pKeyData
, nKeyLen
);
1948 rtl_digest_getSHA1 (
1949 &(ctx
->m_hash
), ctx
->m_opad
, RTL_DIGEST_LENGTH_SHA1
);
1953 /* Initialize 'opad' with plain 'KeyData' */
1954 memcpy (ctx
->m_opad
, pKeyData
, nKeyLen
);
1957 __rtl_digest_ipadHMAC_SHA1 (ctx
);
1958 __rtl_digest_opadHMAC_SHA1 (ctx
);
1960 return rtl_Digest_E_None
;
1964 * rtl_digest_updateHMAC_SHA1.
1966 rtlDigestError SAL_CALL
rtl_digest_updateHMAC_SHA1 (
1967 rtlDigest Digest
, const void *pData
, sal_uInt32 nDatLen
)
1968 SAL_THROW_EXTERN_C()
1970 DigestHMAC_SHA1_Impl
*pImpl
= (DigestHMAC_SHA1_Impl
*)Digest
;
1971 ContextHMAC_SHA1
*ctx
;
1973 if ((pImpl
== NULL
) || (pData
== NULL
))
1974 return rtl_Digest_E_Argument
;
1976 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_SHA1
))
1977 return rtl_Digest_E_Algorithm
;
1979 ctx
= &(pImpl
->m_context
);
1980 rtl_digest_updateSHA1 (&(ctx
->m_hash
), pData
, nDatLen
);
1982 return rtl_Digest_E_None
;
1986 * rtl_digest_getHMAC_SHA1.
1988 rtlDigestError SAL_CALL
rtl_digest_getHMAC_SHA1 (
1989 rtlDigest Digest
, sal_uInt8
*pBuffer
, sal_uInt32 nBufLen
)
1990 SAL_THROW_EXTERN_C()
1992 DigestHMAC_SHA1_Impl
*pImpl
= (DigestHMAC_SHA1_Impl
*)Digest
;
1993 ContextHMAC_SHA1
*ctx
;
1995 if ((pImpl
== NULL
) || (pBuffer
== NULL
))
1996 return rtl_Digest_E_Argument
;
1998 if (!(pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_SHA1
))
1999 return rtl_Digest_E_Algorithm
;
2001 if (!(pImpl
->m_digest
.m_length
<= nBufLen
))
2002 return rtl_Digest_E_BufferSize
;
2004 nBufLen
= pImpl
->m_digest
.m_length
;
2006 ctx
= &(pImpl
->m_context
);
2007 rtl_digest_getSHA1 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
2009 rtl_digest_updateSHA1 (&(ctx
->m_hash
), ctx
->m_opad
, sizeof(ctx
->m_opad
));
2010 rtl_digest_updateSHA1 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
2011 rtl_digest_getSHA1 (&(ctx
->m_hash
), pBuffer
, nBufLen
);
2013 __rtl_digest_opadHMAC_SHA1 (ctx
);
2014 __rtl_digest_ipadHMAC_SHA1 (ctx
);
2015 __rtl_digest_opadHMAC_SHA1 (ctx
);
2017 return rtl_Digest_E_None
;
2021 * rtl_digest_destroyHMAC_SHA1.
2023 void SAL_CALL
rtl_digest_destroyHMAC_SHA1 (rtlDigest Digest
)
2024 SAL_THROW_EXTERN_C()
2026 DigestHMAC_SHA1_Impl
*pImpl
= (DigestHMAC_SHA1_Impl
*)Digest
;
2029 if (pImpl
->m_digest
.m_algorithm
== rtl_Digest_AlgorithmHMAC_SHA1
)
2030 rtl_freeZeroMemory (pImpl
, sizeof (DigestHMAC_SHA1_Impl
));
2032 rtl_freeMemory (pImpl
);
2036 /*========================================================================
2038 * rtl_digest_PBKDF2 internals.
2040 *======================================================================*/
2041 #define DIGEST_CBLOCK_PBKDF2 RTL_DIGEST_LENGTH_HMAC_SHA1
2044 * __rtl_digest_updatePBKDF2.
2046 static void __rtl_digest_updatePBKDF2 (
2048 sal_uInt8 T
[DIGEST_CBLOCK_PBKDF2
],
2049 const sal_uInt8
*pSaltData
, sal_uInt32 nSaltLen
,
2050 sal_uInt32 nCount
, sal_uInt32 nIndex
)
2052 /* T_i = F (P, S, c, i) */
2053 sal_uInt8 U
[DIGEST_CBLOCK_PBKDF2
];
2056 /* U_(1) = PRF (P, S || INDEX) */
2057 rtl_digest_updateHMAC_SHA1 (hDigest
, pSaltData
, nSaltLen
);
2058 rtl_digest_updateHMAC_SHA1 (hDigest
, &nIndex
, sizeof(nIndex
));
2059 rtl_digest_getHMAC_SHA1 (hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
2062 for (k
= 0; k
< DIGEST_CBLOCK_PBKDF2
; k
++) T
[k
] = U
[k
];
2064 /* T ^= U_(2) ^ ... ^ U_(c) */
2065 for (i
= 1; i
< nCount
; i
++)
2067 /* U_(i) = PRF (P, U_(i-1)) */
2068 rtl_digest_updateHMAC_SHA1 (hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
2069 rtl_digest_getHMAC_SHA1 (hDigest
, U
, DIGEST_CBLOCK_PBKDF2
);
2072 for (k
= 0; k
< DIGEST_CBLOCK_PBKDF2
; k
++) T
[k
] ^= U
[k
];
2075 memset (U
, 0, DIGEST_CBLOCK_PBKDF2
);
2078 /*========================================================================
2080 * rtl_digest_PBKDF2 implementation.
2082 *======================================================================*/
2084 * rtl_digest_PBKDF2.
2086 rtlDigestError SAL_CALL
rtl_digest_PBKDF2 (
2087 sal_uInt8
*pKeyData
, sal_uInt32 nKeyLen
,
2088 const sal_uInt8
*pPassData
, sal_uInt32 nPassLen
,
2089 const sal_uInt8
*pSaltData
, sal_uInt32 nSaltLen
,
2090 sal_uInt32 nCount
) SAL_THROW_EXTERN_C()
2092 DigestHMAC_SHA1_Impl digest
;
2095 if ((pKeyData
== NULL
) || (pPassData
== NULL
) || (pSaltData
== NULL
))
2096 return rtl_Digest_E_Argument
;
2098 digest
.m_digest
= __rtl_digest_HMAC_SHA1
;
2099 rtl_digest_initHMAC_SHA1 (&digest
, pPassData
, nPassLen
);
2101 /* DK = T_(1) || T_(2) || ... || T_(l) */
2102 while (nKeyLen
>= DIGEST_CBLOCK_PBKDF2
)
2104 /* T_(i) = F (P, S, c, i); DK ||= T_(i) */
2105 __rtl_digest_updatePBKDF2 (
2107 pSaltData
, nSaltLen
,
2108 nCount
, OSL_NETDWORD(i
));
2110 /* Next 'KeyData' block */
2111 pKeyData
+= DIGEST_CBLOCK_PBKDF2
;
2112 nKeyLen
-= DIGEST_CBLOCK_PBKDF2
;
2117 /* Last 'KeyData' block */
2118 sal_uInt8 T
[DIGEST_CBLOCK_PBKDF2
];
2120 /* T_i = F (P, S, c, i) */
2121 __rtl_digest_updatePBKDF2 (
2123 pSaltData
, nSaltLen
,
2124 nCount
, OSL_NETDWORD(i
));
2127 memcpy (pKeyData
, T
, nKeyLen
);
2128 memset (T
, 0, DIGEST_CBLOCK_PBKDF2
);
2131 memset (&digest
, 0, sizeof (digest
));
2132 return rtl_Digest_E_None
;
2135 /*========================================================================
2139 *======================================================================*/
2141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */