Revert "sal: remove MD2, SHA, HMAC_MD5 digests"
it breaks the published API
This reverts commit e4892750c3.
Change-Id: Id072882efc432cdbc3c20a6bcece1369f9a78bf4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209385
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
@@ -43,9 +43,12 @@ typedef void* rtlDigest;
|
||||
*/
|
||||
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,
|
||||
@@ -156,6 +159,62 @@ SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_get (
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
#define RTL_DIGEST_LENGTH_MD2 16
|
||||
|
||||
/** Create a MD2 digest handle.
|
||||
|
||||
The MD2 digest algorithm is specified in
|
||||
RFC 1319 (Informational)
|
||||
The MD2 Message-Digest Algorithm
|
||||
|
||||
@see rtl_digest_create()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createMD2 (void) SAL_THROW_EXTERN_C();
|
||||
|
||||
|
||||
/** Destroy a MD2 digest handle.
|
||||
@see rtl_digest_destroy()
|
||||
*/
|
||||
SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyMD2 (
|
||||
rtlDigest Digest
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Update a MD2 digest with given data.
|
||||
@see rtl_digest_update()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateMD2 (
|
||||
rtlDigest Digest,
|
||||
const void *pData, sal_uInt32 nDatLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Finalize a MD2 digest and retrieve the digest value.
|
||||
@see rtl_digest_get()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getMD2 (
|
||||
rtlDigest Digest,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Evaluate a MD2 digest value from given data.
|
||||
|
||||
This function performs an optimized call sequence on a
|
||||
single data buffer, avoiding digest creation and destruction.
|
||||
|
||||
@see rtl_digest_updateMD2()
|
||||
@see rtl_digest_getMD2()
|
||||
|
||||
@param[in] pData data buffer.
|
||||
@param[in] nDatLen data length.
|
||||
@param[in] pBuffer digest value buffer.
|
||||
@param[in] nBufLen digest value length.
|
||||
|
||||
@retval rtl_Digest_E_None upon success.
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_MD2 (
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
#define RTL_DIGEST_LENGTH_MD5 16
|
||||
|
||||
/** Create a MD5 digest handle.
|
||||
@@ -224,6 +283,80 @@ SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_MD5 (
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
#define RTL_DIGEST_LENGTH_SHA 20
|
||||
|
||||
/** Create a SHA digest handle.
|
||||
|
||||
The SHA digest algorithm is specified in
|
||||
FIPS PUB 180 (Superseded by FIPS PUB 180-1)
|
||||
Secure Hash Standard
|
||||
|
||||
@deprecated The implementation is buggy and generates incorrect results
|
||||
for 52 <= (len % 64) <= 55; use only for bug-compatibility.
|
||||
|
||||
@see rtl_digest_create()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createSHA (void) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Destroy a SHA digest handle.
|
||||
|
||||
@deprecated The implementation is buggy and generates incorrect results
|
||||
for 52 <= (len % 64) <= 55; use only for bug-compatibility.
|
||||
|
||||
@see rtl_digest_destroy()
|
||||
*/
|
||||
SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroySHA (
|
||||
rtlDigest Digest
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
|
||||
/** Update a SHA digest with given data.
|
||||
|
||||
@deprecated The implementation is buggy and generates incorrect results
|
||||
for 52 <= (len % 64) <= 55; use only for bug-compatibility.
|
||||
|
||||
@see rtl_digest_update()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateSHA (
|
||||
rtlDigest Digest,
|
||||
const void *pData, sal_uInt32 nDatLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Finalize a SHA digest and retrieve the digest value.
|
||||
|
||||
@deprecated The implementation is buggy and generates incorrect results
|
||||
for 52 <= (len % 64) <= 55; use only for bug-compatibility.
|
||||
|
||||
@see rtl_digest_get()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getSHA (
|
||||
rtlDigest Digest,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Evaluate a SHA digest value from given data.
|
||||
|
||||
This function performs an optimized call sequence on a
|
||||
single data buffer, avoiding digest creation and destruction.
|
||||
|
||||
@deprecated The implementation is buggy and generates incorrect results
|
||||
for 52 <= (len % 64) <= 55; use only for bug-compatibility.
|
||||
|
||||
@see rtl_digest_updateSHA()
|
||||
@see rtl_digest_getSHA()
|
||||
|
||||
@param[in] pData data buffer.
|
||||
@param[in] nDatLen data length.
|
||||
@param[in] pBuffer digest value buffer.
|
||||
@param[in] nBufLen digest value length.
|
||||
|
||||
@retval rtl_Digest_E_None upon success.
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_SHA (
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/*========================================================================
|
||||
*
|
||||
* rtl_digest_SHA1 interface.
|
||||
@@ -302,6 +435,80 @@ SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_SHA1 (
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
#define RTL_DIGEST_LENGTH_HMAC_MD5 RTL_DIGEST_LENGTH_MD5
|
||||
|
||||
/** Create a HMAC_MD5 digest handle.
|
||||
|
||||
The HMAC_MD5 digest algorithm is specified in
|
||||
|
||||
RFC 2104 (Informational)
|
||||
HMAC: Keyed-Hashing for Message Authentication
|
||||
|
||||
@see rtl_digest_create()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createHMAC_MD5 (void) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Destroy a HMAC_MD5 digest handle.
|
||||
@see rtl_digest_destroy()
|
||||
*/
|
||||
SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyHMAC_MD5 (
|
||||
rtlDigest Digest
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Initialize a HMAC_MD5 digest.
|
||||
@see rtl_digest_init()
|
||||
|
||||
@param[in] Digest digest handle.
|
||||
@param[in] pKeyData key material buffer.
|
||||
@param[in] nKeyLen key material length.
|
||||
|
||||
@retval rtl_Digest_E_None upon success.
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
|
||||
rtlDigest Digest,
|
||||
const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Update a HMAC_MD5 digest with given data.
|
||||
@see rtl_digest_update()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
|
||||
rtlDigest Digest,
|
||||
const void *pData, sal_uInt32 nDatLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Finalize a HMAC_MD5 digest and retrieve the digest value.
|
||||
@see rtl_digest_get()
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
|
||||
rtlDigest Digest,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
/** Evaluate a HMAC_MD5 digest value from given data.
|
||||
|
||||
This function performs an optimized call sequence on a
|
||||
single data buffer, avoiding digest creation and destruction.
|
||||
|
||||
@see rtl_digest_initHMAC_MD5()
|
||||
@see rtl_digest_updateHMAC_MD5()
|
||||
@see rtl_digest_getHMAC_MD5()
|
||||
|
||||
@param[in] pKeyData key material buffer.
|
||||
@param[in] nKeyLen key material length.
|
||||
@param[in] pData data buffer.
|
||||
@param[in] nDatLen data length.
|
||||
@param[in] pBuffer digest value buffer.
|
||||
@param[in] nBufLen digest value length.
|
||||
|
||||
@retval rtl_Digest_E_None upon success.
|
||||
*/
|
||||
SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
|
||||
const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen
|
||||
) SAL_THROW_EXTERN_C();
|
||||
|
||||
#define RTL_DIGEST_LENGTH_HMAC_SHA1 RTL_DIGEST_LENGTH_SHA1
|
||||
|
||||
/** Create a HMAC_SHA1 digest handle.
|
||||
|
||||
@@ -41,22 +41,31 @@ constexpr OStringLiteral sSampleString_only_one_diff ("This is a sample sentence
|
||||
|
||||
const rtlDigestAlgorithm constDigestAlgorithms[] =
|
||||
{
|
||||
rtl_Digest_AlgorithmMD2,
|
||||
rtl_Digest_AlgorithmMD5,
|
||||
rtl_Digest_AlgorithmSHA,
|
||||
rtl_Digest_AlgorithmSHA1,
|
||||
rtl_Digest_AlgorithmHMAC_MD5,
|
||||
rtl_Digest_AlgorithmHMAC_SHA1,
|
||||
};
|
||||
|
||||
const sal_uInt32 constDigestAlgorithmLengths[] =
|
||||
{
|
||||
RTL_DIGEST_LENGTH_MD2,
|
||||
RTL_DIGEST_LENGTH_MD5,
|
||||
RTL_DIGEST_LENGTH_SHA,
|
||||
RTL_DIGEST_LENGTH_SHA1,
|
||||
RTL_DIGEST_LENGTH_HMAC_MD5,
|
||||
RTL_DIGEST_LENGTH_HMAC_SHA1,
|
||||
};
|
||||
|
||||
const std::string_view constSampleStringSums[] =
|
||||
{
|
||||
std::string_view("647ee6c9d4aa5fdd374ed9d7a156acbf"),
|
||||
std::string_view("b16b903e6fc0b62ae389013ed93fe531"),
|
||||
std::string_view("eab2814429b2613301c8a077b806af3680548914"),
|
||||
std::string_view("2bc5bdb7506a2cdc2fd27fc8b9889343012d5008"),
|
||||
std::string_view("0b1b0e1a6f2e4420326354b031063605"),
|
||||
std::string_view("1998c6a556915be76451bfb587fa7c34d849936e")
|
||||
};
|
||||
|
||||
@@ -271,42 +280,45 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aHandle = nullptr;
|
||||
aError = rtl_digest_updateSHA1(aHandle, nullptr, 0);
|
||||
aError = rtl_digest_updateMD2(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aHandle = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
|
||||
CPPUNIT_ASSERT(aHandle != nullptr);
|
||||
aError = rtl_digest_updateMD5(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aHandle = rtl_digest_create( rtl_Digest_AlgorithmMD2 );
|
||||
CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
|
||||
|
||||
const sal_uInt8* pData = reinterpret_cast<const sal_uInt8*>(sSampleString.getStr());
|
||||
sal_uInt32 nSize = sSampleString.getLength();
|
||||
|
||||
aError = rtl_digest_updateSHA1(aHandle, nullptr, 0);
|
||||
aError = rtl_digest_updateMD2(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aError = rtl_digest_updateSHA1(aHandle, pData, 0);
|
||||
aError = rtl_digest_updateMD2(aHandle, pData, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_None, aError);
|
||||
|
||||
rtl_digest_destroySHA1(aHandle);
|
||||
rtl_digest_destroyMD2(aHandle);
|
||||
|
||||
// use wrong Algorithm!!! This is volitional!
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmHMAC_SHA1);
|
||||
CPPUNIT_ASSERT(aHandle != nullptr);
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD2);
|
||||
CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
|
||||
|
||||
aError = rtl_digest_updateSHA1(aHandle, pData, nSize);
|
||||
aError = rtl_digest_updateMD5(aHandle, pData, nSize);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'handle' wrong", rtl_Digest_E_Algorithm, aError);
|
||||
|
||||
rtl_digest_destroyHMAC_SHA1(aHandle);
|
||||
rtl_digest_destroyMD5(aHandle);
|
||||
|
||||
aHandle = rtl_digest_create( rtl_Digest_AlgorithmHMAC_SHA1 );
|
||||
CPPUNIT_ASSERT(aHandle != nullptr);
|
||||
aHandle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
|
||||
CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD5", aHandle != nullptr);
|
||||
|
||||
aError = rtl_digest_updateHMAC_SHA1(aHandle, nullptr, 0);
|
||||
aError = rtl_digest_updateMD5(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aError = rtl_digest_updateHMAC_SHA1(aHandle, pData, 0);
|
||||
aError = rtl_digest_updateMD5(aHandle, pData, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_None, aError);
|
||||
|
||||
rtl_digest_destroyHMAC_SHA1(aHandle);
|
||||
rtl_digest_destroyMD5(aHandle);
|
||||
}
|
||||
|
||||
void testGet()
|
||||
@@ -319,34 +331,34 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aHandle = nullptr;
|
||||
aError = rtl_digest_getSHA1(aHandle, nullptr, 0);
|
||||
aError = rtl_digest_getMD5(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
|
||||
|
||||
// test with wrong algorithm
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmHMAC_SHA1);
|
||||
CPPUNIT_ASSERT(aHandle != nullptr);
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD2);
|
||||
CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
|
||||
|
||||
sal_uInt32 nKeyLen = rtl_digest_queryLength(aHandle);
|
||||
std::unique_ptr<sal_uInt8[]> pKeyBuffer(new sal_uInt8[nKeyLen]);
|
||||
|
||||
aError = rtl_digest_getSHA1(aHandle, nullptr, 0);
|
||||
aError = rtl_digest_getMD5(aHandle, nullptr, 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle 2. parameter wrong", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aError = rtl_digest_getSHA1(aHandle, pKeyBuffer.get(), 0);
|
||||
aError = rtl_digest_getMD5(aHandle, pKeyBuffer.get(), 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'handle' wrong", rtl_Digest_E_Algorithm, aError);
|
||||
|
||||
rtl_digest_destroyHMAC_SHA1(aHandle);
|
||||
rtl_digest_destroyMD2(aHandle);
|
||||
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmSHA1);
|
||||
CPPUNIT_ASSERT(aHandle != nullptr);
|
||||
aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD5);
|
||||
CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD5", aHandle != nullptr);
|
||||
|
||||
aError = rtl_digest_getSHA1(aHandle, nullptr, nKeyLen);
|
||||
aError = rtl_digest_getMD5(aHandle, nullptr, nKeyLen);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
|
||||
|
||||
aError = rtl_digest_getSHA1(aHandle, pKeyBuffer.get(), 0);
|
||||
aError = rtl_digest_getMD5(aHandle, pKeyBuffer.get(), 0);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_BufferSize, aError);
|
||||
|
||||
rtl_digest_destroySHA1(aHandle);
|
||||
rtl_digest_destroyMD5(aHandle);
|
||||
}
|
||||
|
||||
void testSHA1SumForBiggerInputData()
|
||||
|
||||
@@ -86,14 +86,26 @@ rtlDigest SAL_CALL rtl_digest_create(rtlDigestAlgorithm Algorithm) noexcept
|
||||
rtlDigest Digest = nullptr;
|
||||
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;
|
||||
@@ -158,6 +170,270 @@ void SAL_CALL rtl_digest_destroy(rtlDigest Digest) noexcept
|
||||
pImpl->m_delete(Digest);
|
||||
}
|
||||
|
||||
constexpr auto DIGEST_CBLOCK_MD2 = 16;
|
||||
constexpr auto DIGEST_LBLOCK_MD2 = 16;
|
||||
|
||||
namespace {
|
||||
|
||||
struct DigestContextMD2
|
||||
{
|
||||
sal_uInt32 m_nDatLen;
|
||||
sal_uInt8 m_pData[DIGEST_CBLOCK_MD2];
|
||||
sal_uInt32 m_state[DIGEST_LBLOCK_MD2];
|
||||
sal_uInt32 m_chksum[DIGEST_LBLOCK_MD2];
|
||||
};
|
||||
|
||||
struct DigestMD2_Impl
|
||||
{
|
||||
Digest_Impl m_digest;
|
||||
DigestContextMD2 m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static void initMD2 (DigestContextMD2 *ctx);
|
||||
static void updateMD2 (DigestContextMD2 *ctx);
|
||||
static void endMD2 (DigestContextMD2 *ctx);
|
||||
|
||||
const sal_uInt32 S[256] =
|
||||
{
|
||||
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
|
||||
0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
|
||||
0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
|
||||
0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
|
||||
0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
|
||||
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
|
||||
0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
|
||||
0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
|
||||
0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
|
||||
0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
|
||||
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
|
||||
0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
|
||||
0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
|
||||
0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
|
||||
0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
|
||||
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
|
||||
0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
|
||||
0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
|
||||
0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
|
||||
0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
|
||||
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
|
||||
0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
|
||||
0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
|
||||
0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
|
||||
0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
|
||||
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
|
||||
0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
|
||||
0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
|
||||
0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
|
||||
0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
|
||||
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
|
||||
0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
|
||||
};
|
||||
|
||||
const Digest_Impl MD2 =
|
||||
{
|
||||
rtl_Digest_AlgorithmMD2,
|
||||
RTL_DIGEST_LENGTH_MD2,
|
||||
nullptr,
|
||||
rtl_digest_destroyMD2,
|
||||
rtl_digest_updateMD2,
|
||||
rtl_digest_getMD2
|
||||
};
|
||||
|
||||
static void initMD2(DigestContextMD2 *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(DigestContextMD2));
|
||||
}
|
||||
|
||||
static void updateMD2(DigestContextMD2 *ctx)
|
||||
{
|
||||
sal_uInt8 *X;
|
||||
sal_uInt32 *sp1, *sp2;
|
||||
sal_uInt32 i, k, t;
|
||||
|
||||
sal_uInt32 state[48];
|
||||
|
||||
X = ctx->m_pData;
|
||||
sp1 = ctx->m_state;
|
||||
sp2 = ctx->m_chksum;
|
||||
|
||||
k = sp2[DIGEST_LBLOCK_MD2 - 1];
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
state[i + 0] = sp1[i];
|
||||
state[i + 16] = t = X[i];
|
||||
state[i + 32] = t ^ sp1[i];
|
||||
k = sp2[i] ^= S[t^k];
|
||||
}
|
||||
|
||||
t = 0;
|
||||
for (i = 0; i < 18; i++)
|
||||
{
|
||||
for (k = 0; k < 48; k += 8)
|
||||
{
|
||||
t = state[k + 0] ^= S[t];
|
||||
t = state[k + 1] ^= S[t];
|
||||
t = state[k + 2] ^= S[t];
|
||||
t = state[k + 3] ^= S[t];
|
||||
t = state[k + 4] ^= S[t];
|
||||
t = state[k + 5] ^= S[t];
|
||||
t = state[k + 6] ^= S[t];
|
||||
t = state[k + 7] ^= S[t];
|
||||
}
|
||||
t = ((t + i) & 0xff);
|
||||
}
|
||||
|
||||
memcpy(sp1, state, 16 * sizeof(sal_uInt32));
|
||||
rtl_secureZeroMemory(state, 48 * sizeof(sal_uInt32));
|
||||
}
|
||||
|
||||
static void endMD2(DigestContextMD2 *ctx)
|
||||
{
|
||||
sal_uInt8 *X;
|
||||
sal_uInt32 *C;
|
||||
sal_uInt32 i, n;
|
||||
|
||||
X = ctx->m_pData;
|
||||
C = ctx->m_chksum;
|
||||
n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
|
||||
|
||||
for (i = ctx->m_nDatLen; i < DIGEST_CBLOCK_MD2; i++)
|
||||
X[i] = static_cast<sal_uInt8>(n & 0xff);
|
||||
|
||||
updateMD2(ctx);
|
||||
|
||||
for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
|
||||
X[i] = static_cast<sal_uInt8>(C[i] & 0xff);
|
||||
updateMD2(ctx);
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_MD2(
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestMD2_Impl digest;
|
||||
rtlDigestError result;
|
||||
|
||||
digest.m_digest = MD2;
|
||||
initMD2(&(digest.m_context));
|
||||
|
||||
result = rtl_digest_updateMD2(&digest, pData, nDatLen);
|
||||
if (result == rtl_Digest_E_None)
|
||||
result = rtl_digest_getMD2(&digest, pBuffer, nBufLen);
|
||||
|
||||
rtl_secureZeroMemory(&digest, sizeof(digest));
|
||||
return result;
|
||||
}
|
||||
|
||||
rtlDigest SAL_CALL rtl_digest_createMD2() noexcept
|
||||
{
|
||||
DigestMD2_Impl *pImpl = RTL_DIGEST_CREATE(DigestMD2_Impl);
|
||||
if (pImpl)
|
||||
{
|
||||
pImpl->m_digest = MD2;
|
||||
initMD2(&(pImpl->m_context));
|
||||
}
|
||||
return static_cast<rtlDigest>(pImpl);
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_updateMD2(
|
||||
rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) noexcept
|
||||
{
|
||||
DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
|
||||
const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
|
||||
|
||||
DigestContextMD2 *ctx;
|
||||
|
||||
if (!pImpl || !pData)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmMD2)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
if (nDatLen == 0)
|
||||
return rtl_Digest_E_None;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
|
||||
if (ctx->m_nDatLen)
|
||||
{
|
||||
sal_uInt8 *p = ctx->m_pData + ctx->m_nDatLen;
|
||||
sal_uInt32 n = DIGEST_CBLOCK_MD2 - ctx->m_nDatLen;
|
||||
|
||||
if (nDatLen < n)
|
||||
{
|
||||
memcpy(p, d, nDatLen);
|
||||
ctx->m_nDatLen += nDatLen;
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
memcpy(p, d, n);
|
||||
d += n;
|
||||
nDatLen -= n;
|
||||
|
||||
updateMD2(ctx);
|
||||
ctx->m_nDatLen = 0;
|
||||
}
|
||||
|
||||
while (nDatLen >= DIGEST_CBLOCK_MD2)
|
||||
{
|
||||
memcpy(ctx->m_pData, d, DIGEST_CBLOCK_MD2);
|
||||
d += DIGEST_CBLOCK_MD2;
|
||||
nDatLen -= DIGEST_CBLOCK_MD2;
|
||||
|
||||
updateMD2(ctx);
|
||||
}
|
||||
|
||||
memcpy(ctx->m_pData, d, nDatLen);
|
||||
ctx->m_nDatLen = nDatLen;
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_getMD2(
|
||||
rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
|
||||
sal_uInt32 i;
|
||||
|
||||
DigestContextMD2 *ctx;
|
||||
|
||||
if (!pImpl || !pBuffer)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmMD2)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
if (pImpl->m_digest.m_length > nBufLen)
|
||||
return rtl_Digest_E_BufferSize;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
|
||||
endMD2(ctx);
|
||||
for (i = 0; i < DIGEST_CBLOCK_MD2; i++)
|
||||
{
|
||||
pBuffer[i] = static_cast<sal_uInt8>(ctx->m_state[i] & 0xff);
|
||||
}
|
||||
|
||||
initMD2(ctx);
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
void SAL_CALL rtl_digest_destroyMD2(rtlDigest Digest) noexcept
|
||||
{
|
||||
DigestMD2_Impl *pImpl = static_cast<DigestMD2_Impl *>(Digest);
|
||||
if (pImpl)
|
||||
{
|
||||
if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmMD2)
|
||||
rtl_freeZeroMemory(pImpl, sizeof(DigestMD2_Impl));
|
||||
else
|
||||
free(pImpl);
|
||||
}
|
||||
}
|
||||
|
||||
#define DIGEST_CBLOCK_MD5 64
|
||||
#define DIGEST_LBLOCK_MD5 16
|
||||
|
||||
@@ -546,6 +822,7 @@ void SAL_CALL rtl_digest_destroyMD5(rtlDigest Digest) noexcept
|
||||
|
||||
typedef sal_uInt32 DigestSHA_update_t(sal_uInt32 x);
|
||||
|
||||
static sal_uInt32 updateSHA_0(sal_uInt32 x);
|
||||
static sal_uInt32 updateSHA_1(sal_uInt32 x);
|
||||
|
||||
namespace {
|
||||
@@ -798,6 +1075,163 @@ static void endSHA(DigestContextSHA *ctx)
|
||||
updateSHA(ctx);
|
||||
}
|
||||
|
||||
const Digest_Impl SHA_0 =
|
||||
{
|
||||
rtl_Digest_AlgorithmSHA,
|
||||
RTL_DIGEST_LENGTH_SHA,
|
||||
nullptr,
|
||||
rtl_digest_destroySHA,
|
||||
rtl_digest_updateSHA,
|
||||
rtl_digest_getSHA
|
||||
};
|
||||
|
||||
static sal_uInt32 updateSHA_0(sal_uInt32 x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_SHA(
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestSHA_Impl digest;
|
||||
rtlDigestError result;
|
||||
|
||||
digest.m_digest = SHA_0;
|
||||
initSHA(&(digest.m_context), updateSHA_0);
|
||||
|
||||
result = rtl_digest_updateSHA(&digest, pData, nDatLen);
|
||||
if (result == rtl_Digest_E_None)
|
||||
result = rtl_digest_getSHA(&digest, pBuffer, nBufLen);
|
||||
|
||||
rtl_secureZeroMemory(&digest, sizeof(digest));
|
||||
return result;
|
||||
}
|
||||
|
||||
rtlDigest SAL_CALL rtl_digest_createSHA() noexcept
|
||||
{
|
||||
DigestSHA_Impl *pImpl = RTL_DIGEST_CREATE(DigestSHA_Impl);
|
||||
if (pImpl)
|
||||
{
|
||||
pImpl->m_digest = SHA_0;
|
||||
initSHA(&(pImpl->m_context), updateSHA_0);
|
||||
}
|
||||
return static_cast<rtlDigest>(pImpl);
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_updateSHA(
|
||||
rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) noexcept
|
||||
{
|
||||
DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
|
||||
const sal_uInt8 *d = static_cast<const sal_uInt8 *>(pData);
|
||||
|
||||
DigestContextSHA *ctx;
|
||||
sal_uInt32 len;
|
||||
|
||||
if (!pImpl || !pData)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmSHA)
|
||||
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 = reinterpret_cast<sal_uInt8 *>(ctx->m_pData) + ctx->m_nDatLen;
|
||||
sal_uInt32 n = DIGEST_CBLOCK_SHA - ctx->m_nDatLen;
|
||||
|
||||
if (nDatLen < n)
|
||||
{
|
||||
memcpy(p, d, nDatLen);
|
||||
ctx->m_nDatLen += nDatLen;
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
memcpy(p, d, n);
|
||||
d += n;
|
||||
nDatLen -= n;
|
||||
|
||||
#ifndef OSL_BIGENDIAN
|
||||
swapLong(ctx->m_pData, DIGEST_LBLOCK_SHA);
|
||||
#endif /* OSL_BIGENDIAN */
|
||||
|
||||
updateSHA(ctx);
|
||||
ctx->m_nDatLen = 0;
|
||||
}
|
||||
|
||||
while (nDatLen >= DIGEST_CBLOCK_SHA)
|
||||
{
|
||||
memcpy(ctx->m_pData, d, DIGEST_CBLOCK_SHA);
|
||||
d += DIGEST_CBLOCK_SHA;
|
||||
nDatLen -= DIGEST_CBLOCK_SHA;
|
||||
|
||||
#ifndef OSL_BIGENDIAN
|
||||
swapLong(ctx->m_pData, DIGEST_LBLOCK_SHA);
|
||||
#endif /* OSL_BIGENDIAN */
|
||||
|
||||
updateSHA(ctx);
|
||||
}
|
||||
|
||||
memcpy(ctx->m_pData, d, nDatLen);
|
||||
ctx->m_nDatLen = nDatLen;
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_getSHA(
|
||||
rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestSHA_Impl *pImpl = static_cast<DigestSHA_Impl *>(Digest);
|
||||
sal_uInt8 *p = pBuffer;
|
||||
|
||||
DigestContextSHA *ctx;
|
||||
|
||||
if (!pImpl || !pBuffer)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmSHA)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
if (pImpl->m_digest.m_length > nBufLen)
|
||||
return rtl_Digest_E_BufferSize;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
|
||||
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);
|
||||
initSHA(ctx, updateSHA_0);
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
void SAL_CALL rtl_digest_destroySHA(rtlDigest Digest) noexcept
|
||||
{
|
||||
DigestSHA_Impl *pImpl = static_cast< DigestSHA_Impl * >(Digest);
|
||||
if (pImpl)
|
||||
{
|
||||
if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmSHA)
|
||||
rtl_freeZeroMemory(pImpl, sizeof(DigestSHA_Impl));
|
||||
else
|
||||
free(pImpl);
|
||||
}
|
||||
}
|
||||
|
||||
const Digest_Impl SHA_1 =
|
||||
{
|
||||
rtl_Digest_AlgorithmSHA1,
|
||||
@@ -955,6 +1389,203 @@ void SAL_CALL rtl_digest_destroySHA1(rtlDigest Digest) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
#define DIGEST_CBLOCK_HMAC_MD5 64
|
||||
|
||||
namespace {
|
||||
|
||||
struct ContextHMAC_MD5
|
||||
{
|
||||
DigestMD5_Impl m_hash;
|
||||
sal_uInt8 m_opad[DIGEST_CBLOCK_HMAC_MD5];
|
||||
};
|
||||
|
||||
struct DigestHMAC_MD5_Impl
|
||||
{
|
||||
Digest_Impl m_digest;
|
||||
ContextHMAC_MD5 m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static void initHMAC_MD5(ContextHMAC_MD5 * ctx);
|
||||
static void ipadHMAC_MD5(ContextHMAC_MD5 * ctx);
|
||||
static void opadHMAC_MD5(ContextHMAC_MD5 * ctx);
|
||||
|
||||
const Digest_Impl HMAC_MD5 =
|
||||
{
|
||||
rtl_Digest_AlgorithmHMAC_MD5,
|
||||
RTL_DIGEST_LENGTH_MD5,
|
||||
|
||||
rtl_digest_initHMAC_MD5,
|
||||
rtl_digest_destroyHMAC_MD5,
|
||||
rtl_digest_updateHMAC_MD5,
|
||||
rtl_digest_getHMAC_MD5
|
||||
};
|
||||
|
||||
static void initHMAC_MD5(ContextHMAC_MD5 * ctx)
|
||||
{
|
||||
DigestMD5_Impl *pImpl = &(ctx->m_hash);
|
||||
|
||||
pImpl->m_digest = MD5;
|
||||
initMD5(&(pImpl->m_context));
|
||||
|
||||
memset(ctx->m_opad, 0, DIGEST_CBLOCK_HMAC_MD5);
|
||||
}
|
||||
|
||||
static void ipadHMAC_MD5(ContextHMAC_MD5 * ctx)
|
||||
{
|
||||
sal_uInt32 i;
|
||||
|
||||
for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
|
||||
{
|
||||
ctx->m_opad[i] ^= 0x36;
|
||||
}
|
||||
|
||||
rtl_digest_updateMD5(&(ctx->m_hash), ctx->m_opad, DIGEST_CBLOCK_HMAC_MD5);
|
||||
|
||||
for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
|
||||
{
|
||||
ctx->m_opad[i] ^= 0x36;
|
||||
}
|
||||
}
|
||||
|
||||
static void opadHMAC_MD5(ContextHMAC_MD5 * ctx)
|
||||
{
|
||||
sal_uInt32 i;
|
||||
|
||||
for (i = 0; i < DIGEST_CBLOCK_HMAC_MD5; i++)
|
||||
{
|
||||
ctx->m_opad[i] ^= 0x5c;
|
||||
}
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_HMAC_MD5(
|
||||
const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
|
||||
const void *pData, sal_uInt32 nDatLen,
|
||||
sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl digest;
|
||||
rtlDigestError result;
|
||||
|
||||
digest.m_digest = HMAC_MD5;
|
||||
|
||||
result = rtl_digest_initHMAC_MD5(&digest, pKeyData, nKeyLen);
|
||||
if (result == rtl_Digest_E_None)
|
||||
{
|
||||
result = rtl_digest_updateHMAC_MD5(&digest, pData, nDatLen);
|
||||
if (result == rtl_Digest_E_None)
|
||||
result = rtl_digest_getHMAC_MD5(&digest, pBuffer, nBufLen);
|
||||
}
|
||||
|
||||
rtl_secureZeroMemory(&digest, sizeof(digest));
|
||||
return result;
|
||||
}
|
||||
|
||||
rtlDigest SAL_CALL rtl_digest_createHMAC_MD5() noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl *pImpl = RTL_DIGEST_CREATE(DigestHMAC_MD5_Impl);
|
||||
if (pImpl)
|
||||
{
|
||||
pImpl->m_digest = HMAC_MD5;
|
||||
initHMAC_MD5(&(pImpl->m_context));
|
||||
}
|
||||
return static_cast< rtlDigest >(pImpl);
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5(
|
||||
rtlDigest Digest, const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen) noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl *pImpl = static_cast< DigestHMAC_MD5_Impl* >(Digest);
|
||||
ContextHMAC_MD5 *ctx;
|
||||
|
||||
if (!pImpl || !pKeyData)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmHMAC_MD5)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
initHMAC_MD5(ctx);
|
||||
|
||||
if (nKeyLen > DIGEST_CBLOCK_HMAC_MD5)
|
||||
{
|
||||
/* Initialize 'opad' with hashed 'KeyData' */
|
||||
rtl_digest_updateMD5(&(ctx->m_hash), pKeyData, nKeyLen);
|
||||
rtl_digest_getMD5(&(ctx->m_hash), ctx->m_opad, RTL_DIGEST_LENGTH_MD5);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize 'opad' with plain 'KeyData' */
|
||||
memcpy(ctx->m_opad, pKeyData, nKeyLen);
|
||||
}
|
||||
|
||||
ipadHMAC_MD5(ctx);
|
||||
opadHMAC_MD5(ctx);
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5(
|
||||
rtlDigest Digest, const void *pData, sal_uInt32 nDatLen) noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl *pImpl = static_cast< DigestHMAC_MD5_Impl* >(Digest);
|
||||
ContextHMAC_MD5 *ctx;
|
||||
|
||||
if (!pImpl || !pData)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmHMAC_MD5)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
rtl_digest_updateMD5(&(ctx->m_hash), pData, nDatLen);
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5(
|
||||
rtlDigest Digest, sal_uInt8 *pBuffer, sal_uInt32 nBufLen) noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl *pImpl = static_cast<DigestHMAC_MD5_Impl*>(Digest);
|
||||
ContextHMAC_MD5 *ctx;
|
||||
|
||||
if (!pImpl || !pBuffer)
|
||||
return rtl_Digest_E_Argument;
|
||||
|
||||
if (pImpl->m_digest.m_algorithm != rtl_Digest_AlgorithmHMAC_MD5)
|
||||
return rtl_Digest_E_Algorithm;
|
||||
|
||||
if (pImpl->m_digest.m_length > nBufLen)
|
||||
return rtl_Digest_E_BufferSize;
|
||||
|
||||
nBufLen = pImpl->m_digest.m_length;
|
||||
|
||||
ctx = &(pImpl->m_context);
|
||||
rtl_digest_getMD5(&(ctx->m_hash), pBuffer, nBufLen);
|
||||
|
||||
rtl_digest_updateMD5(&(ctx->m_hash), ctx->m_opad, 64);
|
||||
rtl_digest_updateMD5(&(ctx->m_hash), pBuffer, nBufLen);
|
||||
rtl_digest_getMD5(&(ctx->m_hash), pBuffer, nBufLen);
|
||||
|
||||
opadHMAC_MD5(ctx);
|
||||
ipadHMAC_MD5(ctx);
|
||||
opadHMAC_MD5(ctx);
|
||||
|
||||
return rtl_Digest_E_None;
|
||||
}
|
||||
|
||||
void SAL_CALL rtl_digest_destroyHMAC_MD5(rtlDigest Digest) noexcept
|
||||
{
|
||||
DigestHMAC_MD5_Impl *pImpl = static_cast< DigestHMAC_MD5_Impl* >(Digest);
|
||||
if (pImpl)
|
||||
{
|
||||
if (pImpl->m_digest.m_algorithm == rtl_Digest_AlgorithmHMAC_MD5)
|
||||
rtl_freeZeroMemory(pImpl, sizeof(DigestHMAC_MD5_Impl));
|
||||
else
|
||||
free(pImpl);
|
||||
}
|
||||
}
|
||||
|
||||
#define DIGEST_CBLOCK_HMAC_SHA1 64
|
||||
|
||||
namespace {
|
||||
|
||||
Reference in New Issue
Block a user