Blame SOURCES/dovecot-2.3.6-opensslhmac.patch

70765b
diff -up dovecot-2.2.36/src/auth/auth-token.c.opensslhmac dovecot-2.2.36/src/auth/auth-token.c
70765b
--- dovecot-2.2.36/src/auth/auth-token.c.opensslhmac	2018-04-30 15:52:04.000000000 +0200
70765b
+++ dovecot-2.2.36/src/auth/auth-token.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -163,17 +163,17 @@ void auth_token_deinit(void)
70765b
 const char *auth_token_get(const char *service, const char *session_pid,
70765b
 			   const char *username, const char *session_id)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	unsigned char result[SHA1_RESULTLEN];
70765b
 
70765b
-	hmac_init(&ctx, (const unsigned char*)username, strlen(username),
70765b
+	openssl_hmac_init(&ctx, (const unsigned char*)username, strlen(username),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, session_pid, strlen(session_pid));
70765b
+	openssl_hmac_update(&ctx, session_pid, strlen(session_pid));
70765b
 	if (session_id != NULL && *session_id != '\0')
70765b
-		hmac_update(&ctx, session_id, strlen(session_id));
70765b
-	hmac_update(&ctx, service, strlen(service));
70765b
-	hmac_update(&ctx, auth_token_secret, sizeof(auth_token_secret));
70765b
-	hmac_final(&ctx, result);
70765b
+		openssl_hmac_update(&ctx, session_id, strlen(session_id));
70765b
+	openssl_hmac_update(&ctx, service, strlen(service));
70765b
+	openssl_hmac_update(&ctx, auth_token_secret, sizeof(auth_token_secret));
70765b
+	openssl_hmac_final(&ctx, result);
70765b
 
70765b
 	return binary_to_hex(result, sizeof(result));
70765b
 }
70765b
diff -up dovecot-2.2.36/src/auth/mech-cram-md5.c.opensslhmac dovecot-2.2.36/src/auth/mech-cram-md5.c
70765b
--- dovecot-2.2.36/src/auth/mech-cram-md5.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/auth/mech-cram-md5.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -51,7 +51,7 @@ static bool verify_credentials(struct cr
70765b
 {
70765b
 	
70765b
 	unsigned char digest[MD5_RESULTLEN];
70765b
-        struct hmac_context ctx;
70765b
+        struct orig_hmac_context ctx;
70765b
 	const char *response_hex;
70765b
 
70765b
 	if (size != CRAM_MD5_CONTEXTLEN) {
70765b
@@ -60,10 +60,10 @@ static bool verify_credentials(struct cr
70765b
 		return FALSE;
70765b
 	}
70765b
 
70765b
-	hmac_init(&ctx, NULL, 0, &hash_method_md5);
70765b
+	orig_hmac_init(&ctx, NULL, 0, &hash_method_md5);
70765b
 	hmac_md5_set_cram_context(&ctx, credentials);
70765b
-	hmac_update(&ctx, request->challenge, strlen(request->challenge));
70765b
-	hmac_final(&ctx, digest);
70765b
+	orig_hmac_update(&ctx, request->challenge, strlen(request->challenge));
70765b
+	orig_hmac_final(&ctx, digest);
70765b
 
70765b
 	response_hex = binary_to_hex(digest, sizeof(digest));
70765b
 
70765b
diff -up dovecot-2.2.36/src/auth/mech-scram-sha1.c.opensslhmac dovecot-2.2.36/src/auth/mech-scram-sha1.c
70765b
--- dovecot-2.2.36/src/auth/mech-scram-sha1.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/auth/mech-scram-sha1.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -71,7 +71,7 @@ static const char *get_scram_server_firs
70765b
 
70765b
 static const char *get_scram_server_final(struct scram_auth_request *request)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	const char *auth_message;
70765b
 	unsigned char server_signature[SHA1_RESULTLEN];
70765b
 	string_t *str;
70765b
@@ -80,10 +80,10 @@ static const char *get_scram_server_fina
70765b
 			request->server_first_message, ",",
70765b
 			request->client_final_message_without_proof, NULL);
70765b
 
70765b
-	hmac_init(&ctx, request->server_key, sizeof(request->server_key),
70765b
+	openssl_hmac_init(&ctx, request->server_key, sizeof(request->server_key),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, auth_message, strlen(auth_message));
70765b
-	hmac_final(&ctx, server_signature);
70765b
+	openssl_hmac_update(&ctx, auth_message, strlen(auth_message));
70765b
+	openssl_hmac_final(&ctx, server_signature);
70765b
 
70765b
 	str = t_str_new(MAX_BASE64_ENCODED_SIZE(sizeof(server_signature)));
70765b
 	str_append(str, "v=");
70765b
@@ -221,7 +221,7 @@ static bool parse_scram_client_first(str
70765b
 
70765b
 static bool verify_credentials(struct scram_auth_request *request)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	const char *auth_message;
70765b
 	unsigned char client_key[SHA1_RESULTLEN];
70765b
 	unsigned char client_signature[SHA1_RESULTLEN];
70765b
@@ -232,10 +232,10 @@ static bool verify_credentials(struct sc
70765b
 			request->server_first_message, ",",
70765b
 			request->client_final_message_without_proof, NULL);
70765b
 
70765b
-	hmac_init(&ctx, request->stored_key, sizeof(request->stored_key),
70765b
+	openssl_hmac_init(&ctx, request->stored_key, sizeof(request->stored_key),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, auth_message, strlen(auth_message));
70765b
-	hmac_final(&ctx, client_signature);
70765b
+	openssl_hmac_update(&ctx, auth_message, strlen(auth_message));
70765b
+	openssl_hmac_final(&ctx, client_signature);
70765b
 
70765b
 	for (i = 0; i < sizeof(client_signature); i++)
70765b
 		client_key[i] =
70765b
diff -up dovecot-2.2.36/src/auth/password-scheme.c.opensslhmac dovecot-2.2.36/src/auth/password-scheme.c
70765b
--- dovecot-2.2.36/src/auth/password-scheme.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/auth/password-scheme.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -655,11 +655,11 @@ static void
70765b
 cram_md5_generate(const char *plaintext, const char *user ATTR_UNUSED,
70765b
 		  const unsigned char **raw_password_r, size_t *size_r)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct orig_hmac_context ctx;
70765b
 	unsigned char *context_digest;
70765b
 
70765b
 	context_digest = t_malloc(CRAM_MD5_CONTEXTLEN);
70765b
-	hmac_init(&ctx, (const unsigned char *)plaintext,
70765b
+	orig_hmac_init(&ctx, (const unsigned char *)plaintext,
70765b
 		  strlen(plaintext), &hash_method_md5);
70765b
 	hmac_md5_get_cram_context(&ctx, context_digest);
70765b
 
70765b
diff -up dovecot-2.2.36/src/auth/password-scheme-scram.c.opensslhmac dovecot-2.2.36/src/auth/password-scheme-scram.c
70765b
--- dovecot-2.2.36/src/auth/password-scheme-scram.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/auth/password-scheme-scram.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -27,23 +27,23 @@ static void Hi(const unsigned char *str,
70765b
 	       const unsigned char *salt, size_t salt_size, unsigned int i,
70765b
 	       unsigned char result[SHA1_RESULTLEN])
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	unsigned char U[SHA1_RESULTLEN];
70765b
 	unsigned int j, k;
70765b
 
70765b
 	/* Calculate U1 */
70765b
-	hmac_init(&ctx, str, str_size, &hash_method_sha1);
70765b
-	hmac_update(&ctx, salt, salt_size);
70765b
-	hmac_update(&ctx, "\0\0\0\1", 4);
70765b
-	hmac_final(&ctx, U);
70765b
+	openssl_hmac_init(&ctx, str, str_size, &hash_method_sha1);
70765b
+	openssl_hmac_update(&ctx, salt, salt_size);
70765b
+	openssl_hmac_update(&ctx, "\0\0\0\1", 4);
70765b
+	openssl_hmac_final(&ctx, U);
70765b
 
70765b
 	memcpy(result, U, SHA1_RESULTLEN);
70765b
 
70765b
 	/* Calculate U2 to Ui and Hi */
70765b
 	for (j = 2; j <= i; j++) {
70765b
-		hmac_init(&ctx, str, str_size, &hash_method_sha1);
70765b
-		hmac_update(&ctx, U, sizeof(U));
70765b
-		hmac_final(&ctx, U);
70765b
+		openssl_hmac_init(&ctx, str, str_size, &hash_method_sha1);
70765b
+		openssl_hmac_update(&ctx, U, sizeof(U));
70765b
+		openssl_hmac_final(&ctx, U);
70765b
 		for (k = 0; k < SHA1_RESULTLEN; k++)
70765b
 			result[k] ^= U[k];
70765b
 	}
70765b
@@ -94,7 +94,7 @@ int scram_sha1_verify(const char *plaint
70765b
 		      const unsigned char *raw_password, size_t size,
70765b
 		      const char **error_r)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	const char *salt_base64;
70765b
 	unsigned int iter_count;
70765b
 	const unsigned char *salt;
70765b
@@ -118,10 +118,10 @@ int scram_sha1_verify(const char *plaint
70765b
 	   iter_count, salted_password);
70765b
 
70765b
 	/* Calculate ClientKey */
70765b
-	hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
+	openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, "Client Key", 10);
70765b
-	hmac_final(&ctx, client_key);
70765b
+	openssl_hmac_update(&ctx, "Client Key", 10);
70765b
+	openssl_hmac_final(&ctx, client_key);
70765b
 
70765b
 	/* Calculate StoredKey */
70765b
 	sha1_get_digest(client_key, sizeof(client_key), calculated_stored_key);
70765b
@@ -139,7 +139,7 @@ void scram_sha1_generate(const char *pla
70765b
 			 const unsigned char **raw_password_r, size_t *size_r)
70765b
 {
70765b
 	string_t *str;
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	unsigned char salt[16];
70765b
 	unsigned char salted_password[SHA1_RESULTLEN];
70765b
 	unsigned char client_key[SHA1_RESULTLEN];
70765b
@@ -157,10 +157,10 @@ void scram_sha1_generate(const char *pla
70765b
 	   sizeof(salt), SCRAM_DEFAULT_ITERATE_COUNT, salted_password);
70765b
 
70765b
 	/* Calculate ClientKey */
70765b
-	hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
+	openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, "Client Key", 10);
70765b
-	hmac_final(&ctx, client_key);
70765b
+	openssl_hmac_update(&ctx, "Client Key", 10);
70765b
+	openssl_hmac_final(&ctx, client_key);
70765b
 
70765b
 	/* Calculate StoredKey */
70765b
 	sha1_get_digest(client_key, sizeof(client_key), stored_key);
70765b
@@ -168,10 +168,10 @@ void scram_sha1_generate(const char *pla
70765b
 	base64_encode(stored_key, sizeof(stored_key), str);
70765b
 
70765b
 	/* Calculate ServerKey */
70765b
-	hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
+	openssl_hmac_init(&ctx, salted_password, sizeof(salted_password),
70765b
 		  &hash_method_sha1);
70765b
-	hmac_update(&ctx, "Server Key", 10);
70765b
-	hmac_final(&ctx, server_key);
70765b
+	openssl_hmac_update(&ctx, "Server Key", 10);
70765b
+	openssl_hmac_final(&ctx, server_key);
70765b
 	str_append_c(str, ',');
70765b
 	base64_encode(server_key, sizeof(server_key), str);
70765b
 
70765b
diff -up dovecot-2.2.36/src/lib/hmac.c.opensslhmac dovecot-2.2.36/src/lib/hmac.c
70765b
--- dovecot-2.2.36/src/lib/hmac.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/hmac.c	2019-06-10 15:38:38.834070480 +0200
70765b
@@ -7,15 +7,74 @@
70765b
  * This software is released under the MIT license.
70765b
  */
70765b
 
70765b
+#include <sys/types.h>
70765b
+#include <sys/stat.h>
70765b
+#include <fcntl.h>
70765b
+#include <unistd.h>
70765b
 #include "lib.h"
70765b
 #include "hmac.h"
70765b
 #include "safe-memset.h"
70765b
 #include "buffer.h"
70765b
 
70765b
-void hmac_init(struct hmac_context *_ctx, const unsigned char *key,
70765b
+#ifndef HAVE_HMAC_CTX_NEW
70765b
+#  define HMAC_Init_ex(ctx, key, key_len, md, impl) \
70765b
+	HMAC_Init_ex(&(ctx), key, key_len, md, impl)
70765b
+#  define HMAC_Update(ctx, data, len) HMAC_Update(&(ctx), data, len)
70765b
+#  define HMAC_Final(ctx, md, len) HMAC_Final(&(ctx), md, len)
70765b
+#  define HMAC_CTX_free(ctx) HMAC_cleanup(&(ctx))
70765b
+#else
70765b
+#  define HMAC_CTX_free(ctx) \
70765b
+	STMT_START { HMAC_CTX_free(ctx); (ctx) = NULL; } STMT_END
70765b
+#endif
70765b
+
70765b
+
70765b
+void openssl_hmac_init(struct openssl_hmac_context *_ctx, const unsigned char *key,
70765b
+		size_t key_len, const struct hash_method *meth)
70765b
+{
70765b
+ 	struct openssl_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+
70765b
+	const EVP_MD *md;
70765b
+    const char *ebuf = NULL;
70765b
+    const char **error_r = &ebuf;
70765b
+
70765b
+	md = EVP_get_digestbyname(meth->name);
70765b
+	if(md == NULL) {
70765b
+		if (error_r != NULL) {
70765b
+			*error_r = t_strdup_printf("Invalid digest %s",
70765b
+						   meth->name);
70765b
+		}
70765b
+		//return FALSE;
70765b
+	}
70765b
+
70765b
+// 	int ec;
70765b
+
70765b
+	i_assert(md != NULL);
70765b
+#ifdef HAVE_HMAC_CTX_NEW
70765b
+	ctx->ctx = HMAC_CTX_new();
70765b
+/*	if (ctx->ctx == NULL)
70765b
+		dcrypt_openssl_error(error_r);*/
70765b
+#endif
70765b
+	/*ec = */HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL);
70765b
+}
70765b
+
70765b
+void orig_hmac_init(struct orig_hmac_context *_ctx, const unsigned char *key,
70765b
 		size_t key_len, const struct hash_method *meth)
70765b
 {
70765b
-	struct hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+    static int no_fips = -1;
70765b
+    if (no_fips == -1) {
70765b
+        int fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY);
70765b
+        if (fd != -1)
70765b
+        {
70765b
+            char buf[4];
70765b
+            if (read(fd, buf, 4) > 0)
70765b
+            {
70765b
+                no_fips = buf[0] == '0';   
70765b
+            }
70765b
+            close(fd);   
70765b
+        }
70765b
+    }
70765b
+    i_assert(no_fips);
70765b
+	struct orig_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
 	int i;
70765b
 	unsigned char k_ipad[64];
70765b
 	unsigned char k_opad[64];
70765b
@@ -51,9 +110,27 @@ void hmac_init(struct hmac_context *_ctx
70765b
 	safe_memset(k_opad, 0, 64);
70765b
 }
70765b
 
70765b
-void hmac_final(struct hmac_context *_ctx, unsigned char *digest)
70765b
+void openssl_hmac_final(struct openssl_hmac_context *_ctx, unsigned char *digest)
70765b
+{
70765b
+	int ec;
70765b
+	unsigned char buf[HMAC_MAX_MD_CBLOCK];
70765b
+	unsigned int outl;
70765b
+//     const char *ebuf = NULL;
70765b
+//     const char **error_r = &ebuf;
70765b
+
70765b
+    struct openssl_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+	ec = HMAC_Final(ctx->ctx, buf, &outl);
70765b
+	HMAC_CTX_free(ctx->ctx);
70765b
+	if (ec == 1)
70765b
+		memcpy(digest, buf, outl);
70765b
+//	else
70765b
+//		dcrypt_openssl_error(error_r);
70765b
+
70765b
+}
70765b
+
70765b
+void orig_hmac_final(struct orig_hmac_context *_ctx, unsigned char *digest)
70765b
 {
70765b
-	struct hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+	struct orig_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
 
70765b
 	ctx->hash->result(ctx->ctx, digest);
70765b
 
70765b
@@ -61,35 +138,35 @@ void hmac_final(struct hmac_context *_ct
70765b
 	ctx->hash->result(ctx->ctxo, digest);
70765b
 }
70765b
 
70765b
-buffer_t *t_hmac_data(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_data(const struct hash_method *meth,
70765b
 		      const unsigned char *key, size_t key_len,
70765b
 		      const void *data, size_t data_len)
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	i_assert(meth != NULL);
70765b
 	i_assert(key != NULL && key_len > 0);
70765b
 	i_assert(data != NULL || data_len == 0);
70765b
 
70765b
 	buffer_t *res = buffer_create_dynamic(pool_datastack_create(), meth->digest_size);
70765b
-	hmac_init(&ctx, key, key_len, meth);
70765b
+	openssl_hmac_init(&ctx, key, key_len, meth);
70765b
 	if (data_len > 0)
70765b
-		hmac_update(&ctx, data, data_len);
70765b
+		openssl_hmac_update(&ctx, data, data_len);
70765b
 	unsigned char *buf = buffer_get_space_unsafe(res, 0, meth->digest_size);
70765b
-	hmac_final(&ctx, buf);
70765b
+	openssl_hmac_final(&ctx, buf);
70765b
 	return res;
70765b
 }
70765b
 
70765b
-buffer_t *t_hmac_buffer(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_buffer(const struct hash_method *meth,
70765b
 			const unsigned char *key, size_t key_len,
70765b
 			const buffer_t *data)
70765b
 {
70765b
-	return t_hmac_data(meth, key, key_len, data->data, data->used);
70765b
+	return openssl_t_hmac_data(meth, key, key_len, data->data, data->used);
70765b
 }
70765b
 
70765b
-buffer_t *t_hmac_str(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_str(const struct hash_method *meth,
70765b
 		     const unsigned char *key, size_t key_len,
70765b
 		     const char *data)
70765b
 {
70765b
-	return t_hmac_data(meth, key, key_len, data, strlen(data));
70765b
+	return openssl_t_hmac_data(meth, key, key_len, data, strlen(data));
70765b
 }
70765b
 
70765b
diff -up dovecot-2.2.36/src/lib/hmac-cram-md5.c.opensslhmac dovecot-2.2.36/src/lib/hmac-cram-md5.c
70765b
--- dovecot-2.2.36/src/lib/hmac-cram-md5.c.opensslhmac	2017-06-23 13:18:28.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/hmac-cram-md5.c	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -9,10 +9,10 @@
70765b
 #include "md5.h"
70765b
 #include "hmac-cram-md5.h"
70765b
 
70765b
-void hmac_md5_get_cram_context(struct hmac_context *_hmac_ctx,
70765b
+void hmac_md5_get_cram_context(struct orig_hmac_context *_hmac_ctx,
70765b
 			unsigned char context_digest[CRAM_MD5_CONTEXTLEN])
70765b
 {
70765b
-	struct hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv;
70765b
+	struct orig_hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv;
70765b
 	unsigned char *cdp;
70765b
 
70765b
 	struct md5_context *ctx = (void*)hmac_ctx->ctx;
70765b
@@ -35,10 +35,10 @@ void hmac_md5_get_cram_context(struct hm
70765b
 	CDPUT(cdp, ctx->d);
70765b
 }
70765b
 
70765b
-void hmac_md5_set_cram_context(struct hmac_context *_hmac_ctx,
70765b
+void hmac_md5_set_cram_context(struct orig_hmac_context *_hmac_ctx,
70765b
 			const unsigned char context_digest[CRAM_MD5_CONTEXTLEN])
70765b
 {
70765b
-	struct hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv;
70765b
+	struct orig_hmac_context_priv *hmac_ctx = &_hmac_ctx->u.priv;
70765b
 	const unsigned char *cdp;
70765b
 
70765b
 	struct md5_context *ctx = (void*)hmac_ctx->ctx;
70765b
diff -up dovecot-2.2.36/src/lib/hmac-cram-md5.h.opensslhmac dovecot-2.2.36/src/lib/hmac-cram-md5.h
70765b
--- dovecot-2.2.36/src/lib/hmac-cram-md5.h.opensslhmac	2017-06-23 13:18:28.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/hmac-cram-md5.h	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -5,9 +5,9 @@
70765b
 
70765b
 #define CRAM_MD5_CONTEXTLEN 32
70765b
 
70765b
-void hmac_md5_get_cram_context(struct hmac_context *ctx,
70765b
+void hmac_md5_get_cram_context(struct orig_hmac_context *ctx,
70765b
 		unsigned char context_digest[CRAM_MD5_CONTEXTLEN]);
70765b
-void hmac_md5_set_cram_context(struct hmac_context *ctx,
70765b
+void hmac_md5_set_cram_context(struct orig_hmac_context *ctx,
70765b
 		const unsigned char context_digest[CRAM_MD5_CONTEXTLEN]);
70765b
 
70765b
 
70765b
diff -up dovecot-2.2.36/src/lib/hmac.h.opensslhmac dovecot-2.2.36/src/lib/hmac.h
70765b
--- dovecot-2.2.36/src/lib/hmac.h.opensslhmac	2017-06-23 13:18:28.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/hmac.h	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -3,43 +3,98 @@
70765b
 
70765b
 #include "hash-method.h"
70765b
 #include "sha1.h"
70765b
+#include <openssl/objects.h>
70765b
+#include <openssl/hmac.h>
70765b
+#include <openssl/err.h>
70765b
 
70765b
 #define HMAC_MAX_CONTEXT_SIZE 256
70765b
 
70765b
-struct hmac_context_priv {
70765b
+struct openssl_hmac_context_priv {
70765b
+#ifdef HAVE_HMAC_CTX_NEW
70765b
+	HMAC_CTX *ctx;
70765b
+#else
70765b
+	HMAC_CTX ctx;
70765b
+#endif
70765b
+	const struct hash_method *hash;
70765b
+};
70765b
+
70765b
+struct orig_hmac_context_priv {
70765b
 	char ctx[HMAC_MAX_CONTEXT_SIZE];
70765b
 	char ctxo[HMAC_MAX_CONTEXT_SIZE];
70765b
 	const struct hash_method *hash;
70765b
 };
70765b
 
70765b
-struct hmac_context {
70765b
+struct openssl_hmac_context {
70765b
+	union {
70765b
+		struct openssl_hmac_context_priv priv;
70765b
+		uint64_t padding_requirement;
70765b
+	} u;
70765b
+};
70765b
+
70765b
+struct orig_hmac_context {
70765b
 	union {
70765b
-		struct hmac_context_priv priv;
70765b
+		struct orig_hmac_context_priv priv;
70765b
 		uint64_t padding_requirement;
70765b
 	} u;
70765b
 };
70765b
 
70765b
-void hmac_init(struct hmac_context *ctx, const unsigned char *key,
70765b
+void openssl_hmac_init(struct openssl_hmac_context *ctx, const unsigned char *key,
70765b
 		size_t key_len, const struct hash_method *meth);
70765b
-void hmac_final(struct hmac_context *ctx, unsigned char *digest);
70765b
+void openssl_hmac_final(struct openssl_hmac_context *ctx, unsigned char *digest);
70765b
+
70765b
+static inline void
70765b
+openssl_hmac_update(struct openssl_hmac_context *_ctx, const void *data, size_t size)
70765b
+{
70765b
+	struct openssl_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+	HMAC_Update(ctx->ctx, data, size);
70765b
+/*	if (ec != 1)
70765b
+    {
70765b
+        const char *ebuf = NULL;
70765b
+        const char **error_r = &ebuf;
70765b
+		dcrypt_openssl_error(error_r);
70765b
+    }*/
70765b
+}
70765b
+
70765b
+void orig_hmac_init(struct orig_hmac_context *ctx, const unsigned char *key,
70765b
+		size_t key_len, const struct hash_method *meth);
70765b
+void orig_hmac_final(struct orig_hmac_context *ctx, unsigned char *digest);
70765b
 
70765b
 
70765b
 static inline void
70765b
-hmac_update(struct hmac_context *_ctx, const void *data, size_t size)
70765b
+orig_hmac_update(struct orig_hmac_context *_ctx, const void *data, size_t size)
70765b
 {
70765b
-	struct hmac_context_priv *ctx = &_ctx->u.priv;
70765b
+	struct orig_hmac_context_priv *ctx = &_ctx->u.priv;
70765b
 
70765b
 	ctx->hash->loop(ctx->ctx, data, size);
70765b
 }
70765b
 
70765b
-buffer_t *t_hmac_data(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_data(const struct hash_method *meth,
70765b
 		      const unsigned char *key, size_t key_len,
70765b
 		      const void *data, size_t data_len);
70765b
-buffer_t *t_hmac_buffer(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_buffer(const struct hash_method *meth,
70765b
 			const unsigned char *key, size_t key_len,
70765b
 			const buffer_t *data);
70765b
-buffer_t *t_hmac_str(const struct hash_method *meth,
70765b
+buffer_t *openssl_t_hmac_str(const struct hash_method *meth,
70765b
 		     const unsigned char *key, size_t key_len,
70765b
 		     const char *data);
70765b
 
70765b
+
70765b
+#if 0
70765b
+static bool dcrypt_openssl_error(const char **error_r)
70765b
+{
70765b
+	unsigned long ec;
70765b
+
70765b
+	if (error_r == NULL) {
70765b
+		/* caller is not really interested */
70765b
+		return FALSE; 
70765b
+	}
70765b
+
70765b
+	ec = ERR_get_error();
70765b
+	*error_r = t_strdup_printf("%s", ERR_error_string(ec, NULL));
70765b
+	return FALSE;
70765b
+}
70765b
+#endif
70765b
+
70765b
+
70765b
+
70765b
 #endif
70765b
diff -up dovecot-2.2.36/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac dovecot-2.2.36/src/lib-imap-urlauth/imap-urlauth.c
70765b
--- dovecot-2.2.36/src/lib-imap-urlauth/imap-urlauth.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib-imap-urlauth/imap-urlauth.c	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -83,15 +83,15 @@ imap_urlauth_internal_generate(const cha
70765b
 			       const unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN],
70765b
 			       size_t *token_len_r)
70765b
 {
70765b
-	struct hmac_context hmac;
70765b
+	struct openssl_hmac_context hmac;
70765b
 	unsigned char *token;
70765b
 
70765b
 	token = t_new(unsigned char, SHA1_RESULTLEN + 1);
70765b
 	token[0] = IMAP_URLAUTH_MECH_INTERNAL_VERSION;
70765b
 
70765b
-	hmac_init(&hmac, mailbox_key, IMAP_URLAUTH_KEY_LEN, &hash_method_sha1);
70765b
-	hmac_update(&hmac, rumpurl, strlen(rumpurl));
70765b
-	hmac_final(&hmac, token+1);
70765b
+	openssl_hmac_init(&hmac, mailbox_key, IMAP_URLAUTH_KEY_LEN, &hash_method_sha1);
70765b
+	openssl_hmac_update(&hmac, rumpurl, strlen(rumpurl));
70765b
+	openssl_hmac_final(&hmac, token+1);
70765b
 
70765b
 	*token_len_r = SHA1_RESULTLEN + 1;
70765b
 	return token;
70765b
diff -up dovecot-2.2.36/src/lib/Makefile.am.opensslhmac dovecot-2.2.36/src/lib/Makefile.am
70765b
--- dovecot-2.2.36/src/lib/Makefile.am.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/Makefile.am	2019-06-10 15:42:28.810140696 +0200
70765b
@@ -306,6 +306,9 @@ headers = \
70765b
 	wildcard-match.h \
70765b
 	write-full.h
70765b
 
70765b
+liblib_la_LIBADD = $(SSL_LIBS)
70765b
+liblib_la_CFLAGS = $(SSL_CFLAGS)
70765b
+
70765b
 test_programs = test-lib
70765b
 noinst_PROGRAMS = $(test_programs)
70765b
 
70765b
@@ -335,6 +338,7 @@ test_lib_SOURCES = \
70765b
 	test-hash-format.c \
70765b
 	test-hash-method.c \
70765b
 	test-hex-binary.c \
70765b
+	test-hmac.c \
70765b
 	test-imem.c \
70765b
 	test-ioloop.c \
70765b
 	test-iso8601-date.c \
70765b
diff -up dovecot-2.2.36/src/lib-ntlm/ntlm-encrypt.c.opensslhmac dovecot-2.2.36/src/lib-ntlm/ntlm-encrypt.c
70765b
--- dovecot-2.2.36/src/lib-ntlm/ntlm-encrypt.c.opensslhmac	2018-04-30 15:52:05.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib-ntlm/ntlm-encrypt.c	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -61,12 +61,12 @@ void ntlm_v1_hash(const char *passwd, un
70765b
 }
70765b
 
70765b
 static void
70765b
-hmac_md5_ucs2le_string_ucase(struct hmac_context *ctx, const char *str)
70765b
-{
70765b
-	size_t len;
70765b
-	unsigned char *wstr = t_unicode_str(str, 1, &len;;
70765b
-
70765b
-	hmac_update(ctx, wstr, len);
70765b
+hmac_md5_ucs2le_string_ucase(struct openssl_hmac_context *ctx, const char *str)
70765b
+ {
70765b
+ 	size_t len;
70765b
+ 	unsigned char *wstr = t_unicode_str(str, TRUE, &len;;
70765b
+ 
70765b
+	openssl_hmac_update(ctx, wstr, len);
70765b
 }
70765b
 
70765b
 static void ATTR_NULL(2)
70765b
@@ -74,13 +74,13 @@ ntlm_v2_hash(const char *user, const cha
70765b
 	     const unsigned char *hash_v1,
70765b
 	     unsigned char hash[NTLMSSP_V2_HASH_SIZE])
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 
70765b
-	hmac_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE, &hash_method_md5);
70765b
+	openssl_hmac_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE, &hash_method_md5);
70765b
 	hmac_md5_ucs2le_string_ucase(&ctx, user);
70765b
 	if (target != NULL)
70765b
 		hmac_md5_ucs2le_string_ucase(&ctx, target);
70765b
-	hmac_final(&ctx, hash);
70765b
+	openssl_hmac_final(&ctx, hash);
70765b
 }
70765b
 
70765b
 void
70765b
@@ -125,15 +125,15 @@ ntlmssp_v2_response(const char *user, co
70765b
 		    const unsigned char *blob, size_t blob_size,
70765b
 		    unsigned char response[NTLMSSP_V2_RESPONSE_SIZE])
70765b
 {
70765b
-	struct hmac_context ctx;
70765b
+	struct openssl_hmac_context ctx;
70765b
 	unsigned char hash[NTLMSSP_V2_HASH_SIZE];
70765b
 
70765b
 	ntlm_v2_hash(user, target, hash_v1, hash);
70765b
 
70765b
-	hmac_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE, &hash_method_md5);
70765b
-	hmac_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE);
70765b
-	hmac_update(&ctx, blob, blob_size);
70765b
-	hmac_final(&ctx, response);
70765b
+	openssl_hmac_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE, &hash_method_md5);
70765b
+	openssl_hmac_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE);
70765b
+	openssl_hmac_update(&ctx, blob, blob_size);
70765b
+	openssl_hmac_final(&ctx, response);
70765b
 
70765b
 	safe_memset(hash, 0, sizeof(hash));
70765b
 }
70765b
diff -up dovecot-2.2.36/src/lib/pkcs5.c.opensslhmac dovecot-2.2.36/src/lib/pkcs5.c
70765b
--- dovecot-2.2.36/src/lib/pkcs5.c.opensslhmac	2018-04-30 15:52:04.000000000 +0200
70765b
+++ dovecot-2.2.36/src/lib/pkcs5.c	2019-06-10 15:38:38.835070476 +0200
70765b
@@ -52,7 +52,7 @@ int pkcs5_pbkdf2(const struct hash_metho
70765b
 	size_t l = (length + hash->digest_size - 1)/hash->digest_size; /* same as ceil(length/hash->digest_size) */
70765b
 	unsigned char dk[l * hash->digest_size];
70765b
 	unsigned char *block;
70765b
-	struct hmac_context hctx;
70765b
+	struct openssl_hmac_context hctx;
70765b
 	unsigned int c,i,t;
70765b
 	unsigned char U_c[hash->digest_size];
70765b
 
70765b
@@ -60,17 +60,17 @@ int pkcs5_pbkdf2(const struct hash_metho
70765b
 		block = &(dk[t*hash->digest_size]);
70765b
 		/* U_1 = PRF(Password, Salt|| INT_BE32(Block_Number)) */
70765b
 		c = htonl(t+1);
70765b
-		hmac_init(&hctx, password, password_len, hash);
70765b
-		hmac_update(&hctx, salt, salt_len);
70765b
-		hmac_update(&hctx, &c, sizeof(c));
70765b
-		hmac_final(&hctx, U_c);
70765b
+		openssl_hmac_init(&hctx, password, password_len, hash);
70765b
+		openssl_hmac_update(&hctx, salt, salt_len);
70765b
+		openssl_hmac_update(&hctx, &c, sizeof(c));
70765b
+		openssl_hmac_final(&hctx, U_c);
70765b
 		/* block = U_1 ^ .. ^ U_iter */
70765b
 		memcpy(block, U_c, hash->digest_size);
70765b
 		/* U_c = PRF(Password, U_c-1) */
70765b
 		for(c = 1; c < iter; c++) {
70765b
-			hmac_init(&hctx, password, password_len, hash);
70765b
-			hmac_update(&hctx, U_c, hash->digest_size);
70765b
-			hmac_final(&hctx, U_c);
70765b
+			openssl_hmac_init(&hctx, password, password_len, hash);
70765b
+			openssl_hmac_update(&hctx, U_c, hash->digest_size);
70765b
+			openssl_hmac_final(&hctx, U_c);
70765b
 			for(i = 0; i < hash->digest_size; i++)
70765b
 				block[i] ^= U_c[i];
70765b
 		}
70765b
diff -up dovecot-2.2.36/src/lib/test-hmac.c.opensslhmac dovecot-2.2.36/src/lib/test-hmac.c
70765b
--- dovecot-2.2.36/src/lib/test-hmac.c.opensslhmac	2019-06-10 15:43:02.847003098 +0200
70765b
+++ dovecot-2.2.36/src/lib/test-hmac.c	2019-06-10 14:00:52.000000000 +0200
70765b
@@ -0,0 +1,103 @@
70765b
+/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
70765b
+
70765b
+#include "test-lib.h"
70765b
+#include "hash-method.h"
70765b
+#include "hmac.h"
70765b
+#include "sha-common.h"
70765b
+#include "buffer.h"
70765b
+
70765b
+struct test_vector {
70765b
+	const char *prf;
70765b
+	const unsigned char *key;
70765b
+	size_t key_len;
70765b
+	const unsigned char *data;
70765b
+	size_t data_len;
70765b
+	const unsigned char *res;
70765b
+	size_t res_len;
70765b
+};
70765b
+
70765b
+#define TEST_BUF(x) (const unsigned char*)x, sizeof(x)-1
70765b
+
70765b
+/* RFC 4231 test vectors */
70765b
+static const struct test_vector test_vectors[] = {
70765b
+	/* Test Case 1 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"),
70765b
+	TEST_BUF("Hi There"),
70765b
+	TEST_BUF("\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7")
70765b
+	},
70765b
+	/* Test Case 2 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\x4a\x65\x66\x65"), /* "Jefe" */
70765b
+	TEST_BUF("what do ya want for nothing?"),
70765b
+	TEST_BUF("\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43")
70765b
+	},
70765b
+	/* Test Case 3 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
70765b
+	TEST_BUF("\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"),
70765b
+	TEST_BUF("\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe")
70765b
+	},
70765b
+	/* Test Case 4 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"),
70765b
+	TEST_BUF("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"),
70765b
+	TEST_BUF("\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b")
70765b
+	},
70765b
+	/* Test Case 5 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"),
70765b
+	TEST_BUF("\x54\x65\x73\x74\x20\x57\x69\x74\x68\x20\x54\x72\x75\x6e\x63\x61\x74\x69\x6f\x6e"), /* "Test With Truncation" */
70765b
+	TEST_BUF("\xa3\xb6\x16\x74\x73\x10\x0e\xe0\x6e\x0c\x79\x6c\x29\x55\x55\x2b")
70765b
+	},
70765b
+	/* Test Case 6 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
70765b
+	TEST_BUF("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74"), /* "Test Using Larger Than Block-Size Key - Hash Key First" */
70765b
+	TEST_BUF("\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54")
70765b
+	},
70765b
+	/* Test Case 7 */
70765b
+	{ "sha256",
70765b
+	TEST_BUF("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"),
70765b
+	TEST_BUF("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"),
70765b
+	/* "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." */
70765b
+	TEST_BUF("\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2")
70765b
+	}
70765b
+};
70765b
+
70765b
+static void test_hmac_rfc(void)
70765b
+{
70765b
+	test_begin("hmac sha256 rfc4231 vectors");
70765b
+	for(size_t i = 0; i < N_ELEMENTS(test_vectors); i++) {
70765b
+		const struct test_vector *vec = &(test_vectors[i]);
70765b
+		struct openssl_hmac_context ctx;
70765b
+		openssl_hmac_init(&ctx, vec->key, vec->key_len, hash_method_lookup(vec->prf));
70765b
+		openssl_hmac_update(&ctx, vec->data, vec->data_len);
70765b
+		unsigned char res[SHA256_RESULTLEN];
70765b
+		openssl_hmac_final(&ctx, res);
70765b
+		test_assert_idx(memcmp(res, vec->res, vec->res_len) == 0, i);
70765b
+	}
70765b
+	test_end();
70765b
+}
70765b
+
70765b
+static void test_hmac_buffer(void)
70765b
+{
70765b
+	const struct test_vector *vec = &(test_vectors[0]);
70765b
+	test_begin("hmac temporary buffer");
70765b
+
70765b
+	buffer_t *tmp;
70765b
+
70765b
+	tmp = openssl_t_hmac_data(hash_method_lookup(vec->prf), vec->key, vec->key_len,
70765b
+			  vec->data, vec->data_len);
70765b
+
70765b
+	test_assert(tmp->used == vec->res_len &&
70765b
+		    memcmp(tmp->data, vec->res, vec->res_len) == 0);
70765b
+
70765b
+	test_end();
70765b
+}
70765b
+
70765b
+void test_hmac(void)
70765b
+{
70765b
+	test_hmac_rfc();
70765b
+	test_hmac_buffer();
70765b
+}
70765b
diff -up dovecot-2.2.36/src/lib/test-lib.h.opensslhmac dovecot-2.2.36/src/lib/test-lib.h
70765b
--- dovecot-2.2.36/src/lib/test-lib.h.opensslhmac	2019-06-10 15:41:57.155268669 +0200
70765b
+++ dovecot-2.2.36/src/lib/test-lib.h	2019-06-10 15:41:57.194268512 +0200
70765b
@@ -20,6 +20,7 @@ void test_failures(void);
70765b
 void test_file_create_locked(void);
70765b
 void test_guid(void);
70765b
 void test_hash(void);
70765b
+void test_hmac(void);
70765b
 void test_hash_format(void);
70765b
 void test_hash_method(void);
70765b
 void test_hex_binary(void);