libwinpr-crypto: add basic hashing and HMAC support with OpenSSL/mbedTLS
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 8 Oct 2015 17:58:55 +0000 (13:58 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 8 Oct 2015 17:58:55 +0000 (13:58 -0400)
winpr/include/winpr/crypto.h
winpr/libwinpr/crypto/CMakeLists.txt
winpr/libwinpr/crypto/hash.c [new file with mode: 0644]
winpr/libwinpr/crypto/test/CMakeLists.txt
winpr/libwinpr/crypto/test/TestCryptoHash.c [new file with mode: 0644]
winpr/libwinpr/sspi/CMakeLists.txt

index ba48390..0d37bc5 100644 (file)
@@ -610,5 +610,197 @@ BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, L
 #define CALG_ECDSA                     (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
 #endif
 
+/**
+ * Custom Crypto API Abstraction Layer
+ */
+
+/**
+ * MD5 hashing
+ */
+
+struct _OPENSSL_MD5_CTX
+{
+       UINT32 A, B, C, D;
+       UINT32 Nl, Nh;
+       UINT32 data[16];
+       UINT32 num;
+};
+typedef struct _OPENSSL_MD5_CTX OPENSSL_MD5_CTX;
+
+struct _MBEDTLS_MD5_CTX
+{
+       UINT32 total[2];
+       UINT32 state[4];
+       BYTE buffer[64];
+};
+typedef struct _MBEDTLS_MD5_CTX MBEDTLS_MD5_CTX;
+
+union _WINPR_MD5_CTX
+{
+       OPENSSL_MD5_CTX openssl;
+       MBEDTLS_MD5_CTX mbedtls;
+};
+typedef union _WINPR_MD5_CTX WINPR_MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WINPR_API void winpr_MD5_Init(WINPR_MD5_CTX* ctx);
+WINPR_API void winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen);
+WINPR_API void winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output);
+WINPR_API void winpr_MD5(const BYTE* input, size_t ilen, BYTE* output);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * MD4 hashing
+ */
+
+struct _OPENSSL_MD4_CTX
+{
+       UINT32 A, B, C, D;
+       UINT32 Nl, Nh;
+       UINT32 data[16];
+       UINT32 num;
+};
+typedef struct _OPENSSL_MD4_CTX OPENSSL_MD4_CTX;
+
+struct _MBEDTLS_MD4_CTX
+{
+       UINT32 total[2];
+       UINT32 state[4];
+       BYTE buffer[64];
+};
+typedef struct _MBEDTLS_MD4_CTX MBEDTLS_MD4_CTX;
+
+union _WINPR_MD4_CTX
+{
+       OPENSSL_MD4_CTX openssl;
+       MBEDTLS_MD4_CTX mbedtls;
+};
+typedef union _WINPR_MD4_CTX WINPR_MD4_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WINPR_API void winpr_MD4_Init(WINPR_MD4_CTX* ctx);
+WINPR_API void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen);
+WINPR_API void winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output);
+WINPR_API void winpr_MD4(const BYTE* input, size_t ilen, BYTE* output);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * SHA1 Hashing
+ */
+
+struct _OPENSSL_SHA1_CTX
+{
+       UINT32 h0, h1, h2, h3, h4;
+       UINT32 Nl, Nh;
+       UINT32 data[16];
+       UINT32 num;
+};
+typedef struct _OPENSSL_SHA1_CTX OPENSSL_SHA1_CTX;
+
+struct _MBEDTLS_SHA1_CTX
+{
+       UINT32 total[2];
+       UINT32 state[5];
+       BYTE buffer[64];
+};
+typedef struct _MBEDTLS_SHA1_CTX MBEDTLS_SHA1_CTX;
+
+union _WINPR_SHA1_CTX
+{
+       OPENSSL_SHA1_CTX openssl;
+       MBEDTLS_SHA1_CTX mbedtls;
+};
+typedef union _WINPR_SHA1_CTX WINPR_SHA1_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WINPR_API void winpr_SHA1_Init(WINPR_SHA1_CTX* ctx);
+WINPR_API void winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen);
+WINPR_API void winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output);
+WINPR_API void winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * HMAC
+ */
+
+#define WINPR_MD_NONE          0
+#define WINPR_MD_MD2           1
+#define WINPR_MD_MD4           2
+#define WINPR_MD_MD5           3
+#define WINPR_MD_SHA1          4
+#define WINPR_MD_SHA224                5
+#define WINPR_MD_SHA256                6
+#define WINPR_MD_SHA384                7
+#define WINPR_MD_SHA512                8
+#define WINPR_MD_RIPEMD160     9
+
+struct _OPENSSL_EVP_MD_CTX
+{
+       const void* digest;
+       void* engine;
+       unsigned long flags;
+       void* md_data;
+       void* pctx;
+       void* update;
+};
+typedef struct _OPENSSL_EVP_MD_CTX OPENSSL_EVP_MD_CTX;
+
+struct _OPENSSL_HMAC_CTX
+{
+       const void* md;
+       OPENSSL_EVP_MD_CTX md_ctx;
+       OPENSSL_EVP_MD_CTX i_ctx;
+       OPENSSL_EVP_MD_CTX o_ctx;
+       unsigned int key_length;
+       unsigned char key[128];
+};
+typedef struct _OPENSSL_HMAC_CTX OPENSSL_HMAC_CTX;
+
+struct _MBEDTLS_HMAC_CTX
+{
+           const void* md_info;
+           void* md_ctx;
+           void* hmac_ctx;
+};
+typedef struct _MBEDTLS_HMAC_CTX MBEDTLS_HMAC_CTX;
+
+union _WINPR_HMAC_CTX
+{
+       OPENSSL_HMAC_CTX openssl;
+       MBEDTLS_HMAC_CTX mbedtls;
+};
+typedef union _WINPR_HMAC_CTX WINPR_HMAC_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WINPR_API int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen);
+WINPR_API int winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen);
+WINPR_API int winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output);
+WINPR_API int winpr_HMAC(int md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* WINPR_CRYPTO_H */
 
index c81b8f6..a14df8c 100644 (file)
 # limitations under the License.
 
 winpr_module_add(
+       hash.c
+       cert.c
        crypto.c
-       crypto.h
-       cert.c)
+       crypto.h)
 
 if(WIN32)
        winpr_library_add(crypt32)
diff --git a/winpr/libwinpr/crypto/hash.c b/winpr/libwinpr/crypto/hash.c
new file mode 100644 (file)
index 0000000..9a36897
--- /dev/null
@@ -0,0 +1,324 @@
+/**
+ * WinPR: Windows Portable Runtime
+ *
+ * Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <winpr/crt.h>
+
+#include <winpr/crypto.h>
+
+#ifdef WITH_OPENSSL
+#include <openssl/md4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#endif
+
+#ifdef WITH_MBEDTLS
+#include <mbedtls/md4.h>
+#include <mbedtls/md5.h>
+#include <mbedtls/sha1.h>
+#include <mbedtls/md.h>
+#endif
+
+/**
+ * MD5
+ */
+
+void winpr_MD5_Init(WINPR_MD5_CTX* ctx)
+{
+#if defined(WITH_OPENSSL)
+       MD5_Init((MD5_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
+       mbedtls_md5_init((mbedtls_md5_context*) ctx);
+       mbedtls_md5_starts((mbedtls_md5_context*) ctx);
+#endif
+}
+
+void winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen)
+{
+#if defined(WITH_OPENSSL)
+       MD5_Update((MD5_CTX*) ctx, input, ilen);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
+       mbedtls_md5_update((mbedtls_md5_context*) ctx, input, ilen);
+#endif
+}
+
+void winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output)
+{
+#if defined(WITH_OPENSSL)
+       MD5_Final(output, (MD5_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
+       mbedtls_md5_finish((mbedtls_md5_context*) ctx, output);
+       mbedtls_md5_free((mbedtls_md5_context*) ctx);
+#endif
+}
+
+void winpr_MD5(const BYTE* input, size_t ilen, BYTE* output)
+{
+       WINPR_MD5_CTX ctx;
+       winpr_MD5_Init(&ctx);
+       winpr_MD5_Update(&ctx, input, ilen);
+       winpr_MD5_Final(&ctx, output);
+}
+
+/**
+ * MD4
+ */
+
+void winpr_MD4_Init(WINPR_MD4_CTX* ctx)
+{
+#if defined(WITH_OPENSSL)
+       MD4_Init((MD4_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
+       mbedtls_md4_init((mbedtls_md4_context*) ctx);
+       mbedtls_md4_starts((mbedtls_md4_context*) ctx);
+#endif
+}
+
+void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen)
+{
+#if defined(WITH_OPENSSL)
+       MD4_Update((MD4_CTX*) ctx, input, ilen);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
+       mbedtls_md4_update((mbedtls_md4_context*) ctx, input, ilen);
+#endif
+}
+
+void winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output)
+{
+#if defined(WITH_OPENSSL)
+       MD4_Final(output, (MD4_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
+       mbedtls_md4_finish((mbedtls_md4_context*) ctx, output);
+       mbedtls_md4_free((mbedtls_md4_context*) ctx);
+#endif
+}
+
+void winpr_MD4(const BYTE* input, size_t ilen, BYTE* output)
+{
+       WINPR_MD4_CTX ctx;
+       winpr_MD4_Init(&ctx);
+       winpr_MD4_Update(&ctx, input, ilen);
+       winpr_MD4_Final(&ctx, output);
+}
+
+/**
+ * SHA1
+ */
+
+void winpr_SHA1_Init(WINPR_SHA1_CTX* ctx)
+{
+#if defined(WITH_OPENSSL)
+       SHA1_Init((SHA_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
+       mbedtls_sha1_init((mbedtls_sha1_context*) ctx);
+       mbedtls_sha1_starts((mbedtls_sha1_context*) ctx);
+#endif
+}
+
+void winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen)
+{
+#if defined(WITH_OPENSSL)
+       SHA1_Update((SHA_CTX*) ctx, input, ilen);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
+       mbedtls_sha1_update((mbedtls_sha1_context*) ctx, input, ilen);
+#endif
+}
+
+void winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output)
+{
+#if defined(WITH_OPENSSL)
+       SHA1_Final(output, (SHA_CTX*) ctx);
+#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
+       mbedtls_sha1_finish((mbedtls_sha1_context*) ctx, output);
+       mbedtls_sha1_free((mbedtls_sha1_context*) ctx);
+#endif
+}
+
+void winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output)
+{
+       WINPR_SHA1_CTX ctx;
+       winpr_SHA1_Init(&ctx);
+       winpr_SHA1_Update(&ctx, input, ilen);
+       winpr_SHA1_Final(&ctx, output);
+}
+
+/**
+ * HMAC
+ */
+
+#if defined(WITH_OPENSSL)
+const EVP_MD* winpr_openssl_get_evp_md(int md)
+{
+       const EVP_MD* evp = NULL;
+
+       switch (md)
+       {
+#ifndef OPENSSL_NO_MD2
+               case WINPR_MD_MD2:
+                       evp = EVP_md2();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_MD4
+               case WINPR_MD_MD4:
+                       evp = EVP_md4();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_MD5
+               case WINPR_MD_MD5:
+                       evp = EVP_md5();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_SHA
+               case WINPR_MD_SHA1:
+                       evp = EVP_sha1();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_SHA256
+               case WINPR_MD_SHA224:
+                       evp = EVP_sha224();
+                       break;
+
+               case WINPR_MD_SHA256:
+                       evp = EVP_sha256();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+               case WINPR_MD_SHA384:
+                       evp = EVP_sha384();
+                       break;
+
+               case WINPR_MD_SHA512:
+                       evp = EVP_sha512();
+                       break;
+#endif
+
+#ifndef OPENSSL_NO_RIPEMD
+               case WINPR_MD_RIPEMD160:
+                       evp = EVP_ripemd160();
+                       break;
+#endif
+       }
+
+       return evp;
+}
+#elif defined(WITH_MBEDTLS)
+mbedtls_md_type_t winpr_mbedtls_get_md_type(int md)
+{
+       mbedtls_md_type_t type = MBEDTLS_MD_NONE;
+
+       switch (md)
+       {
+               case WINPR_MD_MD2:
+                       type = MBEDTLS_MD_MD2;
+                       break;
+
+               case WINPR_MD_MD4:
+                       type = MBEDTLS_MD_MD4;
+                       break;
+
+               case WINPR_MD_MD5:
+                       type = MBEDTLS_MD_MD5;
+                       break;
+
+               case WINPR_MD_SHA1:
+                       type = MBEDTLS_MD_SHA1;
+                       break;
+
+               case WINPR_MD_SHA224:
+                       type = MBEDTLS_MD_SHA224;
+                       break;
+
+               case WINPR_MD_SHA256:
+                       type = MBEDTLS_MD_SHA256;
+                       break;
+
+               case WINPR_MD_SHA384:
+                       type = MBEDTLS_MD_SHA384;
+                       break;
+
+               case WINPR_MD_SHA512:
+                       type = MBEDTLS_MD_SHA512;
+                       break;
+
+               case WINPR_MD_RIPEMD160:
+                       type = MBEDTLS_MD_RIPEMD160;
+                       break;
+       }
+
+       return type;
+}
+#endif
+
+int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen)
+{
+#if defined(WITH_OPENSSL)
+       const EVP_MD* evp = winpr_openssl_get_evp_md(md);
+       HMAC_CTX_init((HMAC_CTX*) ctx);
+       HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL);
+#elif defined(WITH_MBEDTLS)
+       const mbedtls_md_info_t* md_info;
+       mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
+       md_info = mbedtls_md_info_from_type(md_type);
+       mbedtls_md_init((mbedtls_md_context_t*) ctx);
+       mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 1);
+       mbedtls_md_hmac_starts((mbedtls_md_context_t*) ctx, key, keylen);
+#endif
+       return 0;
+}
+
+int winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
+{
+#if defined(WITH_OPENSSL)
+       HMAC_Update((HMAC_CTX*) ctx, input, ilen);
+#elif defined(WITH_MBEDTLS)
+       mbedtls_md_hmac_update((mbedtls_md_context_t*) ctx, input, ilen);
+#endif
+       return 0;
+}
+
+int winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output)
+{
+#if defined(WITH_OPENSSL)
+       HMAC_Final((HMAC_CTX*) ctx, output, NULL);
+       HMAC_CTX_cleanup((HMAC_CTX*) ctx);
+#elif defined(WITH_MBEDTLS)
+       mbedtls_md_hmac_finish((mbedtls_md_context_t*) ctx, output);
+       mbedtls_md_free((mbedtls_md_context_t*) ctx);
+#endif
+       return 0;
+}
+
+int winpr_HMAC(int md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen, BYTE* output)
+{
+       WINPR_HMAC_CTX ctx;
+       winpr_HMAC_Init(&ctx, md, key, keylen);
+       winpr_HMAC_Update(&ctx, input, ilen);
+       winpr_HMAC_Final(&ctx, output);
+       return 0;
+}
+
index 382831d..5646749 100644 (file)
@@ -5,6 +5,7 @@ set(MODULE_PREFIX "TEST_CRYPTO")
 set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
 
 set(${MODULE_PREFIX}_TESTS
+       TestCryptoHash.c
        TestCryptoProtectData.c
        TestCryptoProtectMemory.c
        TestCryptoCertEnumCertificatesInStore.c)
diff --git a/winpr/libwinpr/crypto/test/TestCryptoHash.c b/winpr/libwinpr/crypto/test/TestCryptoHash.c
new file mode 100644 (file)
index 0000000..8178469
--- /dev/null
@@ -0,0 +1,182 @@
+
+#include <winpr/crt.h>
+#include <winpr/print.h>
+#include <winpr/crypto.h>
+
+static const char* TEST_MD5_DATA = "test";
+static const BYTE* TEST_MD5_HASH = (BYTE*) "\x09\x8f\x6b\xcd\x46\x21\xd3\x73\xca\xde\x4e\x83\x26\x27\xb4\xf6";
+
+BOOL test_crypto_hash_md5()
+{
+       BYTE hash[16];
+       WINPR_MD5_CTX ctx;
+
+       winpr_MD5_Init(&ctx);
+       winpr_MD5_Update(&ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA));
+       winpr_MD5_Final(&ctx, hash);
+
+       if (memcmp(hash, TEST_MD5_HASH, 16) != 0)
+       {
+               char* actual;
+               char* expected;
+
+               actual = winpr_BinToHexString(hash, 16, FALSE);
+               expected = winpr_BinToHexString(TEST_MD5_HASH, 16, FALSE);
+
+               fprintf(stderr, "unexpected MD5 hash: Actual: %s Expected: %s\n", actual, expected);
+
+               free(actual);
+               free(expected);
+
+               return -1;
+       }
+
+       return TRUE;
+}
+
+static const char* TEST_MD4_DATA = "test";
+static const BYTE* TEST_MD4_HASH = (BYTE*) "\xdb\x34\x6d\x69\x1d\x7a\xcc\x4d\xc2\x62\x5d\xb1\x9f\x9e\x3f\x52";
+
+BOOL test_crypto_hash_md4()
+{
+       BYTE hash[16];
+       WINPR_MD4_CTX ctx;
+
+       winpr_MD4_Init(&ctx);
+       winpr_MD4_Update(&ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA));
+       winpr_MD4_Final(&ctx, hash);
+
+       if (memcmp(hash, TEST_MD4_HASH, 16) != 0)
+       {
+               char* actual;
+               char* expected;
+
+               actual = winpr_BinToHexString(hash, 16, FALSE);
+               expected = winpr_BinToHexString(TEST_MD4_HASH, 16, FALSE);
+
+               fprintf(stderr, "unexpected MD4 hash: Actual: %s Expected: %s\n", actual, expected);
+
+               free(actual);
+               free(expected);
+
+               return -1;
+       }
+
+       return TRUE;
+}
+
+static const char* TEST_SHA1_DATA = "test";
+static const BYTE* TEST_SHA1_HASH = (BYTE*) "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1c\x4c\x08\x73\xd3\x91\xe9\x87\x98\x2f\xbb\xd3";
+
+BOOL test_crypto_hash_sha1()
+{
+       BYTE hash[20];
+       WINPR_SHA1_CTX ctx;
+
+       winpr_SHA1_Init(&ctx);
+       winpr_SHA1_Update(&ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA));
+       winpr_SHA1_Final(&ctx, hash);
+
+       if (memcmp(hash, TEST_SHA1_HASH, 20) != 0)
+       {
+               char* actual;
+               char* expected;
+
+               actual = winpr_BinToHexString(hash, 20, FALSE);
+               expected = winpr_BinToHexString(TEST_SHA1_HASH, 20, FALSE);
+
+               fprintf(stderr, "unexpected SHA1 hash: Actual: %s Expected: %s\n", actual, expected);
+
+               free(actual);
+               free(expected);
+
+               return -1;
+       }
+
+       return TRUE;
+}
+
+static const char* TEST_HMAC_MD5_DATA = "Hi There";
+static const BYTE* TEST_HMAC_MD5_KEY = (BYTE*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
+static const BYTE* TEST_HMAC_MD5_HASH = (BYTE*) "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d";
+
+BOOL test_crypto_hash_hmac_md5()
+{
+       BYTE hash[16];
+       WINPR_HMAC_CTX ctx;
+
+       winpr_HMAC_Init(&ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, 16);
+       winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA));
+       winpr_HMAC_Final(&ctx, hash);
+
+       if (memcmp(hash, TEST_HMAC_MD5_HASH, 16) != 0)
+       {
+               char* actual;
+               char* expected;
+
+               actual = winpr_BinToHexString(hash, 16, FALSE);
+               expected = winpr_BinToHexString(TEST_HMAC_MD5_HASH, 16, FALSE);
+
+               fprintf(stderr, "unexpected HMAC-MD5 hash: Actual: %s Expected: %s\n", actual, expected);
+
+               free(actual);
+               free(expected);
+
+               return -1;
+       }
+
+       return TRUE;
+}
+
+static const char* TEST_HMAC_SHA1_DATA = "Hi There";
+static const BYTE* TEST_HMAC_SHA1_KEY = (BYTE*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
+static const BYTE* TEST_HMAC_SHA1_HASH = (BYTE*) "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00";
+
+BOOL test_crypto_hash_hmac_sha1()
+{
+       BYTE hash[20];
+       WINPR_HMAC_CTX ctx;
+
+       winpr_HMAC_Init(&ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, 20);
+       winpr_HMAC_Update(&ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA));
+       winpr_HMAC_Final(&ctx, hash);
+
+       if (memcmp(hash, TEST_HMAC_SHA1_HASH, 20) != 0)
+       {
+               char* actual;
+               char* expected;
+
+               actual = winpr_BinToHexString(hash, 20, FALSE);
+               expected = winpr_BinToHexString(TEST_HMAC_SHA1_HASH, 20, FALSE);
+
+               fprintf(stderr, "unexpected HMAC-SHA1 hash: Actual: %s Expected: %s\n", actual, expected);
+
+               free(actual);
+               free(expected);
+
+               return -1;
+       }
+
+       return TRUE;
+}
+
+int TestCryptoHash(int argc, char* argv[])
+{
+       if (!test_crypto_hash_md5())
+               return -1;
+
+       if (!test_crypto_hash_md4())
+               return -1;
+
+       if (!test_crypto_hash_sha1())
+               return -1;
+
+       if (!test_crypto_hash_hmac_md5())
+               return -1;
+
+       if (!test_crypto_hash_hmac_sha1())
+               return -1;
+
+       return 0;
+}
+
index e3e0907..efcad47 100644 (file)
@@ -54,11 +54,15 @@ winpr_module_add(${${MODULE_PREFIX}_NTLM_SRCS}
        ${${MODULE_PREFIX}_SCHANNEL_SRCS}
        ${${MODULE_PREFIX}_SRCS})
 
-winpr_include_directory_add(${ZLIB_INCLUDE_DIRS}
-       ${OPENSSL_INCLUDE_DIR})
+if(OPENSSL_FOUND)
+       winpr_include_directory_add(${OPENSSL_INCLUDE_DIR})
+       winpr_library_add(${OPENSSL_LIBRARIES})
+endif()
 
-winpr_library_add(${ZLIB_LIBRARIES}
-       ${OPENSSL_LIBRARIES})
+if(MBEDTLS_FOUND)
+       winpr_include_directory_add(${MBEDTLS_INCLUDE_DIR})
+       winpr_library_add(${MBEDTLS_LIBRARIES})
+endif()
 
 if(WIN32)
        winpr_library_add(ws2_32)