Blame SOURCES/0006-use-libgcrypt-for-MD5.patch

a66d21
From bcb2950d8ded9ec3a2e3ada8428aeaf725ea2171 Mon Sep 17 00:00:00 2001
a66d21
From: Paolo Bonzini <pbonzini@redhat.com>
a66d21
Date: Fri, 3 May 2013 12:47:12 +0200
a66d21
Subject: [RHEL7 libiscsi PATCH 06/18] use libgcrypt for MD5
a66d21
a66d21
This makes sure that CHAP authentication is disabled if the system
a66d21
is running in FIPS 140-2 mode.  MD5 is not a secure algorithm according
a66d21
to the standard.
a66d21
a66d21
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
a66d21
(cherry-picked from upstream commit bcb2950d8ded9ec3a2e3ada8428aeaf725ea2171)
a66d21
---
a66d21
 Makefile.am  |  6 +++++-
a66d21
 configure.ac |  3 +++
a66d21
 lib/login.c  | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
a66d21
 3 files changed, 60 insertions(+), 9 deletions(-)
a66d21
a66d21
diff --git a/Makefile.am b/Makefile.am
a66d21
index 5fea7c8..9a8b2b4 100644
a66d21
--- a/Makefile.am
a66d21
+++ b/Makefile.am
a66d21
@@ -34,10 +34,14 @@ dist_noinst_DATA = lib/libiscsi.syms
a66d21
 lib_LTLIBRARIES = lib/libiscsi.la
a66d21
 lib_libiscsi_la_SOURCES = \
a66d21
 	lib/connect.c lib/crc32c.c lib/discovery.c lib/init.c \
a66d21
-	lib/login.c lib/md5.c lib/nop.c lib/pdu.c lib/iscsi-command.c \
a66d21
+	lib/login.c lib/nop.c lib/pdu.c lib/iscsi-command.c \
a66d21
 	lib/scsi-lowlevel.c lib/socket.c lib/sync.c lib/task_mgmt.c \
a66d21
 	lib/logging.c
a66d21
 
a66d21
+if !HAVE_LIBGCRYPT
a66d21
+lib_libiscsi_la_SOURCES += lib/md5.c
a66d21
+endif
a66d21
+
a66d21
 SONAME=$(firstword $(subst ., ,$(VERSION)))
a66d21
 SOREL=$(shell printf "%d%02d%02d" $(subst ., ,$(VERSION)))
a66d21
 lib_libiscsi_la_LDFLAGS = \
a66d21
diff --git a/configure.ac b/configure.ac
a66d21
index 0b45f91..9d06e3a 100644
a66d21
--- a/configure.ac
a66d21
+++ b/configure.ac
a66d21
@@ -18,6 +18,9 @@ AC_SUBST(WARN_CFLAGS)
a66d21
 
a66d21
 AC_CONFIG_HEADER(config.h)
a66d21
 
a66d21
+AC_CHECK_LIB([gcrypt], [gcry_control])
a66d21
+AM_CONDITIONAL([HAVE_LIBGCRYPT], [test $ac_cv_lib_gcrypt_gcry_control = yes])
a66d21
+
a66d21
 AC_CACHE_CHECK([for sin_len in sock],libiscsi_cv_HAVE_SOCK_SIN_LEN,[
a66d21
 AC_TRY_COMPILE([#include <sys/types.h>
a66d21
 #include <sys/socket.h>
a66d21
diff --git a/lib/login.c b/lib/login.c
a66d21
index 07ca3dd..29fe4b3 100644
a66d21
--- a/lib/login.c
a66d21
+++ b/lib/login.c
a66d21
@@ -35,13 +35,18 @@
a66d21
 #include <arpa/inet.h>
a66d21
 #endif
a66d21
 
a66d21
+#include "config.h"
a66d21
 #include <stdio.h>
a66d21
+#include <assert.h>
a66d21
 #include <stdlib.h>
a66d21
 #include <string.h>
a66d21
 #include "iscsi.h"
a66d21
 #include "iscsi-private.h"
a66d21
 #include "scsi-lowlevel.h"
a66d21
 #include "md5.h"
a66d21
+#ifdef HAVE_LIBGCRYPT
a66d21
+#include <gcrypt.h>
a66d21
+#endif
a66d21
 
a66d21
 static int
a66d21
 iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
a66d21
@@ -628,6 +632,41 @@ i2h(int i)
a66d21
 	return i + '0';
a66d21
 }
a66d21
 
a66d21
+#ifndef HAVE_LIBGCRYPT
a66d21
+typedef struct MD5Context *gcry_md_hd_t;
a66d21
+#define gcry_md_write MD5Update
a66d21
+#define GCRY_MD_MD5 1
a66d21
+
a66d21
+static inline void gcry_md_open(gcry_md_hd_t *hd, int algo, unsigned int flags)
a66d21
+{
a66d21
+	assert(algo == GCRY_MD_MD5 && flags == 0);
a66d21
+	*hd = malloc(sizeof(struct MD5Context));
a66d21
+	if (*hd) {
a66d21
+		MD5Init(*hd);
a66d21
+	}
a66d21
+}
a66d21
+
a66d21
+static inline void gcry_md_putc(gcry_md_hd_t h, unsigned char c)
a66d21
+{
a66d21
+	MD5Update(h, &c, 1);
a66d21
+}
a66d21
+
a66d21
+static inline char *gcry_md_read(gcry_md_hd_t h, int algo)
a66d21
+{
a66d21
+	unsigned char digest[16];
a66d21
+	assert(algo == 0 || algo == GCRY_MD_MD5);
a66d21
+
a66d21
+	MD5Final(digest, h);
a66d21
+	return memcpy(h->buf, digest, sizeof(digest));
a66d21
+}
a66d21
+
a66d21
+static inline void gcry_md_close(gcry_md_hd_t h)
a66d21
+{
a66d21
+	memset(h, 0, sizeof(*h));
a66d21
+	free(h);
a66d21
+}
a66d21
+#endif
a66d21
+
a66d21
 static int
a66d21
 iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
a66d21
 {
a66d21
@@ -635,7 +674,7 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu
a66d21
 	char * strp;
a66d21
 	unsigned char c, cc[2];
a66d21
 	unsigned char digest[16];
a66d21
-	struct MD5Context ctx;
a66d21
+	gcry_md_hd_t ctx;
a66d21
 	int i;
a66d21
 
a66d21
 	if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG
a66d21
@@ -643,22 +682,27 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu
a66d21
 		return 0;
a66d21
 	}
a66d21
 
a66d21
+	gcry_md_open(&ctx, GCRY_MD_MD5, 0);
a66d21
+	if (!ctx) {
a66d21
+		iscsi_set_error(iscsi, "Cannot create MD5 algorithm");
a66d21
+		return -1;
a66d21
+	}
a66d21
+
a66d21
 	if (!iscsi->chap_c[0]) {
a66d21
 		iscsi_set_error(iscsi, "No CHAP challenge found");
a66d21
 		return -1;
a66d21
 	}
a66d21
-	MD5Init(&ctx;;
a66d21
-	c = iscsi->chap_i;
a66d21
-	MD5Update(&ctx, &c, 1);
a66d21
-	MD5Update(&ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd));
a66d21
-	
a66d21
+	gcry_md_putc(ctx, iscsi->chap_i);
a66d21
+	gcry_md_write(ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd));
a66d21
+
a66d21
 	strp = iscsi->chap_c;
a66d21
 	while (*strp != 0) {
a66d21
 		c = (h2i(strp[0]) << 4) | h2i(strp[1]);
a66d21
 		strp += 2;
a66d21
-		MD5Update(&ctx, &c, 1);
a66d21
+		gcry_md_putc(ctx, c);
a66d21
 	}
a66d21
-	MD5Final(digest, &ctx;;
a66d21
+	memcpy(digest, gcry_md_read(ctx, 0), sizeof(digest));
a66d21
+	gcry_md_close(ctx);
a66d21
 
a66d21
 	strncpy(str,"CHAP_R=0x",MAX_STRING_SIZE);
a66d21
 	if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str))
a66d21
-- 
a66d21
1.8.1.4
a66d21