[Dovecot] [PATCH 5/10] NTLM, password hash and auhtentication response calculation

Andrey Panin pazke at donpac.ru
Tue Jul 27 16:18:41 EEST 2004


This patch adds NTLM and NTLMv2 hash and response calculation code.


 src/lib-ntlm/ntlm-encrypt.c |  123 ++++++++++++++++++++++++++++++++++++++++++++
 src/lib-ntlm/ntlm-encrypt.h |   17 ++++++
 2 files changed, 140 insertions(+)

diff -urpNX /usr/share/dontdiff dovecot-1.0-test30.vanilla/src/lib-ntlm/ntlm-encrypt.c dovecot-1.0-test30/src/lib-ntlm/ntlm-encrypt.c
--- dovecot-1.0-test30.vanilla/src/lib-ntlm/ntlm-encrypt.c	1970-01-01 03:00:00.000000000 +0300
+++ dovecot-1.0-test30/src/lib-ntlm/ntlm-encrypt.c	2004-07-27 14:02:37.000000000 +0400
@@ -0,0 +1,123 @@
+/*
+ * NTLM and NTLMv2 hash generation.
+ *
+ * Copyright (c) 2004 Andrey Panin <pazke at donpac.ru>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published 
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <ctype.h>
+
+#include "lib.h"
+#include "compat.h"
+#include "safe-memset.h"
+#include "md4.h"
+#include "hmac-md5.h"
+#include "ntlm.h"
+#include "ntlm-des.h"
+
+
+static int unicode(ucs2le_t *dst, const char *src, int len, int ucase)
+{
+	int i;
+	char *p = (char *) dst;
+
+	memset(dst, 0, len * sizeof(*dst));
+
+	for (i = 0; (i < len - 1) && *src; i++) {
+		*p++ = ucase ? i_toupper(*src) : *src;
+		*p++ = 0;
+		src++;
+	}
+
+	*p++ = 0;
+	*p++ = 0;
+
+	return i;
+}
+
+static void
+ntlmssp_des_encrypt_triad(const unsigned char *hash,
+		 	  const unsigned char *challenge,
+			  unsigned char *response)
+{
+	deshash(response, challenge, hash);
+	deshash(response + 8, challenge, hash + 7);
+	deshash(response + 16, challenge, hash + 14);
+}
+
+const unsigned char *
+ntlm_v1_hash(const char *passwd, unsigned char hash[NTLMSSP_HASH_SIZE])
+{
+	int len = strlen(passwd);
+	ucs2le_t wpwd[len + 1];
+
+	unicode(wpwd, passwd, len + 1, 0);
+
+	len *= sizeof(ucs2le_t);
+
+	md4_get_digest(wpwd, len, hash);
+
+	safe_memset(wpwd, 0, len);
+
+	return hash;
+}
+
+static void
+hmac_md5_ucs2le_string_ucase(struct hmac_md5_context *ctx, const char *str)
+{
+	int len = strlen(str);
+	ucs2le_t ustr[len + 1];
+
+	unicode(ustr, str, len + 1, 1);
+
+	hmac_md5_update(ctx, ustr, len * sizeof(ucs2le_t));
+}
+
+static void
+ntlm_v2_hash(const char *user, const char *target,
+	     const unsigned char *hash_v1,
+	     unsigned char hash[NTLMSSP_V2_HASH_SIZE])
+{
+	struct hmac_md5_context ctx;
+
+	hmac_md5_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE);
+	hmac_md5_ucs2le_string_ucase(&ctx, user);
+	if (target)
+		hmac_md5_ucs2le_string_ucase(&ctx, target);
+	hmac_md5_final(&ctx, hash);
+}
+
+void
+ntlmssp_v1_response(const unsigned char *hash,
+		    const unsigned char *challenge,
+		    unsigned char response[NTLMSSP_RESPONSE_SIZE])
+{
+	unsigned char des_hash[NTLMSSP_DES_KEY_LENGTH * 3];
+
+	memcpy(des_hash, hash, NTLMSSP_HASH_SIZE);
+	memset(des_hash + NTLMSSP_HASH_SIZE, 0, sizeof(hash) - NTLMSSP_HASH_SIZE);
+
+	ntlmssp_des_encrypt_triad(des_hash, challenge, response);
+}
+
+void
+ntlmssp_v2_response(const char *user, const char *target,
+		    const unsigned char *hash_v1,
+		    const unsigned char *challenge,
+		    const unsigned char *blob, size_t blob_size,
+		    unsigned char response[NTLMSSP_V2_RESPONSE_SIZE])
+{
+	struct hmac_md5_context ctx;
+	unsigned char hash[NTLMSSP_V2_HASH_SIZE];
+
+	ntlm_v2_hash(user, target, hash_v1, hash);
+
+	hmac_md5_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE);
+	hmac_md5_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE);
+	hmac_md5_update(&ctx, blob, blob_size);
+	hmac_md5_final(&ctx, response);
+}
diff -urpNX /usr/share/dontdiff dovecot-1.0-test30.vanilla/src/lib-ntlm/ntlm-encrypt.h dovecot-1.0-test30/src/lib-ntlm/ntlm-encrypt.h
--- dovecot-1.0-test30.vanilla/src/lib-ntlm/ntlm-encrypt.h	1970-01-01 03:00:00.000000000 +0300
+++ dovecot-1.0-test30/src/lib-ntlm/ntlm-encrypt.h	2004-07-27 10:28:05.000000000 +0400
@@ -0,0 +1,17 @@
+#ifndef __NTLM_ENCRYPT__
+#define __NTLM_ENCRYPT__
+
+const unsigned char *
+ntlm_v1_hash(const char *passwd, unsigned char hash[NTLMSSP_HASH_SIZE]);
+
+void ntlmssp_v1_response(const unsigned char *hash,
+			 const unsigned char *challenge,
+			 unsigned char response[NTLMSSP_RESPONSE_SIZE]);
+
+void ntlmssp_v2_response(const char *user, const char *target,
+			 const unsigned char *hash_v1,
+			 const unsigned char *challenge,
+			 const unsigned char *blob, size_t blob_size,
+			 unsigned char response[NTLMSSP_V2_RESPONSE_SIZE]);
+
+#endif	/* __NTLM_ENCRYPT__ */




More information about the dovecot mailing list