From: Milan Broz Date: Tue, 26 Oct 2010 14:34:17 +0000 (+0000) Subject: Generalise volume key struct. X-Git-Tag: upstream/1.6~585 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ef10cd09ec26390edc3f6f2009d7cdcbdc242a9c;p=platform%2Fupstream%2Fcryptsetup.git Generalise volume key struct. Do not generate unused volume key in PLAIN mode. git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@346 36d66b0a-2a48-0410-832c-cd162a569da5 --- diff --git a/lib/Makefile.am b/lib/Makefile.am index 635e6c6..be97c0b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -41,6 +41,7 @@ libcryptsetup_la_SOURCES = \ utils_debug.c \ backends.c \ libdevmapper.c \ + volumekey.c \ gcrypt.c include_HEADERS = libcryptsetup.h diff --git a/lib/internal.h b/lib/internal.h index cdfcef2..7123c3c 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -46,6 +46,14 @@ struct device_infos { int readonly; }; +struct volume_key { + size_t keylength; + char key[]; +}; +struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key); +struct volume_key *crypt_generate_volume_key(unsigned keylength); +void crypt_free_volume_key(struct volume_key *mk); + struct crypt_device; int crypt_confirm(struct crypt_device *cd, const char *msg); diff --git a/lib/setup.c b/lib/setup.c index 2f7026e..ae8db71 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -13,7 +13,7 @@ struct crypt_device { char *type; char *device; - struct luks_masterkey *volume_key; + struct volume_key *volume_key; uint64_t timeout; uint64_t iteration_time; int tries; @@ -193,7 +193,7 @@ static int verify_other_keyslot(struct crypt_device *cd, unsigned int flags, int keyIndex) { - struct luks_masterkey *mk; + struct volume_key *vk; crypt_keyslot_info ki; int openedIndex; char *password = NULL; @@ -210,11 +210,11 @@ static int verify_other_keyslot(struct crypt_device *cd, openedIndex = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, passwordLen, - &cd->hdr, &mk, cd); + &cd->hdr, &vk, cd); if (ki == CRYPT_SLOT_ACTIVE) LUKS_keyslot_set(&cd->hdr, keyIndex, 1); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); safe_free(password); if (openedIndex < 0) @@ -229,7 +229,7 @@ static int find_keyslot_by_passphrase(struct crypt_device *cd, unsigned int flags, char *message) { - struct luks_masterkey *mk; + struct volume_key *vk; char *password = NULL; unsigned int passwordLen; int keyIndex; @@ -240,8 +240,8 @@ static int find_keyslot_by_passphrase(struct crypt_device *cd, return -EINVAL; keyIndex = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, - passwordLen, &cd->hdr, &mk, cd); - LUKS_dealloc_masterkey(mk); + passwordLen, &cd->hdr, &vk, cd); + crypt_free_volume_key(vk); safe_free(password); return keyIndex; @@ -394,8 +394,8 @@ static int create_device_helper(struct crypt_device *cd, return r; } -static int open_from_hdr_and_mk(struct crypt_device *cd, - struct luks_masterkey *mk, +static int open_from_hdr_and_vk(struct crypt_device *cd, + struct volume_key *vk, const char *name, uint32_t flags) { @@ -418,7 +418,7 @@ static int open_from_hdr_and_mk(struct crypt_device *cd, else r = dm_create_device(name, cd->device, cipher, cd->type, no_uuid ? NULL : crypt_get_uuid(cd), - size, 0, offset, mk->keyLength, mk->key, + size, 0, offset, vk->keylength, vk->key, read_only, 0); free(cipher); return r; @@ -467,7 +467,7 @@ static void key_from_terminal(struct crypt_device *cd, char *msg, char **key, } static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslot, - struct luks_masterkey **mk) + struct volume_key **vk) { char *prompt = NULL, *passphrase_read = NULL; unsigned int passphrase_size_read; @@ -476,11 +476,11 @@ static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslo if(asprintf(&prompt, _("Enter passphrase for %s: "), cd->device) < 0) return -ENOMEM; - *mk = NULL; + *vk = NULL; do { - if (*mk) - LUKS_dealloc_masterkey(*mk); - *mk = NULL; + if (*vk) + crypt_free_volume_key(*vk); + *vk = NULL; key_from_terminal(cd, prompt, &passphrase_read, &passphrase_size_read, 0); @@ -490,14 +490,14 @@ static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslo } r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read, - passphrase_size_read, &cd->hdr, mk, cd); + passphrase_size_read, &cd->hdr, vk, cd); safe_free(passphrase_read); passphrase_read = NULL; } while (r == -EPERM && (--tries > 0)); - if (r < 0 && *mk) { - LUKS_dealloc_masterkey(*mk); - *mk = NULL; + if (r < 0 && *vk) { + crypt_free_volume_key(*vk); + *vk = NULL; } free(prompt); @@ -1051,6 +1051,7 @@ static int _crypt_format_plain(struct crypt_device *cd, const char *cipher, const char *cipher_mode, const char *uuid, + size_t volume_key_size, struct crypt_params_plain *params) { if (!cipher || !cipher_mode) { @@ -1058,11 +1059,15 @@ static int _crypt_format_plain(struct crypt_device *cd, return -EINVAL; } - if (cd->volume_key->keyLength > 1024) { + if (volume_key_size > 1024) { log_err(cd, _("Invalid key size.\n")); return -EINVAL; } + cd->volume_key = crypt_alloc_volume_key(volume_key_size, NULL); + if (!cd->volume_key) + return -ENOMEM; + cd->plain_cipher = strdup(cipher); cd->plain_cipher_mode = strdup(cipher_mode); @@ -1085,6 +1090,8 @@ static int _crypt_format_luks1(struct crypt_device *cd, const char *cipher, const char *cipher_mode, const char *uuid, + const char *volume_key, + size_t volume_key_size, struct crypt_params_luks1 *params) { int r; @@ -1096,6 +1103,15 @@ static int _crypt_format_luks1(struct crypt_device *cd, return -EINVAL; } + if (volume_key) + cd->volume_key = crypt_alloc_volume_key(volume_key_size, + volume_key); + else + cd->volume_key = crypt_generate_volume_key(volume_key_size); + + if(!cd->volume_key) + return -ENOMEM; + if (params && params->data_alignment) required_alignment = params->data_alignment * SECTOR_SIZE; else @@ -1145,21 +1161,12 @@ int crypt_format(struct crypt_device *cd, return -ENOSYS; } - if (volume_key) - cd->volume_key = LUKS_alloc_masterkey(volume_key_size, - volume_key); - else - cd->volume_key = LUKS_generate_masterkey(volume_key_size); - - if(!cd->volume_key) - return -ENOMEM; - if (isPLAIN(type)) r = _crypt_format_plain(cd, cipher, cipher_mode, - uuid, params); + uuid, volume_key_size, params); else if (isLUKS(type)) r = _crypt_format_luks1(cd, cipher, cipher_mode, - uuid, params); + uuid, volume_key, volume_key_size, params); else { /* FIXME: allow plugins here? */ log_err(cd, _("Unknown crypt device type %s requested.\n"), type); @@ -1170,7 +1177,7 @@ int crypt_format(struct crypt_device *cd, r = -ENOMEM; if (r < 0) { - LUKS_dealloc_masterkey(cd->volume_key); + crypt_free_volume_key(cd->volume_key); cd->volume_key = NULL; } @@ -1256,7 +1263,7 @@ void crypt_free(struct crypt_device *cd) dm_exit(); if (cd->volume_key) - LUKS_dealloc_masterkey(cd->volume_key); + crypt_free_volume_key(cd->volume_key); free(cd->device); free(cd->type); @@ -1316,7 +1323,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, const char *passphrase, size_t passphrase_size) { - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; int r, suspended = 0; log_dbg("Resuming volume %s.", name); @@ -1339,13 +1346,13 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, if (passphrase) { r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase, - passphrase_size, &cd->hdr, &mk, cd); + passphrase_size, &cd->hdr, &vk, cd); } else - r = volume_key_by_terminal_passphrase(cd, keyslot, &mk); + r = volume_key_by_terminal_passphrase(cd, keyslot, &vk); if (r >= 0) { keyslot = r; - r = dm_resume_and_reinstate_key(name, mk->keyLength, mk->key); + r = dm_resume_and_reinstate_key(name, vk->keylength, vk->key); if (r == -ENOTSUP) log_err(cd, "Resume is not supported for device %s.\n", name); else if (r) @@ -1353,7 +1360,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd, } else r = keyslot; out: - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r < 0 ? r : keyslot; } @@ -1363,7 +1370,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd, const char *keyfile, size_t keyfile_size) { - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; char *passphrase_read = NULL; unsigned int passphrase_size_read; int r, suspended = 0; @@ -1396,19 +1403,19 @@ int crypt_resume_by_keyfile(struct crypt_device *cd, r = -EINVAL; else { r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read, - passphrase_size_read, &cd->hdr, &mk, cd); + passphrase_size_read, &cd->hdr, &vk, cd); safe_free(passphrase_read); } if (r >= 0) { keyslot = r; - r = dm_resume_and_reinstate_key(name, mk->keyLength, mk->key); + r = dm_resume_and_reinstate_key(name, vk->keylength, vk->key); if (r) log_err(cd, "Error during resuming device %s.\n", name); } else r = keyslot; out: - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r < 0 ? r : keyslot; } @@ -1420,7 +1427,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, const char *new_passphrase, // NULL -> terminal size_t new_passphrase_size) { - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; char *password = NULL, *new_password = NULL; unsigned int passwordLen, new_passwordLen; int r; @@ -1441,8 +1448,8 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, if (!LUKS_keyslot_active_count(&cd->hdr)) { /* No slots used, try to use pre-generated key in header */ if (cd->volume_key) { - mk = LUKS_alloc_masterkey(cd->volume_key->keyLength, cd->volume_key->key); - r = mk ? 0 : -ENOMEM; + vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key); + r = vk ? 0 : -ENOMEM; } else { log_err(cd, _("Cannot add key slot, all slots disabled and no volume key provided.\n")); return -EINVAL; @@ -1450,7 +1457,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, } else if (passphrase) { /* Passphrase provided, use it to unlock existing keyslot */ r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, passphrase, - passphrase_size, &cd->hdr, &mk, cd); + passphrase_size, &cd->hdr, &vk, cd); } else { /* Passphrase not provided, ask first and use it to unlock existing keyslot */ key_from_terminal(cd, _("Enter any passphrase: "), @@ -1461,7 +1468,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, } r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, - passwordLen, &cd->hdr, &mk, cd); + passwordLen, &cd->hdr, &vk, cd); safe_free(password); } @@ -1481,14 +1488,14 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, } r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen, - &cd->hdr, mk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); + &cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); if(r < 0) goto out; r = 0; out: if (!new_passphrase) safe_free(new_password); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r ?: keyslot; } @@ -1499,7 +1506,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, const char *new_keyfile, size_t new_keyfile_size) { - struct luks_masterkey *mk=NULL; + struct volume_key *vk=NULL; char *password=NULL; unsigned int passwordLen; char *new_password = NULL; unsigned int new_passwordLen; int r; @@ -1519,8 +1526,8 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, if (!LUKS_keyslot_active_count(&cd->hdr)) { /* No slots used, try to use pre-generated key in header */ if (cd->volume_key) { - mk = LUKS_alloc_masterkey(cd->volume_key->keyLength, cd->volume_key->key); - r = mk ? 0 : -ENOMEM; + vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key); + r = vk ? 0 : -ENOMEM; } else { log_err(cd, _("Cannot add key slot, all slots disabled and no volume key provided.\n")); return -EINVAL; @@ -1538,7 +1545,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, return -EINVAL; r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password, passwordLen, - &cd->hdr, &mk, cd); + &cd->hdr, &vk, cd); safe_free(password); } @@ -1559,10 +1566,10 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, } r = LUKS_set_key(cd->device, keyslot, new_password, new_passwordLen, - &cd->hdr, mk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); + &cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); out: safe_free(new_password); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r < 0 ? r : keyslot; } @@ -1573,7 +1580,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, const char *passphrase, size_t passphrase_size) { - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; int r = -EINVAL; char *new_password = NULL; unsigned int new_passwordLen; @@ -1585,14 +1592,14 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, } if (volume_key) - mk = LUKS_alloc_masterkey(volume_key_size, volume_key); + vk = crypt_alloc_volume_key(volume_key_size, volume_key); else if (cd->volume_key) - mk = LUKS_alloc_masterkey(cd->volume_key->keyLength, cd->volume_key->key); + vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key); - if (!mk) + if (!vk) return -ENOMEM; - r = LUKS_verify_master_key(&cd->hdr, mk); + r = LUKS_verify_volume_key(&cd->hdr, vk); if (r < 0) { log_err(cd, _("Volume key does not match the volume.\n")); goto out; @@ -1610,11 +1617,11 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, } r = LUKS_set_key(cd->device, keyslot, passphrase, passphrase_size, - &cd->hdr, mk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); + &cd->hdr, vk, cd->iteration_time, &cd->PBKDF2_per_sec, cd); out: if (new_password) safe_free(new_password); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r ?: keyslot; } @@ -1652,7 +1659,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd, uint32_t flags) { crypt_status_info ci; - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; char *prompt = NULL; int r; @@ -1664,7 +1671,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd, if (isPLAIN(cd->type)) return create_device_helper(cd, name, cd->plain_hdr.hash, cd->plain_cipher, cd->plain_cipher_mode, NULL, passphrase, passphrase_size, - cd->volume_key->keyLength, 0, cd->plain_hdr.skip, + cd->volume_key->keylength, 0, cd->plain_hdr.skip, cd->plain_hdr.offset, cd->plain_uuid, flags & CRYPT_ACTIVATE_READONLY, 0, 0); if (name) { @@ -1683,17 +1690,17 @@ int crypt_activate_by_passphrase(struct crypt_device *cd, /* provided passphrase, do not retry */ if (passphrase) { r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase, - passphrase_size, &cd->hdr, &mk, cd); + passphrase_size, &cd->hdr, &vk, cd); } else - r = volume_key_by_terminal_passphrase(cd, keyslot, &mk); + r = volume_key_by_terminal_passphrase(cd, keyslot, &vk); if (r >= 0) { keyslot = r; if (name) - r = open_from_hdr_and_mk(cd, mk, name, flags); + r = open_from_hdr_and_vk(cd, vk, name, flags); } - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); free(prompt); return r < 0 ? r : keyslot; @@ -1707,7 +1714,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd, uint32_t flags) { crypt_status_info ci; - struct luks_masterkey *mk = NULL; + struct volume_key *vk = NULL; char *passphrase_read = NULL; unsigned int passphrase_size_read; int r; @@ -1739,17 +1746,17 @@ int crypt_activate_by_keyfile(struct crypt_device *cd, r = -EINVAL; else { r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase_read, - passphrase_size_read, &cd->hdr, &mk, cd); + passphrase_size_read, &cd->hdr, &vk, cd); safe_free(passphrase_read); } if (r >= 0) { keyslot = r; if (name) - r = open_from_hdr_and_mk(cd, mk, name, flags); + r = open_from_hdr_and_vk(cd, vk, name, flags); } - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r < 0 ? r : keyslot; } @@ -1761,7 +1768,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, uint32_t flags) { crypt_status_info ci; - struct luks_masterkey *mk; + struct volume_key *vk; int r; log_dbg("Activating volume %s by volume key.", name); @@ -1770,7 +1777,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, if (isPLAIN(cd->type)) return create_device_helper(cd, name, NULL, cd->plain_cipher, cd->plain_cipher_mode, NULL, volume_key, volume_key_size, - cd->volume_key->keyLength, 0, cd->plain_hdr.skip, + cd->volume_key->keylength, 0, cd->plain_hdr.skip, cd->plain_hdr.offset, cd->plain_uuid, flags & CRYPT_ACTIVATE_READONLY, 0, 0); if (!isLUKS(cd->type)) { @@ -1788,18 +1795,18 @@ int crypt_activate_by_volume_key(struct crypt_device *cd, } } - mk = LUKS_alloc_masterkey(volume_key_size, volume_key); - if (!mk) + vk = crypt_alloc_volume_key(volume_key_size, volume_key); + if (!vk) return -ENOMEM; - r = LUKS_verify_master_key(&cd->hdr, mk); + r = LUKS_verify_volume_key(&cd->hdr, vk); if (r == -EPERM) log_err(cd, _("Volume key does not match the volume.\n")); if (!r && name) - r = open_from_hdr_and_mk(cd, mk, name, flags); + r = open_from_hdr_and_vk(cd, vk, name, flags); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r; } @@ -1847,7 +1854,7 @@ int crypt_volume_key_get(struct crypt_device *cd, const char *passphrase, size_t passphrase_size) { - struct luks_masterkey *mk; + struct volume_key *vk; char *processed_key = NULL; int r, key_len; @@ -1872,14 +1879,14 @@ int crypt_volume_key_get(struct crypt_device *cd, if (isLUKS(cd->type)) { r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase, - passphrase_size, &cd->hdr, &mk, cd); + passphrase_size, &cd->hdr, &vk, cd); if (r >= 0) { - memcpy(volume_key, mk->key, mk->keyLength); - *volume_key_size = mk->keyLength; + memcpy(volume_key, vk->key, vk->keylength); + *volume_key_size = vk->keylength; } - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r; } @@ -1891,7 +1898,7 @@ int crypt_volume_key_verify(struct crypt_device *cd, const char *volume_key, size_t volume_key_size) { - struct luks_masterkey *mk; + struct volume_key *vk; int r; if (!isLUKS(cd->type)) { @@ -1899,16 +1906,16 @@ int crypt_volume_key_verify(struct crypt_device *cd, return -EINVAL; } - mk = LUKS_alloc_masterkey(volume_key_size, volume_key); - if (!mk) + vk = crypt_alloc_volume_key(volume_key_size, volume_key); + if (!vk) return -ENOMEM; - r = LUKS_verify_master_key(&cd->hdr, mk); + r = LUKS_verify_volume_key(&cd->hdr, vk); if (r == -EPERM) log_err(cd, _("Volume key does not match the volume.\n")); - LUKS_dealloc_masterkey(mk); + crypt_free_volume_key(vk); return r; } @@ -2064,7 +2071,7 @@ const char *crypt_get_device_name(struct crypt_device *cd) int crypt_get_volume_key_size(struct crypt_device *cd) { if (isPLAIN(cd->type)) - return cd->volume_key->keyLength; + return cd->volume_key->keylength; if (isLUKS(cd->type)) return cd->hdr.keyBytes; diff --git a/lib/volumekey.c b/lib/volumekey.c new file mode 100644 index 0000000..5dec0bf --- /dev/null +++ b/lib/volumekey.c @@ -0,0 +1,67 @@ +/* + * cryptsetup volume key implementation + * + * Copyright (C) 2004-2006, Clemens Fruhwirth + * Copyright (C) 2010 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "internal.h" + +int getRandom(char *buf, size_t len); + +struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key) +{ + struct volume_key *vk = malloc(sizeof(*vk) + keylength); + + if (!vk) + return NULL; + + vk->keylength = keylength; + if (key) + memcpy(&vk->key, key, keylength); + + return vk; +} + +void crypt_free_volume_key(struct volume_key *vk) +{ + if (vk) { + memset(vk->key, 0, vk->keylength); + vk->keylength = 0; + free(vk); + } +} + +struct volume_key *crypt_generate_volume_key(unsigned keylength) +{ + int r; + struct volume_key *vk; + + vk = crypt_alloc_volume_key(keylength, NULL); + if (!vk) + return NULL; + + r = getRandom(vk->key, keylength); + if(r < 0) { + crypt_free_volume_key(vk); + return NULL; + } + return vk; +} + diff --git a/luks/Makefile.am b/luks/Makefile.am index 7ce43ca..cb78503 100644 --- a/luks/Makefile.am +++ b/luks/Makefile.am @@ -9,7 +9,6 @@ libluks_la_SOURCES = \ pbkdf.c \ keymanage.c \ keyencryption.c \ - hexprint.c \ random.c \ pbkdf.h \ random.h \ diff --git a/luks/hexprint.c b/luks/hexprint.c deleted file mode 100644 index 08b5707..0000000 --- a/luks/hexprint.c +++ /dev/null @@ -1,12 +0,0 @@ - -#include - -void hexprint(char *d, int n) -{ - int i; - for(i = 0; i < n; i++) - { - printf("%02hhx ", (char)d[i]); - } -} - diff --git a/luks/keymanage.c b/luks/keymanage.c index 1d1c21d..a95de1f 100644 --- a/luks/keymanage.c +++ b/luks/keymanage.c @@ -47,38 +47,6 @@ static inline int round_up_modulo(int x, int m) { return div_round_up(x, m) * m; } -struct luks_masterkey *LUKS_alloc_masterkey(int keylength, const char *key) -{ - struct luks_masterkey *mk=malloc(sizeof(*mk) + keylength); - if(NULL == mk) return NULL; - mk->keyLength=keylength; - if (key) - memcpy(&mk->key, key, keylength); - return mk; -} - -void LUKS_dealloc_masterkey(struct luks_masterkey *mk) -{ - if(NULL != mk) { - memset(mk->key,0,mk->keyLength); - mk->keyLength=0; - free(mk); - } -} - -struct luks_masterkey *LUKS_generate_masterkey(int keylength) -{ - struct luks_masterkey *mk=LUKS_alloc_masterkey(keylength, NULL); - if(NULL == mk) return NULL; - - int r = getRandom(mk->key,keylength); - if(r < 0) { - LUKS_dealloc_masterkey(mk); - return NULL; - } - return mk; -} - int LUKS_hdr_backup( const char *backup_file, const char *device, @@ -420,7 +388,7 @@ static int LUKS_PBKDF2_performance_check(const char *hashSpec, } int LUKS_generate_phdr(struct luks_phdr *header, - const struct luks_masterkey *mk, + const struct volume_key *vk, const char *cipherName, const char *cipherMode, const char *hashSpec, const char *uuid, unsigned int stripes, unsigned int alignPayload, @@ -430,7 +398,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, struct crypt_device *ctx) { unsigned int i=0; - unsigned int blocksPerStripeSet = div_round_up(mk->keyLength*stripes,SECTOR_SIZE); + unsigned int blocksPerStripeSet = div_round_up(vk->keylength*stripes,SECTOR_SIZE); int r; char luksMagic[] = LUKS_MAGIC; uuid_t partitionUuid; @@ -453,7 +421,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L); strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L); - header->keyBytes=mk->keyLength; + header->keyBytes=vk->keylength; LUKS_fix_header_compatible(header); @@ -475,7 +443,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, header->mkDigestIterations = at_least((uint32_t)(*PBKDF2_per_sec/1024) * iteration_time_ms, LUKS_MKD_ITERATIONS_MIN); - r = PBKDF2_HMAC(header->hashSpec,mk->key,mk->keyLength, + r = PBKDF2_HMAC(header->hashSpec,vk->key,vk->keylength, header->mkDigestSalt,LUKS_SALTSIZE, header->mkDigestIterations, header->mkDigest,LUKS_DIGESTSIZE); @@ -514,7 +482,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, int LUKS_set_key(const char *device, unsigned int keyIndex, const char *password, size_t passwordLen, - struct luks_phdr *hdr, struct luks_masterkey *mk, + struct luks_phdr *hdr, struct volume_key *vk, uint32_t iteration_time_ms, uint64_t *PBKDF2_per_sec, struct crypt_device *ctx) @@ -557,7 +525,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, r = getRandom(hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE); if(r < 0) return r; -// assert((mk->keyLength % TWOFISH_BLOCKSIZE) == 0); FIXME +// assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen, hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE, @@ -566,15 +534,15 @@ int LUKS_set_key(const char *device, unsigned int keyIndex, if(r < 0) return r; /* - * AF splitting, the masterkey stored in mk->key is splitted to AfMK + * AF splitting, the masterkey stored in vk->key is splitted to AfMK */ - AFEKSize = hdr->keyblock[keyIndex].stripes*mk->keyLength; + AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength; AfKey = (char *)malloc(AFEKSize); if(AfKey == NULL) return -ENOMEM; log_dbg("Using hash %s for AF in key slot %d, %d stripes", hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes); - r = AF_split(mk->key,AfKey,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); + r = AF_split(vk->key,AfKey,vk->keylength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); if(r < 0) goto out; log_dbg("Updating key slot %d [0x%04x] area on device %s.", keyIndex, @@ -607,13 +575,13 @@ out: return r; } -/* Check whether a master key is invalid. */ -int LUKS_verify_master_key(const struct luks_phdr *hdr, - const struct luks_masterkey *mk) +/* Check whether a volume key is invalid. */ +int LUKS_verify_volume_key(const struct luks_phdr *hdr, + const struct volume_key *vk) { char checkHashBuf[LUKS_DIGESTSIZE]; - if (PBKDF2_HMAC(hdr->hashSpec, mk->key, mk->keyLength, + if (PBKDF2_HMAC(hdr->hashSpec, vk->key, vk->keylength, hdr->mkDigestSalt, LUKS_SALTSIZE, hdr->mkDigestIterations, checkHashBuf, LUKS_DIGESTSIZE) < 0) @@ -631,7 +599,7 @@ static int LUKS_open_key(const char *device, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey *mk, + struct volume_key *vk, struct crypt_device *ctx) { crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); @@ -645,9 +613,9 @@ static int LUKS_open_key(const char *device, if (ki < CRYPT_SLOT_ACTIVE) return -ENOENT; - // assert((mk->keyLength % TWOFISH_BLOCKSIZE) == 0); FIXME + // assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME - AFEKSize = hdr->keyblock[keyIndex].stripes*mk->keyLength; + AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength; AfKey = (char *)malloc(AFEKSize); if(AfKey == NULL) return -ENOMEM; @@ -671,10 +639,10 @@ static int LUKS_open_key(const char *device, goto out; } - r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); + r = AF_merge(AfKey,vk->key,vk->keylength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); if(r < 0) goto out; - r = LUKS_verify_master_key(hdr, mk); + r = LUKS_verify_volume_key(hdr, vk); if (r >= 0) log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex); out: @@ -687,19 +655,19 @@ int LUKS_open_key_with_hdr(const char *device, const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey **mk, + struct volume_key **vk, struct crypt_device *ctx) { unsigned int i; int r; - *mk = LUKS_alloc_masterkey(hdr->keyBytes, NULL); + *vk = crypt_alloc_volume_key(hdr->keyBytes, NULL); if (keyIndex >= 0) - return LUKS_open_key(device, keyIndex, password, passwordLen, hdr, *mk, ctx); + return LUKS_open_key(device, keyIndex, password, passwordLen, hdr, *vk, ctx); for(i = 0; i < LUKS_NUMKEYS; i++) { - r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk, ctx); + r = LUKS_open_key(device, i, password, passwordLen, hdr, *vk, ctx); if(r == 0) return i; diff --git a/luks/luks.h b/luks/luks.h index 3ed95c0..e51efac 100644 --- a/luks/luks.h +++ b/luks/luks.h @@ -42,6 +42,8 @@ /* Any integer values are stored in network byte order on disk and must be converted */ +struct volume_key; + struct luks_phdr { char magic[LUKS_MAGIC_L]; uint16_t version; @@ -71,20 +73,12 @@ struct luks_phdr { char _padding[432]; }; -struct luks_masterkey { - size_t keyLength; - char key[]; -}; - -struct luks_masterkey *LUKS_alloc_masterkey(int keylength, const char *key); -void LUKS_dealloc_masterkey(struct luks_masterkey *mk); -struct luks_masterkey *LUKS_generate_masterkey(int keylength); -int LUKS_verify_master_key(const struct luks_phdr *hdr, - const struct luks_masterkey *mk); +int LUKS_verify_volume_key(const struct luks_phdr *hdr, + const struct volume_key *vk); int LUKS_generate_phdr( struct luks_phdr *header, - const struct luks_masterkey *mk, + const struct volume_key *vk, const char *cipherName, const char *cipherMode, const char *hashSpec, @@ -132,7 +126,7 @@ int LUKS_set_key( const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey *mk, + struct volume_key *vk, uint32_t iteration_time_ms, uint64_t *PBKDF2_per_sec, struct crypt_device *ctx); @@ -143,7 +137,7 @@ int LUKS_open_key_with_hdr( const char *password, size_t passwordLen, struct luks_phdr *hdr, - struct luks_masterkey **mk, + struct volume_key **vk, struct crypt_device *ctx); int LUKS_del_key(