Use struct volume key thorough.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@571 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
Milan Broz
2011-07-17 22:35:30 +00:00
parent 913ef7c07e
commit 39e6cfcb8a
8 changed files with 60 additions and 63 deletions

View File

@@ -239,16 +239,16 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
} }
static char *get_params(const char *device, uint64_t skip, uint64_t offset, static char *get_params(const char *device, uint64_t skip, uint64_t offset,
const char *cipher, size_t key_size, const char *key) const char *cipher, struct volume_key *vk)
{ {
char *params; char *params;
char *hexkey; char *hexkey;
hexkey = crypt_safe_alloc(key_size * 2 + 1); hexkey = crypt_safe_alloc(vk->keylength * 2 + 1);
if (!hexkey) if (!hexkey)
return NULL; return NULL;
hex_key(hexkey, key_size, key); hex_key(hexkey, vk->keylength, vk->key);
params = crypt_safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64); params = crypt_safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64);
if (!params) if (!params)
@@ -411,7 +411,7 @@ int dm_create_device(const char *name,
uint16_t udev_flags = 0; uint16_t udev_flags = 0;
params = get_params(dmd->device, dmd->iv_offset, dmd->offset, params = get_params(dmd->device, dmd->iv_offset, dmd->offset,
dmd->cipher, dmd->key_size, dmd->key); dmd->cipher, dmd->vk);
if (!params) if (!params)
goto out_no_removal; goto out_no_removal;
@@ -641,24 +641,21 @@ int dm_query_device(const char *name, uint32_t get_flags,
goto out; goto out;
dmd->offset = val64; dmd->offset = val64;
/* key_size */ if (get_flags & DM_ACTIVE_KEY) {
dmd->key_size = strlen(key_) / 2; dmd->vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
if (!dmd->vk) {
/* key */
if (dmd->key_size && (get_flags & DM_ACTIVE_KEY)) {
dmd->key = crypt_safe_alloc(dmd->key_size);
if (!dmd->key) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
buffer[2] = '\0'; buffer[2] = '\0';
for(i = 0; i < dmd->key_size; i++) { for(i = 0; i < dmd->vk->keylength; i++) {
memcpy(buffer, &key_[i * 2], 2); memcpy(buffer, &key_[i * 2], 2);
dmd->key[i] = strtoul(buffer, &endp, 16); dmd->vk->key[i] = strtoul(buffer, &endp, 16);
if (endp != &buffer[2]) { if (endp != &buffer[2]) {
crypt_safe_free(dmd->key); crypt_free_volume_key(dmd->vk);
dmd->key = NULL; dmd->vk = NULL;
r = -EINVAL;
goto out; goto out;
} }
} }

View File

@@ -195,8 +195,7 @@ int LOOPAES_activate(struct crypt_device *cd,
.device = crypt_get_device_name(cd), .device = crypt_get_device_name(cd),
.cipher = NULL, .cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.key = vk->key, .vk = vk,
.key_size = vk->keylength,
.offset = crypt_get_data_offset(cd), .offset = crypt_get_data_offset(cd),
.iv_offset = skip, .iv_offset = skip,
.size = 0, .size = 0,

View File

@@ -4,6 +4,9 @@
#include <unistd.h> #include <unistd.h>
#include "config.h" #include "config.h"
struct crypt_device;
struct volume_key;
#define LOOPAES_KEYS_MAX 65 #define LOOPAES_KEYS_MAX 65
int LOOPAES_parse_keyfile(struct crypt_device *cd, int LOOPAES_parse_keyfile(struct crypt_device *cd,

View File

@@ -51,7 +51,7 @@ static int devfd=-1;
static int setup_mapping(const char *cipher, const char *name, static int setup_mapping(const char *cipher, const char *name,
const char *device, const char *device,
const char *key, size_t keyLength, struct volume_key *vk,
unsigned int sector, size_t srcLength, unsigned int sector, size_t srcLength,
int mode, struct crypt_device *ctx) int mode, struct crypt_device *ctx)
{ {
@@ -60,8 +60,7 @@ static int setup_mapping(const char *cipher, const char *name,
.device = device, .device = device,
.cipher = cipher, .cipher = cipher,
.uuid = NULL, .uuid = NULL,
.key = (char*)key, .vk = vk,
.key_size = keyLength,
.offset = sector, .offset = sector,
.iv_offset = 0, .iv_offset = 0,
.size = 0, .size = 0,
@@ -128,7 +127,7 @@ static const char *_error_hint(char *cipherMode, size_t keyLength)
handler and global vars for cleaning */ handler and global vars for cleaning */
static int LUKS_endec_template(char *src, size_t srcLength, static int LUKS_endec_template(char *src, size_t srcLength,
struct luks_phdr *hdr, struct luks_phdr *hdr,
char *key, size_t keyLength, struct volume_key *vk,
const char *device, const char *device,
unsigned int sector, unsigned int sector,
ssize_t (*func)(int, void *, size_t), ssize_t (*func)(int, void *, size_t),
@@ -156,12 +155,12 @@ static int LUKS_endec_template(char *src, size_t srcLength,
cleaner_name = name; cleaner_name = name;
r = setup_mapping(dmCipherSpec, name, device, r = setup_mapping(dmCipherSpec, name, device,
key, keyLength, sector, srcLength, mode, ctx); vk, sector, srcLength, mode, ctx);
if(r < 0) { if(r < 0) {
log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n" log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n"
"Check that kernel supports %s cipher (check syslog for more info).\n%s"), "Check that kernel supports %s cipher (check syslog for more info).\n%s"),
device, dmCipherSpec, device, dmCipherSpec,
_error_hint(hdr->cipherMode, keyLength * 8)); _error_hint(hdr->cipherMode, vk->keylength * 8));
r = -EIO; r = -EIO;
goto out1; goto out1;
} }
@@ -198,22 +197,22 @@ static int LUKS_endec_template(char *src, size_t srcLength,
int LUKS_encrypt_to_storage(char *src, size_t srcLength, int LUKS_encrypt_to_storage(char *src, size_t srcLength,
struct luks_phdr *hdr, struct luks_phdr *hdr,
char *key, size_t keyLength, struct volume_key *vk,
const char *device, const char *device,
unsigned int sector, unsigned int sector,
struct crypt_device *ctx) struct crypt_device *ctx)
{ {
return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, return LUKS_endec_template(src,srcLength,hdr,vk, device,
sector, write_blockwise, O_RDWR, ctx); sector, write_blockwise, O_RDWR, ctx);
} }
int LUKS_decrypt_from_storage(char *dst, size_t dstLength, int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
struct luks_phdr *hdr, struct luks_phdr *hdr,
char *key, size_t keyLength, struct volume_key *vk,
const char *device, const char *device,
unsigned int sector, unsigned int sector,
struct crypt_device *ctx) struct crypt_device *ctx)
{ {
return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, return LUKS_endec_template(dst,dstLength,hdr,vk, device,
sector, read_blockwise, O_RDONLY, ctx); sector, read_blockwise, O_RDONLY, ctx);
} }

View File

@@ -29,6 +29,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <assert.h>
#include <uuid/uuid.h> #include <uuid/uuid.h>
#include "luks.h" #include "luks.h"
@@ -525,7 +526,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
uint64_t *PBKDF2_per_sec, uint64_t *PBKDF2_per_sec,
struct crypt_device *ctx) struct crypt_device *ctx)
{ {
char derivedKey[hdr->keyBytes]; struct volume_key *derived_key;
char *AfKey = NULL; char *AfKey = NULL;
unsigned int AFEKSize; unsigned int AFEKSize;
uint64_t PBKDF2_temp; uint64_t PBKDF2_temp;
@@ -560,23 +561,26 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
log_dbg("Key slot %d use %d password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations); log_dbg("Key slot %d use %d password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations);
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!derived_key)
return -ENOMEM;
r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt, r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt,
LUKS_SALTSIZE, CRYPT_RND_NORMAL); LUKS_SALTSIZE, CRYPT_RND_NORMAL);
if (r < 0) if (r < 0)
return r; return r;
// assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen, r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE, hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
hdr->keyblock[keyIndex].passwordIterations, hdr->keyblock[keyIndex].passwordIterations,
derivedKey, hdr->keyBytes); derived_key->key, hdr->keyBytes);
if (r < 0) if (r < 0)
goto out; goto out;
/* /*
* AF splitting, the masterkey stored in vk->key is split to AfKey * AF splitting, the masterkey stored in vk->key is split to AfKey
*/ */
assert(vk->keylength == hdr->keyBytes);
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength; AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
AfKey = crypt_safe_alloc(AFEKSize); AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) { if (!AfKey) {
@@ -596,8 +600,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
r = LUKS_encrypt_to_storage(AfKey, r = LUKS_encrypt_to_storage(AfKey,
AFEKSize, AFEKSize,
hdr, hdr,
derivedKey, derived_key,
hdr->keyBytes,
device, device,
hdr->keyblock[keyIndex].keyMaterialOffset, hdr->keyblock[keyIndex].keyMaterialOffset,
ctx); ctx);
@@ -619,7 +622,7 @@ int LUKS_set_key(const char *device, unsigned int keyIndex,
r = 0; r = 0;
out: out:
crypt_safe_free(AfKey); crypt_safe_free(AfKey);
memset(derivedKey, 0, sizeof(derivedKey)); crypt_free_volume_key(derived_key);
return r; return r;
} }
@@ -651,7 +654,7 @@ static int LUKS_open_key(const char *device,
struct crypt_device *ctx) struct crypt_device *ctx)
{ {
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
char derivedKey[hdr->keyBytes]; struct volume_key *derived_key;
char *AfKey; char *AfKey;
size_t AFEKSize; size_t AFEKSize;
int r; int r;
@@ -662,8 +665,11 @@ static int LUKS_open_key(const char *device,
if (ki < CRYPT_SLOT_ACTIVE) if (ki < CRYPT_SLOT_ACTIVE)
return -ENOENT; return -ENOENT;
// assert((vk->keylength % TWOFISH_BLOCKSIZE) == 0); FIXME derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!derived_key)
return -ENOMEM;
assert(vk->keylength == hdr->keyBytes);
AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength; AFEKSize = hdr->keyblock[keyIndex].stripes*vk->keylength;
AfKey = crypt_safe_alloc(AFEKSize); AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) if (!AfKey)
@@ -672,7 +678,7 @@ static int LUKS_open_key(const char *device,
r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen, r = PBKDF2_HMAC(hdr->hashSpec, password,passwordLen,
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE, hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
hdr->keyblock[keyIndex].passwordIterations, hdr->keyblock[keyIndex].passwordIterations,
derivedKey, hdr->keyBytes); derived_key->key, hdr->keyBytes);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -680,8 +686,7 @@ static int LUKS_open_key(const char *device,
r = LUKS_decrypt_from_storage(AfKey, r = LUKS_decrypt_from_storage(AfKey,
AFEKSize, AFEKSize,
hdr, hdr,
derivedKey, derived_key,
hdr->keyBytes,
device, device,
hdr->keyblock[keyIndex].keyMaterialOffset, hdr->keyblock[keyIndex].keyMaterialOffset,
ctx); ctx);
@@ -699,7 +704,7 @@ static int LUKS_open_key(const char *device,
log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex); log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex);
out: out:
crypt_safe_free(AfKey); crypt_safe_free(AfKey);
memset(derivedKey, 0, sizeof(derivedKey)); crypt_free_volume_key(derived_key);
return r; return r;
} }
@@ -909,8 +914,7 @@ int LUKS1_activate(struct crypt_device *cd,
.device = crypt_get_device_name(cd), .device = crypt_get_device_name(cd),
.cipher = NULL, .cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.key = vk->key, .vk = vk,
.key_size = vk->keylength,
.offset = crypt_get_data_offset(cd), .offset = crypt_get_data_offset(cd),
.iv_offset = 0, .iv_offset = 0,
.size = 0, .size = 0,

View File

@@ -160,7 +160,7 @@ int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable);
int LUKS_encrypt_to_storage( int LUKS_encrypt_to_storage(
char *src, size_t srcLength, char *src, size_t srcLength,
struct luks_phdr *hdr, struct luks_phdr *hdr,
char *key, size_t keyLength, struct volume_key *vk,
const char *device, const char *device,
unsigned int sector, unsigned int sector,
struct crypt_device *ctx); struct crypt_device *ctx);
@@ -168,7 +168,7 @@ int LUKS_encrypt_to_storage(
int LUKS_decrypt_from_storage( int LUKS_decrypt_from_storage(
char *dst, size_t dstLength, char *dst, size_t dstLength,
struct luks_phdr *hdr, struct luks_phdr *hdr,
char *key, size_t keyLength, struct volume_key *vk,
const char *device, const char *device,
unsigned int sector, unsigned int sector,
struct crypt_device *ctx); struct crypt_device *ctx);

View File

@@ -225,8 +225,7 @@ int PLAIN_activate(struct crypt_device *cd,
.device = crypt_get_device_name(cd), .device = crypt_get_device_name(cd),
.cipher = NULL, .cipher = NULL,
.uuid = crypt_get_uuid(cd), .uuid = crypt_get_uuid(cd),
.key = vk->key, .vk = vk,
.key_size = vk->keylength,
.offset = crypt_get_data_offset(cd), .offset = crypt_get_data_offset(cd),
.iv_offset = iv_offset, .iv_offset = iv_offset,
.size = size, .size = size,
@@ -527,11 +526,8 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
(*cd)->plain_hdr.hash = NULL; /* no way to get this */ (*cd)->plain_hdr.hash = NULL; /* no way to get this */
(*cd)->plain_hdr.offset = dmd.offset; (*cd)->plain_hdr.offset = dmd.offset;
(*cd)->plain_hdr.skip = dmd.iv_offset; (*cd)->plain_hdr.skip = dmd.iv_offset;
(*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key); (*cd)->volume_key = dmd.vk;
if (!(*cd)->volume_key) { dmd.vk = NULL;
r = -ENOMEM;
goto out;
}
r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode);
if (!r) { if (!r) {
@@ -549,23 +545,20 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
(*cd)->loopaes_cipher = strdup(cipher); (*cd)->loopaes_cipher = strdup(cipher);
(*cd)->loopaes_cipher_mode = strdup(cipher_mode); (*cd)->loopaes_cipher_mode = strdup(cipher_mode);
/* version 3 uses last key for IV */ /* version 3 uses last key for IV */
if (dmd.key_size % key_nums) if (dmd.vk->keylength % key_nums)
key_nums++; key_nums++;
(*cd)->loopaes_key_size = dmd.key_size / key_nums; (*cd)->loopaes_key_size = dmd.vk->keylength / key_nums;
} }
} else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1)) { } else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1)) {
if (dmd.device) { if (dmd.device) {
if (crypt_load(*cd, CRYPT_LUKS1, NULL) < 0 || if (crypt_load(*cd, CRYPT_LUKS1, NULL) < 0 ||
crypt_volume_key_verify(*cd, dmd.key, dmd.key_size) < 0) { crypt_volume_key_verify(*cd, dmd.vk->key, dmd.vk->keylength) < 0) {
log_dbg("LUKS device header does not match active device."); log_dbg("LUKS device header does not match active device.");
goto out; goto out;
} }
(*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key); (*cd)->volume_key = dmd.vk;
if (!(*cd)->volume_key) { dmd.vk = NULL;
r = -ENOMEM;
goto out;
}
} }
} }
} else } else
@@ -576,7 +569,7 @@ out:
crypt_free(*cd); crypt_free(*cd);
*cd = NULL; *cd = NULL;
} }
crypt_safe_free(dmd.key); crypt_free_volume_key(dmd.vk);
free((char*)dmd.device); free((char*)dmd.device);
free((char*)dmd.cipher); free((char*)dmd.cipher);
free((char*)dmd.uuid); free((char*)dmd.uuid);
@@ -826,7 +819,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
r = dm_create_device(name, cd->type, &dmd, 1); r = dm_create_device(name, cd->type, &dmd, 1);
} }
out: out:
crypt_safe_free(dmd.key); crypt_free_volume_key(dmd.vk);
free((char*)dmd.cipher); free((char*)dmd.cipher);
free((char*)dmd.device); free((char*)dmd.device);
free((char*)dmd.uuid); free((char*)dmd.uuid);

View File

@@ -5,6 +5,7 @@
#include <inttypes.h> #include <inttypes.h>
struct crypt_device; struct crypt_device;
struct volume_key;
/* Device mapper backend - kernel support flags */ /* Device mapper backend - kernel support flags */
#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */ #define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */
@@ -28,8 +29,9 @@ struct crypt_dm_active_device {
const char *device; const char *device;
const char *cipher; const char *cipher;
const char *uuid; const char *uuid;
char *key;
size_t key_size; /* Active key for device */
struct volume_key *vk;
/* struct crypt_active_device */ /* struct crypt_active_device */
uint64_t offset; /* offset in sectors */ uint64_t offset; /* offset in sectors */