LCOV - code coverage report
Current view: top level - libreoffice/sal/rtl/source - digest.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 460 833 55.2 %
Date: 2012-12-17 Functions: 31 60 51.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10