diff --git a/.cryptsetup.metadata b/.cryptsetup.metadata index 834901d..6107d6a 100644 --- a/.cryptsetup.metadata +++ b/.cryptsetup.metadata @@ -1 +1 @@ -1b7005c0f8ad286a7f3d65e99cb555597666605c SOURCES/cryptsetup-1.7.2.tar.xz +1f06d268aee0adff931a39fe6709af7804e4f4f6 SOURCES/cryptsetup-1.7.4.tar.xz diff --git a/.gitignore b/.gitignore index 6adbac9..83bb1c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/cryptsetup-1.7.2.tar.xz +SOURCES/cryptsetup-1.7.4.tar.xz diff --git a/SOURCES/cryptsetup-1.7.5-fix-luksformat-in-fips-mode.patch b/SOURCES/cryptsetup-1.7.5-fix-luksformat-in-fips-mode.patch new file mode 100644 index 0000000..c321d4a --- /dev/null +++ b/SOURCES/cryptsetup-1.7.5-fix-luksformat-in-fips-mode.patch @@ -0,0 +1,35 @@ +From 3c2135b36bbc52d052e4ced7c94dc4981eb07a53 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Fri, 21 Apr 2017 08:16:14 +0200 +Subject: [PATCH] Fix luksFormat if running in FIPS mode on recent kernel. + +Recently introduced check for weak keys for XTS mode makes +zeroed key for algorithm check unusable. + +Use random key for the test instead. +--- + lib/luks1/keymanage.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c +index b700bab..5b1421b 100644 +--- a/lib/luks1/keymanage.c ++++ b/lib/luks1/keymanage.c +@@ -631,9 +631,11 @@ static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx) + if (!empty_key) + return -ENOMEM; + +- r = LUKS_decrypt_from_storage(buf, sizeof(buf), +- hdr->cipherName, hdr->cipherMode, +- empty_key, 0, ctx); ++ /* No need to get KEY quality random but it must avoid known weak keys. */ ++ r = crypt_random_get(ctx, empty_key->key, empty_key->keylength, CRYPT_RND_NORMAL); ++ if (!r) ++ r = LUKS_decrypt_from_storage(buf, sizeof(buf), hdr->cipherName, ++ hdr->cipherMode, empty_key, 0, ctx); + + crypt_free_volume_key(empty_key); + crypt_memzero(buf, sizeof(buf)); +-- +2.7.4 + diff --git a/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch b/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch new file mode 100644 index 0000000..874a851 --- /dev/null +++ b/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch @@ -0,0 +1,376 @@ +From a117f431179a2747f2b1d5293f43d9e198f1bac9 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Mon, 30 Nov 2015 16:44:15 +0100 +Subject: [PATCH] Fix access to unaligned hidden TrueCrypt header. + +backport all changes needed to fix unaligned access +to hidden TrueCrypt hedaer. +--- + lib/internal.h | 7 ++- + lib/luks1/keymanage.c | 6 +- + lib/tcrypt/tcrypt.c | 24 ++++---- + lib/utils.c | 155 +++++++++++++++++++++++++++++++++++++++++++------- + 4 files changed, 152 insertions(+), 40 deletions(-) + +diff --git a/lib/internal.h b/lib/internal.h +index 382a600..f1525f2 100644 +--- a/lib/internal.h ++++ b/lib/internal.h +@@ -101,9 +101,12 @@ char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t + char *crypt_get_base_device(const char *dev_path); + uint64_t crypt_dev_partition_offset(const char *dev_path); + ++ssize_t write_buffer(int fd, const void *buf, size_t count); ++ssize_t read_buffer(int fd, void *buf, size_t count); + ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count); +-ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count); +-ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset); ++ssize_t read_blockwise(int fd, int bsize, void *buf, size_t count); ++ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset); ++ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset); + + unsigned crypt_getpagesize(void); + int init_crypto(struct crypt_device *ctx); +diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c +index 23e3fe2..b193ee9 100644 +--- a/lib/luks1/keymanage.c ++++ b/lib/luks1/keymanage.c +@@ -201,7 +201,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx) + r = -EINVAL; + goto out; + } +- if (write(devfd, buffer, buffer_size) < buffer_size) { ++ if (write_buffer(devfd, buffer, buffer_size) < buffer_size) { + log_err(ctx, _("Cannot write header backup file %s.\n"), backup_file); + r = -EIO; + goto out; +@@ -253,7 +253,7 @@ int LUKS_hdr_restore( + goto out; + } + +- if (read(devfd, buffer, buffer_size) < buffer_size) { ++ if (read_buffer(devfd, buffer, buffer_size) < buffer_size) { + log_err(ctx, _("Cannot read header backup file %s.\n"), backup_file); + r = -EIO; + goto out; +@@ -498,7 +498,7 @@ int LUKS_read_phdr_backup(const char *backup_file, + return -ENOENT; + } + +- if (read(devfd, hdr, hdr_size) < hdr_size) ++ if (read_buffer(devfd, hdr, hdr_size) < hdr_size) + r = -EIO; + else { + LUKS_fix_header_compatible(hdr); +diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c +index 45154ed..9ff7157 100644 +--- a/lib/tcrypt/tcrypt.c ++++ b/lib/tcrypt/tcrypt.c +@@ -469,8 +469,7 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd, + return -EIO; + } + +- /* FIXME: add while */ +- data_size = read(fd, data, TCRYPT_KEYFILE_LEN); ++ data_size = read_buffer(fd, data, TCRYPT_KEYFILE_LEN); + close(fd); + if (data_size < 0) { + log_err(cd, _("Error reading keyfile %s.\n"), keyfile); +@@ -628,27 +627,26 @@ int TCRYPT_read_phdr(struct crypt_device *cd, + + r = -EIO; + if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) { +- if (lseek(devfd, TCRYPT_HDR_SYSTEM_OFFSET, SEEK_SET) >= 0 && +- read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) { ++ if (read_lseek_blockwise(devfd, bs, hdr, hdr_size, ++ TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) { + r = TCRYPT_init_hdr(cd, hdr, params); + } + } else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) { + if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) { +- if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_BCK, SEEK_END) >= 0 && +- read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) ++ if (read_lseek_blockwise(devfd, bs, hdr, hdr_size, ++ TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size) + r = TCRYPT_init_hdr(cd, hdr, params); + } else { +- if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET, SEEK_SET) >= 0 && +- read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) ++ if (read_lseek_blockwise(devfd, bs, hdr, hdr_size, ++ TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size) + r = TCRYPT_init_hdr(cd, hdr, params); +- if (r && +- lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_OLD, SEEK_END) >= 0 && +- read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) ++ if (r && read_lseek_blockwise(devfd, bs, hdr, hdr_size, ++ TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size) + r = TCRYPT_init_hdr(cd, hdr, params); + } + } else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) { +- if (lseek(devfd, TCRYPT_HDR_OFFSET_BCK, SEEK_END) >= 0 && +- read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) ++ if (read_lseek_blockwise(devfd, bs, hdr, hdr_size, ++ TCRYPT_HDR_OFFSET_BCK) == hdr_size) + r = TCRYPT_init_hdr(cd, hdr, params); + } else if (read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) + r = TCRYPT_init_hdr(cd, hdr, params); +diff --git a/lib/utils.c b/lib/utils.c +index 2dcf753..802ba55 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -56,22 +56,70 @@ static void *aligned_malloc(void **base, int size, int alignment) + /* Credits go to Michal's padlock patches for this alignment code */ + char *ptr; + +- ptr = malloc(size + alignment); +- if(ptr == NULL) return NULL; ++ ptr = malloc(size + alignment); ++ if (!ptr) ++ return NULL; + + *base = ptr; +- if(alignment > 1 && ((long)ptr & (alignment - 1))) { ++ if (alignment > 1 && ((long)ptr & (alignment - 1))) + ptr += alignment - ((long)(ptr) & (alignment - 1)); +- } ++ + return ptr; + #endif + } + ++ssize_t read_buffer(int fd, void *buf, size_t count) ++{ ++ size_t read_size = 0; ++ ssize_t r; ++ ++ if (fd < 0 || !buf) ++ return -EINVAL; ++ ++ do { ++ r = read(fd, buf, count - read_size); ++ if (r == -1 && errno != EINTR) ++ return r; ++ if (r == 0) ++ return (ssize_t)read_size; ++ if (r > 0) { ++ read_size += (size_t)r; ++ buf = (uint8_t*)buf + r; ++ } ++ } while (read_size != count); ++ ++ return (ssize_t)count; ++} ++ ++ssize_t write_buffer(int fd, const void *buf, size_t count) ++{ ++ size_t write_size = 0; ++ ssize_t w; ++ ++ if (fd < 0 || !buf || !count) ++ return -EINVAL; ++ ++ do { ++ w = write(fd, buf, count - write_size); ++ if (w < 0 && errno != EINTR) ++ return w; ++ if (w == 0) ++ return (ssize_t)write_size; ++ if (w > 0) { ++ write_size += (size_t) w; ++ buf = (const uint8_t*)buf + w; ++ } ++ } while (write_size != count); ++ ++ return (ssize_t)write_size; ++} ++ + ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count) + { + void *hangover_buf, *hangover_buf_base = NULL; + void *buf, *buf_base = NULL; +- int r, hangover, solid, alignment; ++ int r, alignment; ++ size_t hangover, solid; + ssize_t ret = -1; + + if (fd == -1 || !orig_buf || bsize <= 0) +@@ -89,17 +137,19 @@ ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count) + } else + buf = orig_buf; + +- r = write(fd, buf, solid); +- if (r < 0 || r != solid) +- goto out; ++ if (solid) { ++ r = write_buffer(fd, buf, solid); ++ if (r < 0 || r != (ssize_t)solid) ++ goto out; ++ } + + if (hangover) { + hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment); + if (!hangover_buf) + goto out; + +- r = read(fd, hangover_buf, bsize); +- if (r < 0 || r < hangover) ++ r = read_buffer(fd, hangover_buf, bsize); ++ if (r < 0 || r < (ssize_t)hangover) + goto out; + + if (r < bsize) +@@ -110,8 +160,8 @@ ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count) + + memcpy(hangover_buf, (char*)buf + solid, hangover); + +- r = write(fd, hangover_buf, bsize); +- if (r < 0 || r < hangover) ++ r = write_buffer(fd, hangover_buf, bsize); ++ if (r < 0 || r < (ssize_t)hangover) + goto out; + } + ret = count; +@@ -122,10 +172,12 @@ out: + return ret; + } + +-ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) { ++ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) ++{ + void *hangover_buf, *hangover_buf_base = NULL; + void *buf, *buf_base = NULL; +- int r, hangover, solid, alignment; ++ int r, alignment; ++ size_t hangover, solid; + ssize_t ret = -1; + + if (fd == -1 || !orig_buf || bsize <= 0) +@@ -142,16 +194,16 @@ ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) { + } else + buf = orig_buf; + +- r = read(fd, buf, solid); +- if(r < 0 || r != solid) ++ r = read_buffer(fd, buf, solid); ++ if (r < 0 || r != (ssize_t)solid) + goto out; + + if (hangover) { + hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment); + if (!hangover_buf) + goto out; +- r = read(fd, hangover_buf, bsize); +- if (r < 0 || r < hangover) ++ r = read_buffer(fd, hangover_buf, bsize); ++ if (r < 0 || r < (ssize_t)hangover) + goto out; + + memcpy((char *)buf + solid, hangover_buf, hangover); +@@ -172,7 +224,8 @@ out: + * is implicitly included in the read/write offset, which can not be set to non-aligned + * boundaries. Hence, we combine llseek with write. + */ +-ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset) { ++ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset) ++{ + char *frontPadBuf; + void *frontPadBuf_base = NULL; + int r, frontHang; +@@ -182,6 +235,12 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t + if (fd == -1 || !buf || bsize <= 0) + return -1; + ++ if (offset < 0) ++ offset = lseek(fd, offset, SEEK_END); ++ ++ if (offset < 0) ++ return -1; ++ + frontHang = offset % bsize; + + if (lseek(fd, offset - frontHang, SEEK_SET) < 0) +@@ -193,7 +252,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t + if (!frontPadBuf) + goto out; + +- r = read(fd, frontPadBuf, bsize); ++ r = read_buffer(fd, frontPadBuf, bsize); + if (r < 0 || r != bsize) + goto out; + +@@ -206,11 +265,11 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t + if (lseek(fd, offset - frontHang, SEEK_SET) < 0) + goto out; + +- r = write(fd, frontPadBuf, bsize); ++ r = write_buffer(fd, frontPadBuf, bsize); + if (r < 0 || r != bsize) + goto out; + +- buf += innerCount; ++ buf = (char*)buf + innerCount; + count -= innerCount; + } + +@@ -223,6 +282,58 @@ out: + return ret; + } + ++ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset) ++{ ++ char *frontPadBuf; ++ void *frontPadBuf_base = NULL; ++ int r, frontHang; ++ size_t innerCount = 0; ++ ssize_t ret = -1; ++ ++ if (fd == -1 || !buf || bsize <= 0) ++ return -1; ++ ++ if (offset < 0) ++ offset = lseek(fd, offset, SEEK_END); ++ ++ if (offset < 0) ++ return -1; ++ ++ frontHang = offset % bsize; ++ ++ if (lseek(fd, offset - frontHang, SEEK_SET) < 0) ++ return ret; ++ ++ if (frontHang) { ++ frontPadBuf = aligned_malloc(&frontPadBuf_base, ++ bsize, get_alignment(fd)); ++ ++ if (!frontPadBuf) ++ return ret; ++ ++ r = read_buffer(fd, frontPadBuf, bsize); ++ if (r < 0 || r != bsize) ++ goto out; ++ ++ innerCount = bsize - frontHang; ++ if (innerCount > count) ++ innerCount = count; ++ ++ memcpy(buf, frontPadBuf + frontHang, innerCount); ++ ++ buf = (char*)buf + innerCount; ++ count -= innerCount; ++ } ++ ++ ret = read_blockwise(fd, bsize, buf, count); ++ if (ret >= 0) ++ ret += innerCount; ++out: ++ free(frontPadBuf_base); ++ ++ return ret; ++} ++ + /* MEMLOCK */ + #define DEFAULT_PROCESS_PRIORITY -18 + +-- +2.7.4 + diff --git a/SPECS/cryptsetup.spec b/SPECS/cryptsetup.spec index fa837ad..02b1dac 100644 --- a/SPECS/cryptsetup.spec +++ b/SPECS/cryptsetup.spec @@ -4,8 +4,8 @@ Summary: A utility for setting up encrypted disks Name: cryptsetup -Version: 1.7.2 -Release: 1%{?dist} +Version: 1.7.4 +Release: 3%{?dist} License: GPLv2+ and LGPLv2+ Group: Applications/System URL: https://gitlab.com/cryptsetup/cryptsetup @@ -24,6 +24,8 @@ Requires: libpwquality >= 1.2.0 %define upstream_version %{version} Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-%{upstream_version}.tar.xz Patch0: %{name}-avoid-rh-kernel-bug.patch +Patch1: %{name}-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch +Patch2: %{name}-1.7.5-fix-luksformat-in-fips-mode.patch %if 0%{?fedora} >= 19 || 0%{?rhel} >= 7 %define configure_cipher --enable-gcrypt-pbkdf2 @@ -110,6 +112,8 @@ for setting up disk encryption using dm-crypt kernel module. %prep %setup -q -n cryptsetup-%{upstream_version} %patch0 -p1 +%patch1 -p1 +%patch2 -p1 chmod -x python/pycryptsetup-test.py %if %{python3_enable} @@ -205,6 +209,18 @@ install -m755 misc/dracut_90reencrypt/reencrypt.sh %{buildroot}/%{dracutmodulesd %clean %changelog +* Tue Apr 25 2017 Ondrej Kozina - 1.7.4-3 +- patch: fix luksFormat failure while running in FIPS mode. +- Resolves: #1444137 + +* Tue Apr 04 2017 Ondrej Kozina - 1.7.4-2 +- patch: fix access to unaligned hidden TrueCrypt header. +- Resolves: #1435543 + +* Wed Mar 15 2017 Ondrej Kozina - 1.7.4-1 +- Update to cryptsetup 1.7.4. +- Resolves: #1381273 + * Tue Jun 7 2016 Ondrej Kozina - 1.7.2-1 - Update to cryptsetup 1.7.2. - Resolves: #1302022 #1070825