/************************************************************************* * This implementation has been taken from the OpenOffice 1.0 and modified * to use KSpread data types. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Sun has made the contents of this file available subject to the * terms of GNU Lesser General Public License Version 2.1 as * specified in sal/rtl/source/digest.c in the OpenOffice package. * * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA * * All Rights Reserved. * * Contributor(s): Matthias Huetsch <matthias.huetsch@sun.com> * * ************************************************************************/ #include <stdlib.h> #include <string.h> #include "../config.h" #include "digest.h" #include <kdebug.h> #include <kmdcodec.h> typedef unsigned char sal_uInt8; typedef unsigned short sal_uInt16; #if SIZEOF_INT == 4 typedef unsigned int sal_uInt32; #else typedef unsigned long sal_uInt32; #endif void rtl_freeZeroMemory(void * p, sal_uInt32 n); void rtl_freeMemory(void * p); void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes); void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes); #ifndef OSL_LOBYTE # define OSL_LOBYTE(w) ((sal_uInt8)((sal_uInt16)(w) & 0xFF)) #endif #ifndef OSL_HIBYTE # define OSL_HIBYTE(w) ((sal_uInt8)(((sal_uInt16)(w) >> 8) & 0xFF)) #endif #ifndef OSL_MAKEWORD # define OSL_MAKEWORD(bl, bh) ((sal_uInt16)((bl) & 0xFF) | (((sal_uInt16)(bh) & 0xFF) << 8)) #endif #ifndef OSL_MAKEDWORD # define OSL_MAKEDWORD(wl, wh) ((sal_uInt32)((wl) & 0xFFFF) | (((sal_uInt32)(wh) & 0xFFFF) << 16)) #endif #ifndef OSL_LOWORD # define OSL_LOWORD(d) ((sal_uInt16)((sal_uInt32)(d) & 0xFFFF)) #endif #ifndef OSL_HIWORD # define OSL_HIWORD(d) ((sal_uInt16)(((sal_uInt32)(d) >> 16) & 0xFFFF)) #endif /** Define macros for swapping between byte orders. */ #ifndef OSL_SWAPWORD # define OSL_SWAPWORD(w) OSL_MAKEWORD(OSL_HIBYTE(w),OSL_LOBYTE(w)) #endif #ifndef OSL_SWAPDWORD # define OSL_SWAPDWORD(d) OSL_MAKEDWORD(OSL_SWAPWORD(OSL_HIWORD(d)),OSL_SWAPWORD(OSL_LOWORD(d))) #endif /*======================================================================== * * rtlDigest. * *======================================================================*/ /** Digest Handle opaque type. */ typedef void* rtlDigest; /** Digest Algorithm enumeration. @see rtl_digest_create() */ enum __rtl_DigestAlgorithm { rtl_Digest_AlgorithmMD2, rtl_Digest_AlgorithmMD5, rtl_Digest_AlgorithmSHA, rtl_Digest_AlgorithmSHA1, rtl_Digest_AlgorithmHMAC_MD5, rtl_Digest_AlgorithmHMAC_SHA1, rtl_Digest_AlgorithmInvalid, rtl_Digest_Algorithm_FORCE_EQUAL_SIZE }; /** Digest Algorithm type. */ typedef enum __rtl_DigestAlgorithm rtlDigestAlgorithm; /** Error Code enumeration. */ enum __rtl_DigestError { rtl_Digest_E_None, rtl_Digest_E_Argument, rtl_Digest_E_Algorithm, rtl_Digest_E_BufferSize, rtl_Digest_E_Memory, rtl_Digest_E_Unknown, rtl_Digest_E_FORCE_EQUAL_SIZE }; /** Error Code type. */ typedef enum __rtl_DigestError rtlDigestError; typedef rtlDigestError Digest_init_t( void * ctx, const sal_uInt8 * Data, sal_uInt32 DatLen ); typedef void Digest_delete_t( void *ctx ); typedef rtlDigestError Digest_update_t( void * ctx, const void * Data, sal_uInt32 DatLen ); typedef rtlDigestError Digest_get_t( void * ctx, sal_uInt8 * Buffer, sal_uInt32 BufLen ); /*======================================================================== * * rtl_digest_SHA1 interface. * *======================================================================*/ #define RTL_DIGEST_LENGTH_SHA1 20 /** Create a SHA1 digest handle. @descr The SHA1 digest algorithm is specified in FIPS PUB 180-1 (Supersedes FIPS PUB 180) Secure Hash Standard @see rtl_digest_create() */ rtlDigest rtl_digest_createSHA1 (void); /** Destroy a SHA1 digest handle. @see rtl_digest_destroy() */ void rtl_digest_destroySHA1( rtlDigest Digest ); /** Update a SHA1 digest with given data. @see rtl_digest_update() */ rtlDigestError rtl_digest_updateSHA1( rtlDigest Digest, const void * pData, uint nDatLen ); /** Finalize a SHA1 digest and retrieve the digest value. @see rtl_digest_get() */ rtlDigestError rtl_digest_getSHA1( rtlDigest Digest, sal_uInt8 * pBuffer, uint nBufLen ); /** Evaluate a SHA1 digest value from given data. @descr This function performs an optimized call sequence on a single data buffer, avoiding digest creation and destruction. @see rtl_digest_updateSHA1() @see rtl_digest_getSHA1() @param pData [in] data buffer. @param nDatLen [in] data length. @param pBuffer [in] digest value buffer. @param nBufLen [in] digest value length. @return rtl_Digest_E_None upon success. */ rtlDigestError rtl_digest_SHA1( const void * pData, uint nDatLen, unsigned char * pBuffer, uint nBufLen ); /*======================================================================== * * rtlDigest internals. * *======================================================================*/ void rtl_zeroMemory(void * Ptr, sal_uInt32 Bytes) { memset(Ptr, 0, Bytes); } void rtl_copyMemory(void *Dst, const void *Src, sal_uInt32 Bytes) { memcpy(Dst, Src, Bytes); } void rtl_freeMemory (void * p) { free(p); } void rtl_freeZeroMemory (void * p, sal_uInt32 n) { if (p) { memset(p, 0, n); free(p); } } #define RTL_DIGEST_CREATE(T) ((T*)(malloc(sizeof(T)))) #define RTL_DIGEST_ROTL(a,n) (((a) << (n)) | ((a) >> (32 - (n)))) #define RTL_DIGEST_HTONL(l,c) \ (*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \ *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \ *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \ *((c)++) = (sal_uInt8)(((l) ) & 0xff)) #define RTL_DIGEST_LTOC(l,c) \ (*((c)++) = (sal_uInt8)(((l) ) & 0xff), \ *((c)++) = (sal_uInt8)(((l) >> 8L) & 0xff), \ *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \ *((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff)) typedef struct digest_impl_st { rtlDigestAlgorithm m_algorithm; sal_uInt32 m_length; Digest_init_t *m_init; Digest_delete_t *m_delete; Digest_update_t *m_update; Digest_get_t *m_get; } Digest_Impl; /* * __rtl_digest_swapLong. */ static void __rtl_digest_swapLong (sal_uInt32 *pData, sal_uInt32 nDatLen) { sal_uInt32 *X; int i, n; X = pData; n = nDatLen; for (i = 0; i < n; i++) X[i] = OSL_SWAPDWORD(X[i]); } /*======================================================================== * * rtlDigest implementation. * *======================================================================*/ /* * rtl_digest_create. rtlDigest rtl_digest_create (rtlDigestAlgorithm Algorithm) { rtlDigest Digest = (rtlDigest)NULL; switch (Algorithm) { case rtl_Digest_AlgorithmMD2: Digest = rtl_digest_createMD2(); break; case rtl_Digest_AlgorithmMD5: Digest = rtl_digest_createMD5(); break; case rtl_Digest_AlgorithmSHA: Digest = rtl_digest_createSHA(); break; case rtl_Digest_AlgorithmSHA1: Digest = rtl_digest_createSHA1(); break; case rtl_Digest_AlgorithmHMAC_MD5: Digest = rtl_digest_createHMAC_MD5(); break; case rtl_Digest_AlgorithmHMAC_SHA1: Digest = rtl_digest_createHMAC_SHA1(); break; default: // rtl_Digest_AlgorithmInvalid break; } return Digest; } // rtl_digest_queryAlgorithm. rtlDigestAlgorithm rtl_digest_queryAlgorithm (rtlDigest Digest) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl) return pImpl->m_algorithm; else return rtl_Digest_AlgorithmInvalid; } // rtl_digest_queryLength. sal_uInt32 rtl_digest_queryLength (rtlDigest Digest) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl) return pImpl->m_length; else return 0; } // * rtl_digest_init. rtlDigestError rtl_digest_init ( rtlDigest Digest, const sal_uInt8 *pData, sal_uInt32 nDatLen) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl) { if (pImpl->m_init) return pImpl->m_init (Digest, pData, nDatLen); else return rtl_Digest_E_None; } return rtl_Digest_E_Argument; } // * rtl_digest_update. rtlDigestError rtl_digest_update ( rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl && pImpl->m_update) return pImpl->m_update (Digest, pData, nDatLen); else return rtl_Digest_E_Argument; } // * rtl_digest_get. rtlDigestError rtl_digest_get ( rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl && pImpl->m_get) return pImpl->m_get (Digest, pBuffer, nBufLen); else return rtl_Digest_E_Argument; } // * rtl_digest_destroy. void rtl_digest_destroy (rtlDigest Digest) { Digest_Impl *pImpl = (Digest_Impl *)Digest; if (pImpl && pImpl->m_delete) pImpl->m_delete (Digest); } */ /*======================================================================== * * rtl_digest_(SHA|SHA1) common internals. * *======================================================================*/ #define DIGEST_CBLOCK_SHA 64 #define DIGEST_LBLOCK_SHA 16 typedef sal_uInt32 DigestSHA_update_t (sal_uInt32 x); static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x); typedef struct digestSHA_context_st { DigestSHA_update_t *m_update; sal_uInt32 m_nDatLen; sal_uInt32 m_pData[DIGEST_LBLOCK_SHA]; sal_uInt32 m_nA, m_nB, m_nC, m_nD, m_nE; sal_uInt32 m_nL, m_nH; } DigestContextSHA; typedef struct digestSHA_impl_st { Digest_Impl m_digest; DigestContextSHA m_context; } DigestSHA_Impl; static void __rtl_digest_initSHA ( DigestContextSHA *ctx, DigestSHA_update_t *fct); static void __rtl_digest_updateSHA (DigestContextSHA *ctx); static void __rtl_digest_endSHA (DigestContextSHA *ctx); #define K_00_19 (sal_uInt32)0x5a827999L #define K_20_39 (sal_uInt32)0x6ed9eba1L #define K_40_59 (sal_uInt32)0x8f1bbcdcL #define K_60_79 (sal_uInt32)0xca62c1d6L #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) #define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) #define F_40_59(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) #define F_60_79(b,c,d) F_20_39(b,c,d) #define BODY_X(i) \ (X[(i)&0x0f] ^ X[((i)+2)&0x0f] ^ X[((i)+8)&0x0f] ^ X[((i)+13)&0x0f]) #define BODY_00_15(u,i,a,b,c,d,e,f) \ (f) = X[i]; \ (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \ (b) = RTL_DIGEST_ROTL((b), 30); #define BODY_16_19(u,i,a,b,c,d,e,f) \ (f) = BODY_X((i)); \ (f) = X[(i)&0x0f] = (u)((f)); \ (f) += (e) + K_00_19 + RTL_DIGEST_ROTL((a), 5) + F_00_19((b), (c), (d)); \ (b) = RTL_DIGEST_ROTL((b), 30); #define BODY_20_39(u,i,a,b,c,d,e,f) \ (f) = BODY_X((i)); \ (f) = X[(i)&0x0f] = (u)((f)); \ (f) += (e) + K_20_39 + RTL_DIGEST_ROTL((a), 5) + F_20_39((b), (c), (d)); \ (b) = RTL_DIGEST_ROTL((b), 30); #define BODY_40_59(u,i,a,b,c,d,e,f) \ (f) = BODY_X((i)); \ (f) = X[(i)&0x0f] = (u)((f)); \ (f) += (e) + K_40_59 + RTL_DIGEST_ROTL((a), 5) + F_40_59((b), (c), (d)); \ (b) = RTL_DIGEST_ROTL((b), 30); #define BODY_60_79(u,i,a,b,c,d,e,f) \ (f) = BODY_X((i)); \ (f) = X[(i)&0x0f] = (u)((f)); \ (f) += (e) + K_60_79 + RTL_DIGEST_ROTL((a), 5) + F_60_79((b), (c), (d)); \ (b) = RTL_DIGEST_ROTL((b), 30); /* * __rtl_digest_initSHA. */ static void __rtl_digest_initSHA ( DigestContextSHA *ctx, DigestSHA_update_t *fct) { rtl_zeroMemory (ctx, sizeof (DigestContextSHA)); ctx->m_update = fct; ctx->m_nA = (sal_uInt32)0x67452301L; ctx->m_nB = (sal_uInt32)0xefcdab89L; ctx->m_nC = (sal_uInt32)0x98badcfeL; ctx->m_nD = (sal_uInt32)0x10325476L; ctx->m_nE = (sal_uInt32)0xc3d2e1f0L; } /* * __rtl_digest_updateSHA. */ static void __rtl_digest_updateSHA (DigestContextSHA *ctx) { sal_uInt32 A, B, C, D, E, T; sal_uInt32 *X; DigestSHA_update_t *U; U = ctx->m_update; A = ctx->m_nA; B = ctx->m_nB; C = ctx->m_nC; D = ctx->m_nD; E = ctx->m_nE; X = ctx->m_pData; BODY_00_15 (U, 0, A, B, C, D, E, T); BODY_00_15 (U, 1, T, A, B, C, D, E); BODY_00_15 (U, 2, E, T, A, B, C, D); BODY_00_15 (U, 3, D, E, T, A, B, C); BODY_00_15 (U, 4, C, D, E, T, A, B); BODY_00_15 (U, 5, B, C, D, E, T, A); BODY_00_15 (U, 6, A, B, C, D, E, T); BODY_00_15 (U, 7, T, A, B, C, D, E); BODY_00_15 (U, 8, E, T, A, B, C, D); BODY_00_15 (U, 9, D, E, T, A, B, C); BODY_00_15 (U, 10, C, D, E, T, A, B); BODY_00_15 (U, 11, B, C, D, E, T, A); BODY_00_15 (U, 12, A, B, C, D, E, T); BODY_00_15 (U, 13, T, A, B, C, D, E); BODY_00_15 (U, 14, E, T, A, B, C, D); BODY_00_15 (U, 15, D, E, T, A, B, C); BODY_16_19 (U, 16, C, D, E, T, A, B); BODY_16_19 (U, 17, B, C, D, E, T, A); BODY_16_19 (U, 18, A, B, C, D, E, T); BODY_16_19 (U, 19, T, A, B, C, D, E); BODY_20_39 (U, 20, E, T, A, B, C, D); BODY_20_39 (U, 21, D, E, T, A, B, C); BODY_20_39 (U, 22, C, D, E, T, A, B); BODY_20_39 (U, 23, B, C, D, E, T, A); BODY_20_39 (U, 24, A, B, C, D, E, T); BODY_20_39 (U, 25, T, A, B, C, D, E); BODY_20_39 (U, 26, E, T, A, B, C, D); BODY_20_39 (U, 27, D, E, T, A, B, C); BODY_20_39 (U, 28, C, D, E, T, A, B); BODY_20_39 (U, 29, B, C, D, E, T, A); BODY_20_39 (U, 30, A, B, C, D, E, T); BODY_20_39 (U, 31, T, A, B, C, D, E); BODY_20_39 (U, 32, E, T, A, B, C, D); BODY_20_39 (U, 33, D, E, T, A, B, C); BODY_20_39 (U, 34, C, D, E, T, A, B); BODY_20_39 (U, 35, B, C, D, E, T, A); BODY_20_39 (U, 36, A, B, C, D, E, T); BODY_20_39 (U, 37, T, A, B, C, D, E); BODY_20_39 (U, 38, E, T, A, B, C, D); BODY_20_39 (U, 39, D, E, T, A, B, C); BODY_40_59 (U, 40, C, D, E, T, A, B); BODY_40_59 (U, 41, B, C, D, E, T, A); BODY_40_59 (U, 42, A, B, C, D, E, T); BODY_40_59 (U, 43, T, A, B, C, D, E); BODY_40_59 (U, 44, E, T, A, B, C, D); BODY_40_59 (U, 45, D, E, T, A, B, C); BODY_40_59 (U, 46, C, D, E, T, A, B); BODY_40_59 (U, 47, B, C, D, E, T, A); BODY_40_59 (U, 48, A, B, C, D, E, T); BODY_40_59 (U, 49, T, A, B, C, D, E); BODY_40_59 (U, 50, E, T, A, B, C, D); BODY_40_59 (U, 51, D, E, T, A, B, C); BODY_40_59 (U, 52, C, D, E, T, A, B); BODY_40_59 (U, 53, B, C, D, E, T, A); BODY_40_59 (U, 54, A, B, C, D, E, T); BODY_40_59 (U, 55, T, A, B, C, D, E); BODY_40_59 (U, 56, E, T, A, B, C, D); BODY_40_59 (U, 57, D, E, T, A, B, C); BODY_40_59 (U, 58, C, D, E, T, A, B); BODY_40_59 (U, 59, B, C, D, E, T, A); BODY_60_79 (U, 60, A, B, C, D, E, T); BODY_60_79 (U, 61, T, A, B, C, D, E); BODY_60_79 (U, 62, E, T, A, B, C, D); BODY_60_79 (U, 63, D, E, T, A, B, C); BODY_60_79 (U, 64, C, D, E, T, A, B); BODY_60_79 (U, 65, B, C, D, E, T, A); BODY_60_79 (U, 66, A, B, C, D, E, T); BODY_60_79 (U, 67, T, A, B, C, D, E); BODY_60_79 (U, 68, E, T, A, B, C, D); BODY_60_79 (U, 69, D, E, T, A, B, C); BODY_60_79 (U, 70, C, D, E, T, A, B); BODY_60_79 (U, 71, B, C, D, E, T, A); BODY_60_79 (U, 72, A, B, C, D, E, T); BODY_60_79 (U, 73, T, A, B, C, D, E); BODY_60_79 (U, 74, E, T, A, B, C, D); BODY_60_79 (U, 75, D, E, T, A, B, C); BODY_60_79 (U, 76, C, D, E, T, A, B); BODY_60_79 (U, 77, B, C, D, E, T, A); BODY_60_79 (U, 78, A, B, C, D, E, T); BODY_60_79 (U, 79, T, A, B, C, D, E); ctx->m_nA += E; ctx->m_nB += T; ctx->m_nC += A; ctx->m_nD += B; ctx->m_nE += C; } /* * __rtl_digest_endSHA. */ static void __rtl_digest_endSHA (DigestContextSHA *ctx) { static const sal_uInt8 end[4] = { 0x80, 0x00, 0x00, 0x00 }; const sal_uInt8 *p = end; sal_uInt32 *X; int i; X = ctx->m_pData; i = (ctx->m_nDatLen >> 2); #ifdef WORDS_BIGENDIAN __rtl_digest_swapLong (X, i + 1); #endif switch (ctx->m_nDatLen & 0x03) { case 1: X[i] &= 0x000000ff; break; case 2: X[i] &= 0x0000ffff; break; case 3: X[i] &= 0x00ffffff; break; } switch (ctx->m_nDatLen & 0x03) { case 0: X[i] = ((sal_uInt32)(*(p++))) << 0L; case 1: X[i] |= ((sal_uInt32)(*(p++))) << 8L; case 2: X[i] |= ((sal_uInt32)(*(p++))) << 16L; case 3: X[i] |= ((sal_uInt32)(*(p++))) << 24L; } __rtl_digest_swapLong (X, i + 1); i += 1; if (i >= (DIGEST_LBLOCK_SHA - 2)) { for (; i < DIGEST_LBLOCK_SHA; i++) X[i] = 0; __rtl_digest_updateSHA (ctx); i = 0; } for (; i < (DIGEST_LBLOCK_SHA - 2); i++) X[i] = 0; X[DIGEST_LBLOCK_SHA - 2] = ctx->m_nH; X[DIGEST_LBLOCK_SHA - 1] = ctx->m_nL; __rtl_digest_updateSHA (ctx); } /*======================================================================== * * rtl_digest_SHA1 internals. * *======================================================================*/ /* * __rtl_digest_SHA_1. */ static const Digest_Impl __rtl_digest_SHA_1 = { rtl_Digest_AlgorithmSHA1, RTL_DIGEST_LENGTH_SHA1, 0, rtl_digest_destroySHA1, rtl_digest_updateSHA1, rtl_digest_getSHA1 }; /* * __rtl_digest_updateSHA_1. */ static sal_uInt32 __rtl_digest_updateSHA_1 (sal_uInt32 x) { return RTL_DIGEST_ROTL (x, 1); } /*======================================================================== * * rtl_digest_SHA1 implementation. * *======================================================================*/ /* * rtl_digest_SHA1. */ rtlDigestError rtl_digest_SHA1 ( const void *pData, sal_uInt32 nDatLen, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) { DigestSHA_Impl digest; rtlDigestError result; digest.m_digest = __rtl_digest_SHA_1; __rtl_digest_initSHA (&(digest.m_context), __rtl_digest_updateSHA_1); result = rtl_digest_updateSHA1 (&digest, pData, nDatLen); if (result == rtl_Digest_E_None) result = rtl_digest_getSHA1 (&digest, pBuffer, nBufLen); rtl_zeroMemory (&digest, sizeof (digest)); return (result); } /* * rtl_digest_createSHA1. */ rtlDigest rtl_digest_createSHA1 (void) { DigestSHA_Impl *pImpl = (DigestSHA_Impl*)NULL; pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl); if (pImpl) { pImpl->m_digest = __rtl_digest_SHA_1; __rtl_digest_initSHA (&(pImpl->m_context), __rtl_digest_updateSHA_1); } return ((rtlDigest)pImpl); } /* * rtl_digest_updateSHA1. */ rtlDigestError rtl_digest_updateSHA1 ( rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) { DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; const sal_uInt8 *d = (const sal_uInt8 *)pData; DigestContextSHA *ctx; sal_uInt32 len; if ((pImpl == NULL) || (pData == NULL)) return rtl_Digest_E_Argument; if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)) return rtl_Digest_E_Algorithm; if (nDatLen == 0) return rtl_Digest_E_None; ctx = &(pImpl->m_context); len = ctx->m_nL + (nDatLen << 3); if (len < ctx->m_nL) ctx->m_nH += 1; ctx->m_nH += (nDatLen >> 29); ctx->m_nL = len; if (ctx->m_nDatLen) { sal_uInt8 *p = (sal_uInt8 *)(ctx->m_pData) + ctx->m_nDatLen; sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen; if (nDatLen < n) { rtl_copyMemory (p, d, nDatLen); ctx->m_nDatLen += nDatLen; return rtl_Digest_E_None; } rtl_copyMemory (p, d, n); d += n; nDatLen -= n; #ifndef WORDS_BIGENDIAN __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA); #endif __rtl_digest_updateSHA (ctx); ctx->m_nDatLen = 0; } while (nDatLen >= DIGEST_CBLOCK_SHA) { rtl_copyMemory (ctx->m_pData, d, DIGEST_CBLOCK_SHA); d += DIGEST_CBLOCK_SHA; nDatLen -= DIGEST_CBLOCK_SHA; #ifndef WORDS_BIGENDIAN __rtl_digest_swapLong (ctx->m_pData, DIGEST_LBLOCK_SHA); #endif __rtl_digest_updateSHA (ctx); } rtl_copyMemory (ctx->m_pData, d, nDatLen); ctx->m_nDatLen = nDatLen; return rtl_Digest_E_None; } /* * rtl_digest_getSHA1. */ rtlDigestError rtl_digest_getSHA1 ( rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) { DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; sal_uInt8 *p = pBuffer; DigestContextSHA *ctx; if ((pImpl == NULL) || (pBuffer == NULL)) return rtl_Digest_E_Argument; if (!(pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1)) return rtl_Digest_E_Algorithm; if (!(pImpl->m_digest.m_length <= nBufLen)) return rtl_Digest_E_BufferSize; ctx = &(pImpl->m_context); __rtl_digest_endSHA (ctx); RTL_DIGEST_HTONL (ctx->m_nA, p); RTL_DIGEST_HTONL (ctx->m_nB, p); RTL_DIGEST_HTONL (ctx->m_nC, p); RTL_DIGEST_HTONL (ctx->m_nD, p); RTL_DIGEST_HTONL (ctx->m_nE, p); __rtl_digest_initSHA (ctx, __rtl_digest_updateSHA_1); return rtl_Digest_E_None; } /* * rtl_digest_destroySHA1. */ void rtl_digest_destroySHA1 (rtlDigest Digest) { DigestSHA_Impl *pImpl = (DigestSHA_Impl *)Digest; if (pImpl) { if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA1) rtl_freeZeroMemory (pImpl, sizeof (DigestSHA_Impl)); else rtl_freeMemory (pImpl); } } /*======================================================================== * * The End. * *======================================================================*/ bool SHA1::getHash( TQString const & text, TQCString & hash ) { rtlDigest aDigest = rtl_digest_createSHA1(); rtlDigestError aError = rtl_digest_updateSHA1( aDigest, text.unicode(), text.length() * sizeof(TQChar) ); if ( aError == rtl_Digest_E_None ) { TQCString digest; digest.resize( RTL_DIGEST_LENGTH_SHA1 + 1 ); digest.fill( '\0', RTL_DIGEST_LENGTH_SHA1 ); aError = rtl_digest_getSHA1( aDigest, (unsigned char *) digest.data(), RTL_DIGEST_LENGTH_SHA1 ); if (aError != rtl_Digest_E_None) return false; hash = digest; return true; } return false; }