From ce23225e46cbbef41dd6881acf8be5d0016d7ca5 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sun, 10 Nov 2013 22:05:55 +0100 Subject: [PATCH] Check if provided cipher and mode is usable before writing LUKS header to disk. If user provided unusable cipher-mode string, LUKS header was written and keyslot creation failed later. Better check early (by creating fake dmcrypt device) if cipher is usable and fail early (without writing LUKS header to device). Fixes Issue#176 --- lib/luks1/keymanage.c | 27 +++++++++++++++++++++++++++ tests/api-test.c | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index c1e24bdf..4a936a59 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -3,6 +3,7 @@ * * Copyright (C) 2004-2006, Clemens Fruhwirth * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved. + * Copyright (C) 2013, Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -594,6 +595,28 @@ int LUKS_write_phdr(struct luks_phdr *hdr, return r; } +/* Check that kernel supports requested cipher by decryption of one sector */ +static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx) +{ + int r; + struct volume_key *empty_key; + char buf[SECTOR_SIZE]; + + log_dbg("Checking if cipher %s-%s is usable.", hdr->cipherName, hdr->cipherMode); + + empty_key = crypt_alloc_volume_key(hdr->keyBytes, NULL); + if (!empty_key) + return -ENOMEM; + + r = LUKS_decrypt_from_storage(buf, sizeof(buf), + hdr->cipherName, hdr->cipherMode, + empty_key, 0, ctx); + + crypt_free_volume_key(empty_key); + memset(buf, 0, sizeof(buf)); + return r; +} + int LUKS_generate_phdr(struct luks_phdr *header, const struct volume_key *vk, const char *cipherName, const char *cipherMode, const char *hashSpec, @@ -647,6 +670,10 @@ int LUKS_generate_phdr(struct luks_phdr *header, LUKS_fix_header_compatible(header); + r = LUKS_check_cipher(header, ctx); + if (r < 0) + return r; + log_dbg("Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes", header->version, header->hashSpec ,header->cipherName, header->cipherMode, header->keyBytes); diff --git a/tests/api-test.c b/tests/api-test.c index 5607f8d8..721d3b57 100644 --- a/tests/api-test.c +++ b/tests/api-test.c @@ -1842,7 +1842,7 @@ static void NonFIPSAlg(void) struct crypt_device *cd; struct crypt_params_luks1 params = {0}; char key[128] = ""; - size_t key_size = 128; + size_t key_size = 128 / 8; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; int ret;