LCOV - code coverage report
Current view: top level - libreoffice/sal/rtl/source - digest.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 447 833 53.7 %
Date: 2012-12-27 Functions: 29 60 48.3 %
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      196697 : static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen)
      75             : {
      76             :     sal_uInt32 *X;
      77             :     int         i, n;
      78             : 
      79      196697 :     X = pData;
      80      196697 :     n = nDatLen;
      81             : 
      82     2360672 :     for (i = 0; i < n; i++)
      83     2163975 :         X[i] = OSL_SWAPDWORD(X[i]);
      84      196697 : }
      85             : 
      86             : /*========================================================================
      87             :  *
      88             :  * rtlDigest implementation.
      89             :  *
      90             :  *======================================================================*/
      91             : /*
      92             :  * rtl_digest_create.
      93             :  */
      94          94 : rtlDigest SAL_CALL rtl_digest_create (rtlDigestAlgorithm Algorithm)
      95             :     SAL_THROW_EXTERN_C()
      96             : {
      97          94 :     rtlDigest Digest = (rtlDigest)NULL;
      98          94 :     switch (Algorithm)
      99             :     {
     100             :         case rtl_Digest_AlgorithmMD2:
     101           0 :             Digest = rtl_digest_createMD2();
     102           0 :             break;
     103             : 
     104             :         case rtl_Digest_AlgorithmMD5:
     105          94 :             Digest = rtl_digest_createMD5();
     106          94 :             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          94 :     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           0 : sal_uInt32 SAL_CALL rtl_digest_queryLength (rtlDigest Digest)
     147             :     SAL_THROW_EXTERN_C()
     148             : {
     149           0 :     Digest_Impl *pImpl = (Digest_Impl *)Digest;
     150           0 :     if (pImpl)
     151           0 :         return pImpl->m_length;
     152             :     else
     153           0 :         return 0;
     154             : }
     155             : 
     156             : /*
     157             :  * rtl_digest_init.
     158             :  */
     159           0 : rtlDigestError SAL_CALL rtl_digest_init (
     160             :     rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen)
     161             :     SAL_THROW_EXTERN_C()
     162             : {
     163           0 :     Digest_Impl *pImpl = (Digest_Impl *)Digest;
     164           0 :     if (pImpl)
     165             :     {
     166           0 :         if (pImpl->m_init)
     167           0 :             return pImpl->m_init (Digest, pData, nDatLen);
     168             :         else
     169           0 :             return rtl_Digest_E_None;
     170             :     }
     171           0 :     return rtl_Digest_E_Argument;
     172             : }
     173             : 
     174             : /*
     175             :  * rtl_digest_update.
     176             :  */
     177       45217 : rtlDigestError SAL_CALL rtl_digest_update (
     178             :     rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
     179             :     SAL_THROW_EXTERN_C()
     180             : {
     181       45217 :     Digest_Impl *pImpl = (Digest_Impl *)Digest;
     182       45217 :     if (pImpl && pImpl->m_update)
     183       45217 :         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       16477 : rtlDigestError SAL_CALL rtl_digest_get (
     192             :     rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
     193             :     SAL_THROW_EXTERN_C()
     194             : {
     195       16477 :     Digest_Impl *pImpl = (Digest_Impl *)Digest;
     196       16477 :     if (pImpl && pImpl->m_get)
     197       16477 :         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          40 : void SAL_CALL rtl_digest_destroy (rtlDigest Digest) SAL_THROW_EXTERN_C()
     206             : {
     207          40 :     Digest_Impl *pImpl = (Digest_Impl *)Digest;
     208          40 :     if (pImpl && pImpl->m_delete)
     209          40 :         pImpl->m_delete (Digest);
     210          40 : }
     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       16579 : static void __rtl_digest_initMD5 (DigestContextMD5 *ctx)
     578             : {
     579       16579 :     memset (ctx, 0, sizeof (DigestContextMD5));
     580             : 
     581       16579 :     ctx->m_nA = (sal_uInt32)0x67452301L;
     582       16579 :     ctx->m_nB = (sal_uInt32)0xefcdab89L;
     583       16579 :     ctx->m_nC = (sal_uInt32)0x98badcfeL;
     584       16579 :     ctx->m_nD = (sal_uInt32)0x10325476L;
     585       16579 : }
     586             : 
     587             : /*
     588             :  * __rtl_digest_updateMD5.
     589             :  */
     590       16481 : static void __rtl_digest_updateMD5 (DigestContextMD5 *ctx)
     591             : {
     592             :     sal_uInt32  A, B, C, D;
     593             :     sal_uInt32 *X;
     594             : 
     595       16481 :     A = ctx->m_nA;
     596       16481 :     B = ctx->m_nB;
     597       16481 :     C = ctx->m_nC;
     598       16481 :     D = ctx->m_nD;
     599       16481 :     X = ctx->m_pData;
     600             : 
     601       16481 :     R0 (A, B, C, D, X[ 0],  7, 0xd76aa478L);
     602       16481 :     R0 (D, A, B, C, X[ 1], 12, 0xe8c7b756L);
     603       16481 :     R0 (C, D, A, B, X[ 2], 17, 0x242070dbL);
     604       16481 :     R0 (B, C, D, A, X[ 3], 22, 0xc1bdceeeL);
     605       16481 :     R0 (A, B, C, D, X[ 4],  7, 0xf57c0fafL);
     606       16481 :     R0 (D, A, B, C, X[ 5], 12, 0x4787c62aL);
     607       16481 :     R0 (C, D, A, B, X[ 6], 17, 0xa8304613L);
     608       16481 :     R0 (B, C, D, A, X[ 7], 22, 0xfd469501L);
     609       16481 :     R0 (A, B, C, D, X[ 8],  7, 0x698098d8L);
     610       16481 :     R0 (D, A, B, C, X[ 9], 12, 0x8b44f7afL);
     611       16481 :     R0 (C, D, A, B, X[10], 17, 0xffff5bb1L);
     612       16481 :     R0 (B, C, D, A, X[11], 22, 0x895cd7beL);
     613       16481 :     R0 (A, B, C, D, X[12],  7, 0x6b901122L);
     614       16481 :     R0 (D, A, B, C, X[13], 12, 0xfd987193L);
     615       16481 :     R0 (C, D, A, B, X[14], 17, 0xa679438eL);
     616       16481 :     R0 (B, C, D, A, X[15], 22, 0x49b40821L);
     617             : 
     618       16481 :     R1 (A, B, C, D, X[ 1],  5, 0xf61e2562L);
     619       16481 :     R1 (D, A, B, C, X[ 6],  9, 0xc040b340L);
     620       16481 :     R1 (C, D, A, B, X[11], 14, 0x265e5a51L);
     621       16481 :     R1 (B, C, D, A, X[ 0], 20, 0xe9b6c7aaL);
     622       16481 :     R1 (A, B, C, D, X[ 5],  5, 0xd62f105dL);
     623       16481 :     R1 (D, A, B, C, X[10],  9, 0x02441453L);
     624       16481 :     R1 (C, D, A, B, X[15], 14, 0xd8a1e681L);
     625       16481 :     R1 (B, C, D, A, X[ 4], 20, 0xe7d3fbc8L);
     626       16481 :     R1 (A, B, C, D, X[ 9],  5, 0x21e1cde6L);
     627       16481 :     R1 (D, A, B, C, X[14],  9, 0xc33707d6L);
     628       16481 :     R1 (C, D, A, B, X[ 3], 14, 0xf4d50d87L);
     629       16481 :     R1 (B, C, D, A, X[ 8], 20, 0x455a14edL);
     630       16481 :     R1 (A, B, C, D, X[13],  5, 0xa9e3e905L);
     631       16481 :     R1 (D, A, B, C, X[ 2],  9, 0xfcefa3f8L);
     632       16481 :     R1 (C, D, A, B, X[ 7], 14, 0x676f02d9L);
     633       16481 :     R1 (B, C, D, A, X[12], 20, 0x8d2a4c8aL);
     634             : 
     635       16481 :     R2 (A, B, C, D, X[ 5],  4, 0xfffa3942L);
     636       16481 :     R2 (D, A, B, C, X[ 8], 11, 0x8771f681L);
     637       16481 :     R2 (C, D, A, B, X[11], 16, 0x6d9d6122L);
     638       16481 :     R2 (B, C, D, A, X[14], 23, 0xfde5380cL);
     639       16481 :     R2 (A, B, C, D, X[ 1],  4, 0xa4beea44L);
     640       16481 :     R2 (D, A, B, C, X[ 4], 11, 0x4bdecfa9L);
     641       16481 :     R2 (C, D, A, B, X[ 7], 16, 0xf6bb4b60L);
     642       16481 :     R2 (B, C, D, A, X[10], 23, 0xbebfbc70L);
     643       16481 :     R2 (A, B, C, D, X[13],  4, 0x289b7ec6L);
     644       16481 :     R2 (D, A, B, C, X[ 0], 11, 0xeaa127faL);
     645       16481 :     R2 (C, D, A, B, X[ 3], 16, 0xd4ef3085L);
     646       16481 :     R2 (B, C, D, A, X[ 6], 23, 0x04881d05L);
     647       16481 :     R2 (A, B, C, D, X[ 9],  4, 0xd9d4d039L);
     648       16481 :     R2 (D, A, B, C, X[12], 11, 0xe6db99e5L);
     649       16481 :     R2 (C, D, A, B, X[15], 16, 0x1fa27cf8L);
     650       16481 :     R2 (B, C, D, A, X[ 2], 23, 0xc4ac5665L);
     651             : 
     652       16481 :     R3 (A, B, C, D, X[ 0],  6, 0xf4292244L);
     653       16481 :     R3 (D, A, B, C, X[ 7], 10, 0x432aff97L);
     654       16481 :     R3 (C, D, A, B, X[14], 15, 0xab9423a7L);
     655       16481 :     R3 (B, C, D, A, X[ 5], 21, 0xfc93a039L);
     656       16481 :     R3 (A, B, C, D, X[12],  6, 0x655b59c3L);
     657       16481 :     R3 (D, A, B, C, X[ 3], 10, 0x8f0ccc92L);
     658       16481 :     R3 (C, D, A, B, X[10], 15, 0xffeff47dL);
     659       16481 :     R3 (B, C, D, A, X[ 1], 21, 0x85845dd1L);
     660       16481 :     R3 (A, B, C, D, X[ 8],  6, 0x6fa87e4fL);
     661       16481 :     R3 (D, A, B, C, X[15], 10, 0xfe2ce6e0L);
     662       16481 :     R3 (C, D, A, B, X[ 6], 15, 0xa3014314L);
     663       16481 :     R3 (B, C, D, A, X[13], 21, 0x4e0811a1L);
     664       16481 :     R3 (A, B, C, D, X[ 4],  6, 0xf7537e82L);
     665       16481 :     R3 (D, A, B, C, X[11], 10, 0xbd3af235L);
     666       16481 :     R3 (C, D, A, B, X[ 2], 15, 0x2ad7d2bbL);
     667       16481 :     R3 (B, C, D, A, X[ 9], 21, 0xeb86d391L);
     668             : 
     669       16481 :     ctx->m_nA += A;
     670       16481 :     ctx->m_nB += B;
     671       16481 :     ctx->m_nC += C;
     672       16481 :     ctx->m_nD += D;
     673       16481 : }
     674             : 
     675             : /*
     676             :  * __rtl_digest_endMD5.
     677             :  */
     678       16481 : static void __rtl_digest_endMD5 (DigestContextMD5 *ctx)
     679             : {
     680             :     static const sal_uInt8 end[4] =
     681             :     {
     682             :         0x80, 0x00, 0x00, 0x00
     683             :     };
     684       16481 :     const sal_uInt8 *p = end;
     685             : 
     686             :     sal_uInt32 *X;
     687             :     int         i;
     688             : 
     689       16481 :     X = ctx->m_pData;
     690       16481 :     i = (ctx->m_nDatLen >> 2);
     691             : 
     692             : #ifdef OSL_BIGENDIAN
     693             :     __rtl_digest_swapLong (X, i + 1);
     694             : #endif /* OSL_BIGENDIAN */
     695             : 
     696       16481 :     switch (ctx->m_nDatLen & 0x03)
     697             :     {
     698           5 :         case 1: X[i] &= 0x000000ff; break;
     699           1 :         case 2: X[i] &= 0x0000ffff; break;
     700           2 :         case 3: X[i] &= 0x00ffffff; break;
     701             :     }
     702             : 
     703       16481 :     switch (ctx->m_nDatLen & 0x03)
     704             :     {
     705       16473 :         case 0: X[i]  = ((sal_uInt32)(*(p++))) <<  0L;
     706       16478 :         case 1: X[i] |= ((sal_uInt32)(*(p++))) <<  8L;
     707       16479 :         case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
     708       16481 :         case 3: X[i] |= ((sal_uInt32)(*p)) << 24L;
     709             :     }
     710             : 
     711       16481 :     i += 1;
     712             : 
     713       16481 :     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      114961 :     for (; i < (DIGEST_LBLOCK_MD5 - 2); i++)
     722       98480 :         X[i] = 0;
     723             : 
     724       16481 :     X[DIGEST_LBLOCK_MD5 - 2] = ctx->m_nL;
     725       16481 :     X[DIGEST_LBLOCK_MD5 - 1] = ctx->m_nH;
     726             : 
     727       16481 :     __rtl_digest_updateMD5 (ctx);
     728       16481 : }
     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          98 : rtlDigest SAL_CALL rtl_digest_createMD5() SAL_THROW_EXTERN_C()
     760             : {
     761          98 :     DigestMD5_Impl *pImpl = (DigestMD5_Impl*)NULL;
     762          98 :     pImpl = RTL_DIGEST_CREATE(DigestMD5_Impl);
     763          98 :     if (pImpl)
     764             :     {
     765          98 :         pImpl->m_digest = __rtl_digest_MD5;
     766          98 :         __rtl_digest_initMD5 (&(pImpl->m_context));
     767             :     }
     768          98 :     return ((rtlDigest)pImpl);
     769             : }
     770             : 
     771             : /*
     772             :  * rtl_digest_updateMD5.
     773             :  */
     774       45225 : rtlDigestError SAL_CALL rtl_digest_updateMD5 (
     775             :     rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
     776             :     SAL_THROW_EXTERN_C()
     777             : {
     778       45225 :     DigestMD5_Impl   *pImpl = (DigestMD5_Impl *)Digest;
     779       45225 :     const sal_uInt8  *d     = (const sal_uInt8 *)pData;
     780             : 
     781             :     DigestContextMD5 *ctx;
     782             :     sal_uInt32        len;
     783             : 
     784       45225 :     if ((pImpl == NULL) || (pData == NULL))
     785           0 :         return rtl_Digest_E_Argument;
     786             : 
     787       45225 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
     788           0 :         return rtl_Digest_E_Algorithm;
     789             : 
     790       45225 :     if (nDatLen == 0)
     791           0 :         return rtl_Digest_E_None;
     792             : 
     793       45225 :     ctx = &(pImpl->m_context);
     794             : 
     795       45225 :     len = ctx->m_nL + (nDatLen << 3);
     796       45225 :     if (len < ctx->m_nL) ctx->m_nH += 1;
     797       45225 :     ctx->m_nH += (nDatLen >> 29);
     798       45225 :     ctx->m_nL  = len;
     799             : 
     800       45225 :     if (ctx->m_nDatLen)
     801             :     {
     802       28744 :         sal_uInt8  *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
     803       28744 :         sal_uInt32  n = DIGEST_CBLOCK_MD5 - ctx->m_nDatLen;
     804             : 
     805       28744 :         if (nDatLen < n)
     806             :         {
     807       28744 :             memcpy (p, d, nDatLen);
     808       28744 :             ctx->m_nDatLen += nDatLen;
     809             : 
     810       28744 :             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       32962 :     while (nDatLen >= DIGEST_CBLOCK_MD5)
     826             :     {
     827           0 :         memcpy (ctx->m_pData, d, DIGEST_CBLOCK_MD5);
     828           0 :         d       += DIGEST_CBLOCK_MD5;
     829           0 :         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           0 :         __rtl_digest_updateMD5 (ctx);
     836             :     }
     837             : 
     838       16481 :     memcpy (ctx->m_pData, d, nDatLen);
     839       16481 :     ctx->m_nDatLen = nDatLen;
     840             : 
     841       16481 :     return rtl_Digest_E_None;
     842             : }
     843             : 
     844             : /*
     845             :  * rtl_digest_getMD5.
     846             :  */
     847       16481 : rtlDigestError SAL_CALL rtl_digest_getMD5 (
     848             :     rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
     849             :     SAL_THROW_EXTERN_C()
     850             : {
     851       16481 :     DigestMD5_Impl   *pImpl = (DigestMD5_Impl *)Digest;
     852       16481 :     sal_uInt8        *p     = pBuffer;
     853             : 
     854             :     DigestContextMD5 *ctx;
     855             : 
     856       16481 :     if ((pImpl == NULL) || (pBuffer == NULL))
     857           0 :         return rtl_Digest_E_Argument;
     858             : 
     859       16481 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5))
     860           0 :         return rtl_Digest_E_Algorithm;
     861             : 
     862       16481 :     if (!(pImpl->m_digest.m_length <= nBufLen))
     863           0 :         return rtl_Digest_E_BufferSize;
     864             : 
     865       16481 :     ctx = &(pImpl->m_context);
     866             : 
     867       16481 :     __rtl_digest_endMD5 (ctx);
     868       16481 :     RTL_DIGEST_LTOC (ctx->m_nA, p);
     869       16481 :     RTL_DIGEST_LTOC (ctx->m_nB, p);
     870       16481 :     RTL_DIGEST_LTOC (ctx->m_nC, p);
     871       16481 :     RTL_DIGEST_LTOC (ctx->m_nD, p);
     872       16481 :     __rtl_digest_initMD5 (ctx);
     873             : 
     874       16481 :     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          44 : void SAL_CALL rtl_digest_destroyMD5 (rtlDigest Digest) SAL_THROW_EXTERN_C()
     914             : {
     915          44 :     DigestMD5_Impl *pImpl = (DigestMD5_Impl *)Digest;
     916          44 :     if (pImpl)
     917             :     {
     918          44 :         if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD5)
     919          44 :             rtl_freeZeroMemory (pImpl, sizeof (DigestMD5_Impl));
     920             :         else
     921           0 :             rtl_freeMemory (pImpl);
     922             :     }
     923          44 : }
     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       98356 : static void __rtl_digest_initSHA (
    1005             :     DigestContextSHA *ctx, DigestSHA_update_t *fct)
    1006             : {
    1007       98356 :     memset (ctx, 0, sizeof (DigestContextSHA));
    1008       98356 :     ctx->m_update = fct;
    1009             : 
    1010       98356 :     ctx->m_nA = (sal_uInt32)0x67452301L;
    1011       98356 :     ctx->m_nB = (sal_uInt32)0xefcdab89L;
    1012       98356 :     ctx->m_nC = (sal_uInt32)0x98badcfeL;
    1013       98356 :     ctx->m_nD = (sal_uInt32)0x10325476L;
    1014       98356 :     ctx->m_nE = (sal_uInt32)0xc3d2e1f0L;
    1015       98356 : }
    1016             : 
    1017             : /*
    1018             :  * __rtl_digest_updateSHA.
    1019             :  */
    1020      196698 : 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      196698 :     U = ctx->m_update;
    1027             : 
    1028      196698 :     A = ctx->m_nA;
    1029      196698 :     B = ctx->m_nB;
    1030      196698 :     C = ctx->m_nC;
    1031      196698 :     D = ctx->m_nD;
    1032      196698 :     E = ctx->m_nE;
    1033      196698 :     X = ctx->m_pData;
    1034             : 
    1035      196698 :     BODY_00_15 (U,  0, A, B, C, D, E, T);
    1036      196698 :     BODY_00_15 (U,  1, T, A, B, C, D, E);
    1037      196698 :     BODY_00_15 (U,  2, E, T, A, B, C, D);
    1038      196698 :     BODY_00_15 (U,  3, D, E, T, A, B, C);
    1039      196698 :     BODY_00_15 (U,  4, C, D, E, T, A, B);
    1040      196698 :     BODY_00_15 (U,  5, B, C, D, E, T, A);
    1041      196698 :     BODY_00_15 (U,  6, A, B, C, D, E, T);
    1042      196698 :     BODY_00_15 (U,  7, T, A, B, C, D, E);
    1043      196698 :     BODY_00_15 (U,  8, E, T, A, B, C, D);
    1044      196698 :     BODY_00_15 (U,  9, D, E, T, A, B, C);
    1045      196698 :     BODY_00_15 (U, 10, C, D, E, T, A, B);
    1046      196698 :     BODY_00_15 (U, 11, B, C, D, E, T, A);
    1047      196698 :     BODY_00_15 (U, 12, A, B, C, D, E, T);
    1048      196698 :     BODY_00_15 (U, 13, T, A, B, C, D, E);
    1049      196698 :     BODY_00_15 (U, 14, E, T, A, B, C, D);
    1050      196698 :     BODY_00_15 (U, 15, D, E, T, A, B, C);
    1051      196698 :     BODY_16_19 (U, 16, C, D, E, T, A, B);
    1052      196698 :     BODY_16_19 (U, 17, B, C, D, E, T, A);
    1053      196698 :     BODY_16_19 (U, 18, A, B, C, D, E, T);
    1054      196698 :     BODY_16_19 (U, 19, T, A, B, C, D, E);
    1055             : 
    1056      196698 :     BODY_20_39 (U, 20, E, T, A, B, C, D);
    1057      196698 :     BODY_20_39 (U, 21, D, E, T, A, B, C);
    1058      196698 :     BODY_20_39 (U, 22, C, D, E, T, A, B);
    1059      196698 :     BODY_20_39 (U, 23, B, C, D, E, T, A);
    1060      196698 :     BODY_20_39 (U, 24, A, B, C, D, E, T);
    1061      196698 :     BODY_20_39 (U, 25, T, A, B, C, D, E);
    1062      196698 :     BODY_20_39 (U, 26, E, T, A, B, C, D);
    1063      196698 :     BODY_20_39 (U, 27, D, E, T, A, B, C);
    1064      196698 :     BODY_20_39 (U, 28, C, D, E, T, A, B);
    1065      196698 :     BODY_20_39 (U, 29, B, C, D, E, T, A);
    1066      196698 :     BODY_20_39 (U, 30, A, B, C, D, E, T);
    1067      196698 :     BODY_20_39 (U, 31, T, A, B, C, D, E);
    1068      196698 :     BODY_20_39 (U, 32, E, T, A, B, C, D);
    1069      196698 :     BODY_20_39 (U, 33, D, E, T, A, B, C);
    1070      196698 :     BODY_20_39 (U, 34, C, D, E, T, A, B);
    1071      196698 :     BODY_20_39 (U, 35, B, C, D, E, T, A);
    1072      196698 :     BODY_20_39 (U, 36, A, B, C, D, E, T);
    1073      196698 :     BODY_20_39 (U, 37, T, A, B, C, D, E);
    1074      196698 :     BODY_20_39 (U, 38, E, T, A, B, C, D);
    1075      196698 :     BODY_20_39 (U, 39, D, E, T, A, B, C);
    1076             : 
    1077      196698 :     BODY_40_59 (U, 40, C, D, E, T, A, B);
    1078      196698 :     BODY_40_59 (U, 41, B, C, D, E, T, A);
    1079      196698 :     BODY_40_59 (U, 42, A, B, C, D, E, T);
    1080      196698 :     BODY_40_59 (U, 43, T, A, B, C, D, E);
    1081      196698 :     BODY_40_59 (U, 44, E, T, A, B, C, D);
    1082      196698 :     BODY_40_59 (U, 45, D, E, T, A, B, C);
    1083      196698 :     BODY_40_59 (U, 46, C, D, E, T, A, B);
    1084      196698 :     BODY_40_59 (U, 47, B, C, D, E, T, A);
    1085      196698 :     BODY_40_59 (U, 48, A, B, C, D, E, T);
    1086      196698 :     BODY_40_59 (U, 49, T, A, B, C, D, E);
    1087      196698 :     BODY_40_59 (U, 50, E, T, A, B, C, D);
    1088      196698 :     BODY_40_59 (U, 51, D, E, T, A, B, C);
    1089      196698 :     BODY_40_59 (U, 52, C, D, E, T, A, B);
    1090      196698 :     BODY_40_59 (U, 53, B, C, D, E, T, A);
    1091      196698 :     BODY_40_59 (U, 54, A, B, C, D, E, T);
    1092      196698 :     BODY_40_59 (U, 55, T, A, B, C, D, E);
    1093      196698 :     BODY_40_59 (U, 56, E, T, A, B, C, D);
    1094      196698 :     BODY_40_59 (U, 57, D, E, T, A, B, C);
    1095      196698 :     BODY_40_59 (U, 58, C, D, E, T, A, B);
    1096      196698 :     BODY_40_59 (U, 59, B, C, D, E, T, A);
    1097             : 
    1098      196698 :     BODY_60_79 (U, 60, A, B, C, D, E, T);
    1099      196698 :     BODY_60_79 (U, 61, T, A, B, C, D, E);
    1100      196698 :     BODY_60_79 (U, 62, E, T, A, B, C, D);
    1101      196698 :     BODY_60_79 (U, 63, D, E, T, A, B, C);
    1102      196698 :     BODY_60_79 (U, 64, C, D, E, T, A, B);
    1103      196698 :     BODY_60_79 (U, 65, B, C, D, E, T, A);
    1104      196698 :     BODY_60_79 (U, 66, A, B, C, D, E, T);
    1105      196698 :     BODY_60_79 (U, 67, T, A, B, C, D, E);
    1106      196698 :     BODY_60_79 (U, 68, E, T, A, B, C, D);
    1107      196698 :     BODY_60_79 (U, 69, D, E, T, A, B, C);
    1108      196698 :     BODY_60_79 (U, 70, C, D, E, T, A, B);
    1109      196698 :     BODY_60_79 (U, 71, B, C, D, E, T, A);
    1110      196698 :     BODY_60_79 (U, 72, A, B, C, D, E, T);
    1111      196698 :     BODY_60_79 (U, 73, T, A, B, C, D, E);
    1112      196698 :     BODY_60_79 (U, 74, E, T, A, B, C, D);
    1113      196698 :     BODY_60_79 (U, 75, D, E, T, A, B, C);
    1114      196698 :     BODY_60_79 (U, 76, C, D, E, T, A, B);
    1115      196698 :     BODY_60_79 (U, 77, B, C, D, E, T, A);
    1116      196698 :     BODY_60_79 (U, 78, A, B, C, D, E, T);
    1117      196698 :     BODY_60_79 (U, 79, T, A, B, C, D, E);
    1118             : 
    1119      196698 :     ctx->m_nA += E;
    1120      196698 :     ctx->m_nB += T;
    1121      196698 :     ctx->m_nC += A;
    1122      196698 :     ctx->m_nD += B;
    1123      196698 :     ctx->m_nE += C;
    1124      196698 : }
    1125             : 
    1126             : /*
    1127             :  * __rtl_digest_endSHA.
    1128             :  */
    1129       98316 : static void __rtl_digest_endSHA (DigestContextSHA *ctx)
    1130             : {
    1131             :     static const sal_uInt8 end[4] =
    1132             :     {
    1133             :         0x80, 0x00, 0x00, 0x00
    1134             :     };
    1135       98316 :     const sal_uInt8 *p = end;
    1136             : 
    1137             :     sal_uInt32 *X;
    1138             :     int         i;
    1139             : 
    1140       98316 :     X = ctx->m_pData;
    1141       98316 :     i = (ctx->m_nDatLen >> 2);
    1142             : 
    1143             : #ifdef OSL_BIGENDIAN
    1144             :     __rtl_digest_swapLong (X, i + 1);
    1145             : #endif /* OSL_BIGENDIAN */
    1146             : 
    1147       98316 :     switch (ctx->m_nDatLen & 0x03)
    1148             :     {
    1149           2 :         case 1: X[i] &= 0x000000ff; break;
    1150           0 :         case 2: X[i] &= 0x0000ffff; break;
    1151           1 :         case 3: X[i] &= 0x00ffffff; break;
    1152             :     }
    1153             : 
    1154       98316 :     switch (ctx->m_nDatLen & 0x03)
    1155             :     {
    1156       98313 :         case 0: X[i]  = ((sal_uInt32)(*(p++))) <<  0L;
    1157       98315 :         case 1: X[i] |= ((sal_uInt32)(*(p++))) <<  8L;
    1158       98315 :         case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L;
    1159       98316 :         case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L;
    1160             :     }
    1161             : 
    1162       98316 :     __rtl_digest_swapLong (X, i + 1);
    1163             : 
    1164       98316 :     i += 1;
    1165             : 
    1166       98316 :     if (i >= (DIGEST_LBLOCK_SHA - 2))
    1167             :     {
    1168           2 :         for (; i < DIGEST_LBLOCK_SHA; i++)
    1169           1 :             X[i] = 0;
    1170           1 :         __rtl_digest_updateSHA (ctx);
    1171           1 :         i = 0;
    1172             :     }
    1173             : 
    1174      884876 :     for (; i < (DIGEST_LBLOCK_SHA - 2); i++)
    1175      786560 :         X[i] = 0;
    1176             : 
    1177       98316 :     X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH;
    1178       98316 :     X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL;
    1179             : 
    1180       98316 :     __rtl_digest_updateSHA (ctx);
    1181       98316 : }
    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    12588672 : static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x)
    1396             : {
    1397    12588672 :     return RTL_DIGEST_ROTL (x, 1);
    1398             : }
    1399             : 
    1400             : /*========================================================================
    1401             :  *
    1402             :  * rtl_digest_SHA1 implementation.
    1403             :  *
    1404             :  *======================================================================*/
    1405             : /*
    1406             :  * rtl_digest_SHA1.
    1407             :  */
    1408           8 : 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           8 :     digest.m_digest = __rtl_digest_SHA_1;
    1416           8 :     __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1);
    1417             : 
    1418           8 :     result = rtl_digest_updateSHA1 (&digest, pData, nDatLen);
    1419           8 :     if (result == rtl_Digest_E_None)
    1420           8 :         result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen);
    1421             : 
    1422           8 :     memset (&digest, 0, sizeof (digest));
    1423           8 :     return (result);
    1424             : }
    1425             : 
    1426             : /*
    1427             :  * rtl_digest_createSHA1.
    1428             :  */
    1429           4 : rtlDigest SAL_CALL rtl_digest_createSHA1() SAL_THROW_EXTERN_C()
    1430             : {
    1431           4 :     DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL;
    1432           4 :     pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
    1433           4 :     if (pImpl)
    1434             :     {
    1435           4 :         pImpl->m_digest = __rtl_digest_SHA_1;
    1436           4 :         __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
    1437             :     }
    1438           4 :     return ((rtlDigest)pImpl);
    1439             : }
    1440             : 
    1441             : /*
    1442             :  * rtl_digest_updateSHA1.
    1443             :  */
    1444      196696 : rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
    1445             :     rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
    1446             :     SAL_THROW_EXTERN_C()
    1447             : {
    1448      196696 :     DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
    1449      196696 :     const sal_uInt8  *d     = (const sal_uInt8 *)pData;
    1450             : 
    1451             :     DigestContextSHA *ctx;
    1452             :     sal_uInt32        len;
    1453             : 
    1454      196696 :     if ((pImpl == NULL) || (pData == NULL))
    1455           0 :         return rtl_Digest_E_Argument;
    1456             : 
    1457      196696 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
    1458           0 :         return rtl_Digest_E_Algorithm;
    1459             : 
    1460      196696 :     if (nDatLen == 0)
    1461           0 :         return rtl_Digest_E_None;
    1462             : 
    1463      196696 :     ctx = &(pImpl->m_context);
    1464             : 
    1465      196696 :     len = ctx->m_nL + (nDatLen << 3);
    1466      196696 :     if (len < ctx->m_nL) ctx->m_nH += 1;
    1467      196696 :     ctx->m_nH += (nDatLen >> 29);
    1468      196696 :     ctx->m_nL  = len;
    1469             : 
    1470      196696 :     if (ctx->m_nDatLen)
    1471             :     {
    1472          48 :         sal_uInt8  *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen;
    1473          48 :         sal_uInt32  n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
    1474             : 
    1475          48 :         if (nDatLen < n)
    1476             :         {
    1477          48 :             memcpy (p, d, nDatLen);
    1478          48 :             ctx->m_nDatLen += nDatLen;
    1479             : 
    1480          48 :             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      491677 :     while (nDatLen >= DIGEST_CBLOCK_SHA)
    1496             :     {
    1497       98381 :         memcpy (ctx->m_pData, d, DIGEST_CBLOCK_SHA);
    1498       98381 :         d       += DIGEST_CBLOCK_SHA;
    1499       98381 :         nDatLen -= DIGEST_CBLOCK_SHA;
    1500             : 
    1501             : #ifndef OSL_BIGENDIAN
    1502       98381 :         __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA);
    1503             : #endif /* OSL_BIGENDIAN */
    1504             : 
    1505       98381 :         __rtl_digest_updateSHA (ctx);
    1506             :     }
    1507             : 
    1508      196648 :     memcpy (ctx->m_pData, d, nDatLen);
    1509      196648 :     ctx->m_nDatLen = nDatLen;
    1510             : 
    1511      196648 :     return rtl_Digest_E_None;
    1512             : }
    1513             : 
    1514             : /*
    1515             :  * rtl_digest_getSHA1.
    1516             :  */
    1517       98316 : rtlDigestError SAL_CALL rtl_digest_getSHA1 (
    1518             :     rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
    1519             :     SAL_THROW_EXTERN_C()
    1520             : {
    1521       98316 :     DigestSHA_Impl   *pImpl = (DigestSHA_Impl *)Digest;
    1522       98316 :     sal_uInt8        *p     = pBuffer;
    1523             : 
    1524             :     DigestContextSHA *ctx;
    1525             : 
    1526       98316 :     if ((pImpl == NULL) || (pBuffer == NULL))
    1527           0 :         return rtl_Digest_E_Argument;
    1528             : 
    1529       98316 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1))
    1530           0 :         return rtl_Digest_E_Algorithm;
    1531             : 
    1532       98316 :     if (!(pImpl->m_digest.m_length <= nBufLen))
    1533           0 :         return rtl_Digest_E_BufferSize;
    1534             : 
    1535       98316 :     ctx = &(pImpl->m_context);
    1536             : 
    1537       98316 :     __rtl_digest_endSHA (ctx);
    1538       98316 :     RTL_DIGEST_HTONL (ctx->m_nA, p);
    1539       98316 :     RTL_DIGEST_HTONL (ctx->m_nB, p);
    1540       98316 :     RTL_DIGEST_HTONL (ctx->m_nC, p);
    1541       98316 :     RTL_DIGEST_HTONL (ctx->m_nD, p);
    1542       98316 :     RTL_DIGEST_HTONL (ctx->m_nE, p);
    1543       98316 :     __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1);
    1544             : 
    1545       98316 :     return rtl_Digest_E_None;
    1546             : }
    1547             : 
    1548             : /*
    1549             :  * rtl_digest_destroySHA1.
    1550             :  */
    1551           4 : void SAL_CALL rtl_digest_destroySHA1 (rtlDigest Digest) SAL_THROW_EXTERN_C()
    1552             : {
    1553           4 :     DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest;
    1554           4 :     if (pImpl)
    1555             :     {
    1556           4 :         if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)
    1557           4 :             rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl));
    1558             :         else
    1559           0 :             rtl_freeMemory (pImpl);
    1560             :     }
    1561           4 : }
    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          28 : static void __rtl_digest_initHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
    1836             : {
    1837          28 :     DigestSHA_Impl *pImpl = &(ctx->m_hash);
    1838             : 
    1839          28 :     pImpl->m_digest = __rtl_digest_SHA_1;
    1840          28 :     __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1);
    1841             : 
    1842          28 :     memset (ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_SHA1);
    1843          28 : }
    1844             : 
    1845             : /*
    1846             :  * __rtl_digest_ipadHMAC_SHA1.
    1847             :  */
    1848       49180 : static void __rtl_digest_ipadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
    1849             : {
    1850             :     sal_uInt32 i;
    1851             : 
    1852     3196700 :     for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
    1853     3147520 :         ctx->m_opad[i] ^= 0x36;
    1854             :     rtl_digest_updateSHA1 (
    1855       49180 :         &(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_SHA1);
    1856     3196700 :     for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
    1857     3147520 :         ctx->m_opad[i] ^= 0x36;
    1858       49180 : }
    1859             : 
    1860             : /*
    1861             :  * __rtl_digest_opadHMAC_SHA1.
    1862             :  */
    1863       98332 : static void __rtl_digest_opadHMAC_SHA1 (ContextHMAC_SHA1 * ctx)
    1864             : {
    1865             :     sal_uInt32 i;
    1866             : 
    1867     6391580 :     for (i = 0; i < DIGEST_CBLOCK_HMAC_SHA1; i++)
    1868     6293248 :         ctx->m_opad[i] ^= 0x5c;
    1869       98332 : }
    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          28 : rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
    1920             :     rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen)
    1921             :     SAL_THROW_EXTERN_C()
    1922             : {
    1923          28 :     DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
    1924             :     ContextHMAC_SHA1     *ctx;
    1925             : 
    1926          28 :     if ((pImpl == NULL) || (pKeyData == NULL))
    1927           0 :         return rtl_Digest_E_Argument;
    1928             : 
    1929          28 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
    1930           0 :         return rtl_Digest_E_Algorithm;
    1931             : 
    1932          28 :     ctx = &(pImpl->m_context);
    1933          28 :     __rtl_digest_initHMAC_SHA1 (ctx);
    1934             : 
    1935          28 :     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          28 :         memcpy (ctx->m_opad, pKeyData, nKeyLen);
    1947             :     }
    1948             : 
    1949          28 :     __rtl_digest_ipadHMAC_SHA1 (ctx);
    1950          28 :     __rtl_digest_opadHMAC_SHA1 (ctx);
    1951             : 
    1952          28 :     return rtl_Digest_E_None;
    1953             : }
    1954             : 
    1955             : /*
    1956             :  * rtl_digest_updateHMAC_SHA1.
    1957             :  */
    1958       49200 : rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
    1959             :     rtlDigest Digest, const void *pData, sal_uInt32 nDatLen)
    1960             :     SAL_THROW_EXTERN_C()
    1961             : {
    1962       49200 :     DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
    1963             :     ContextHMAC_SHA1     *ctx;
    1964             : 
    1965       49200 :     if ((pImpl == NULL) || (pData == NULL))
    1966           0 :         return rtl_Digest_E_Argument;
    1967             : 
    1968       49200 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
    1969           0 :         return rtl_Digest_E_Algorithm;
    1970             : 
    1971       49200 :     ctx = &(pImpl->m_context);
    1972       49200 :     rtl_digest_updateSHA1 (&(ctx->m_hash), pData, nDatLen);
    1973             : 
    1974       49200 :     return rtl_Digest_E_None;
    1975             : }
    1976             : 
    1977             : /*
    1978             :  * rtl_digest_getHMAC_SHA1.
    1979             :  */
    1980       49152 : rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
    1981             :     rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen)
    1982             :     SAL_THROW_EXTERN_C()
    1983             : {
    1984       49152 :     DigestHMAC_SHA1_Impl *pImpl = (DigestHMAC_SHA1_Impl*)Digest;
    1985             :     ContextHMAC_SHA1     *ctx;
    1986             : 
    1987       49152 :     if ((pImpl == NULL) || (pBuffer == NULL))
    1988           0 :         return rtl_Digest_E_Argument;
    1989             : 
    1990       49152 :     if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_SHA1))
    1991           0 :         return rtl_Digest_E_Algorithm;
    1992             : 
    1993       49152 :     if (!(pImpl->m_digest.m_length <= nBufLen))
    1994           0 :         return rtl_Digest_E_BufferSize;
    1995             : 
    1996       49152 :     nBufLen = pImpl->m_digest.m_length;
    1997             : 
    1998       49152 :     ctx = &(pImpl->m_context);
    1999       49152 :     rtl_digest_getSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
    2000             : 
    2001       49152 :     rtl_digest_updateSHA1 (&(ctx->m_hash), ctx->m_opad, sizeof(ctx->m_opad));
    2002       49152 :     rtl_digest_updateSHA1 (&(ctx->m_hash), pBuffer, nBufLen);
    2003       49152 :     rtl_digest_getSHA1    (&(ctx->m_hash), pBuffer, nBufLen);
    2004             : 
    2005       49152 :     __rtl_digest_opadHMAC_SHA1 (ctx);
    2006       49152 :     __rtl_digest_ipadHMAC_SHA1 (ctx);
    2007       49152 :     __rtl_digest_opadHMAC_SHA1 (ctx);
    2008             : 
    2009       49152 :     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          48 : 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          48 :     rtl_digest_updateHMAC_SHA1 (hDigest, pSaltData, nSaltLen);
    2050          48 :     rtl_digest_updateHMAC_SHA1 (hDigest, &nIndex, sizeof(nIndex));
    2051          48 :     rtl_digest_getHMAC_SHA1    (hDigest, U, DIGEST_CBLOCK_PBKDF2);
    2052             : 
    2053             :     /* T = U_(1) */
    2054          48 :     for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] = U[k];
    2055             : 
    2056             :     /* T ^= U_(2) ^ ... ^ U_(c) */
    2057       49152 :     for (i = 1; i < nCount; i++)
    2058             :     {
    2059             :         /* U_(i) = PRF (P, U_(i-1)) */
    2060       49104 :         rtl_digest_updateHMAC_SHA1 (hDigest, U, DIGEST_CBLOCK_PBKDF2);
    2061       49104 :         rtl_digest_getHMAC_SHA1    (hDigest, U, DIGEST_CBLOCK_PBKDF2);
    2062             : 
    2063             :         /* T ^= U_(i) */
    2064       49104 :         for (k = 0; k < DIGEST_CBLOCK_PBKDF2; k++) T[k] ^= U[k];
    2065             :     }
    2066             : 
    2067          48 :     memset (U, 0, DIGEST_CBLOCK_PBKDF2);
    2068          48 : }
    2069             : 
    2070             : /*========================================================================
    2071             :  *
    2072             :  * rtl_digest_PBKDF2 implementation.
    2073             :  *
    2074             :  *======================================================================*/
    2075             : /*
    2076             :  * rtl_digest_PBKDF2.
    2077             :  */
    2078          28 : 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          28 :     sal_uInt32           i = 1;
    2086             : 
    2087          28 :     if ((pKeyData == NULL) || (pPassData == NULL) || (pSaltData == NULL))
    2088           0 :         return rtl_Digest_E_Argument;
    2089             : 
    2090          28 :     digest.m_digest = __rtl_digest_HMAC_SHA1;
    2091          28 :     rtl_digest_initHMAC_SHA1 (&digest, pPassData, nPassLen);
    2092             : 
    2093             :     /* DK = T_(1) || T_(2) || ... || T_(l) */
    2094          76 :     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          20 :             nCount, OSL_NETDWORD(i));
    2101             : 
    2102             :         /* Next 'KeyData' block */
    2103          20 :         pKeyData += DIGEST_CBLOCK_PBKDF2;
    2104          20 :         nKeyLen  -= DIGEST_CBLOCK_PBKDF2;
    2105          20 :         i += 1;
    2106             :     }
    2107          28 :     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          28 :             nCount, OSL_NETDWORD(i));
    2117             : 
    2118             :         /* DK ||= T_(i) */
    2119          28 :         memcpy (pKeyData, T, nKeyLen);
    2120          28 :         memset (T, 0, DIGEST_CBLOCK_PBKDF2);
    2121             :     }
    2122             : 
    2123          28 :     memset (&digest, 0, sizeof (digest));
    2124          28 :     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