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