From: Milan Broz Date: Sun, 30 Aug 2009 18:09:34 +0000 (+0000) Subject: * Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results. X-Git-Tag: upstream/1.6~733 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74b26c7b8a2b6f09c7e5030d89c225feb418cfd5;p=platform%2Fupstream%2Fcryptsetup.git * Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results. * Add ability to provide pre-generated master key and UUID in LUKS header format. * Add LUKS function to verify master key digest. * Move key slot manuipulation function into LUKS specific code. Signed-off-by: Milan Broz git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@94 36d66b0a-2a48-0410-832c-cd162a569da5 --- diff --git a/ChangeLog b/ChangeLog index 65ed80a..835c27b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ * Move device utils code and provide context parameter (for log). * Keyfile now must be provided by path, only stdin file descriptor is used (api only). * Do not call isatty() on closed keyfile descriptor. + * Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results. + * Add ability to provide pre-generated master key and UUID in LUKS header format. + * Add LUKS function to verify master key digest. + * Move key slot manuipulation function into LUKS specific code. 2009-08-17 Milan Broz * Fix PBKDF2 speed calculation for large passhrases. diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index afee144..7602136 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -6,6 +6,11 @@ extern "C" { #include +struct crypt_device; /* crypt device handle */ + +#define CRYPT_ANY_SLOT -1 + +typedef enum { SLOT_INVALID, SLOT_INACTIVE, SLOT_ACTIVE, SLOT_ACTIVE_LAST } crypt_keyslot_info; #define CRYPT_LOG_NORMAL 0 #define CRYPT_LOG_ERROR 1 @@ -16,7 +21,6 @@ struct interface_callbacks { void (*log)(int class, char *msg); }; - #define CRYPT_FLAG_VERIFY (1 << 0) #define CRYPT_FLAG_READONLY (1 << 1) #define CRYPT_FLAG_VERIFY_IF_POSSIBLE (1 << 2) @@ -33,9 +37,9 @@ struct crypt_options { const char *passphrase; int passphrase_fd; const char *key_file; - const char *new_key_file; + const char *new_key_file; int key_size; - + unsigned int flags; int key_slot; @@ -43,9 +47,9 @@ struct crypt_options { uint64_t offset; uint64_t skip; uint64_t iteration_time; - uint64_t timeout; + uint64_t timeout; - uint64_t align_payload; + uint64_t align_payload; int tries; struct interface_callbacks *icb; @@ -63,7 +67,6 @@ int crypt_luksRemoveKey(struct crypt_options *options); int crypt_luksAddKey(struct crypt_options *options); int crypt_luksUUID(struct crypt_options *options); int crypt_isLuks(struct crypt_options *options); -int crypt_luksFormat(struct crypt_options *options); int crypt_luksDump(struct crypt_options *options); void crypt_get_error(char *buf, size_t size); diff --git a/lib/setup.c b/lib/setup.c index 0cf2f0d..fb6aff7 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -250,8 +250,9 @@ static int luks_remove_helper(struct crypt_device *cd, int openedIndex; int r, last_slot; - if (!LUKS_device_ready(options->device, O_RDWR)) - return -ENOTBLK; + r = LUKS_read_phdr(options->device, &hdr, 1, cd); + if(r < 0) + return r; if(supply_it) { get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, @@ -260,7 +261,7 @@ static int luks_remove_helper(struct crypt_device *cd, r = -EINVAL; goto out; } - keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, cd); + keyIndex = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd); if(keyIndex < 0) { log_err(cd, "No remaining key available with this passphrase.\n"); r = -EPERM; goto out; @@ -276,7 +277,13 @@ static int luks_remove_helper(struct crypt_device *cd, } } - last_slot = LUKS_is_last_keyslot(options->device, keyIndex); + if (LUKS_keyslot_info(&hdr, keyIndex) == SLOT_INACTIVE) { + log_err(cd, _("Key %d not active. Can't wipe.\n"), keyIndex); + r = -EINVAL; + goto out; + } + + last_slot = (LUKS_keyslot_info(&hdr, keyIndex) == SLOT_ACTIVE_LAST); if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) { r = -EINVAL; goto out; } @@ -298,7 +305,7 @@ static int luks_remove_helper(struct crypt_device *cd, if(!last_slot) hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; - openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, cd); + openedIndex = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd); /* Clean up */ if (openedIndex >= 0) { LUKS_dealloc_masterkey(mk); @@ -429,10 +436,10 @@ int crypt_luksFormat(struct crypt_options *options) char cipherName[LUKS_CIPHERNAME_L]; char cipherMode[LUKS_CIPHERMODE_L]; unsigned int passwordLen; - unsigned int PBKDF2perSecond = 0; + uint64_t PBKDF2perSecond = 0; int r, keyIndex; - if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL)) + if (!device_ready(cd, options->device, O_RDWR | O_EXCL)) return -ENOTBLK; mk = LUKS_generate_masterkey(options->key_size); @@ -466,7 +473,7 @@ int crypt_luksFormat(struct crypt_options *options) return r; } - r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload, NULL); + r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, NULL, LUKS_STRIPES, options->align_payload, NULL); if(r < 0) return r; keyIndex = keyslot_from_option(NULL, options->key_slot, &header); @@ -474,13 +481,6 @@ int crypt_luksFormat(struct crypt_options *options) r = -EINVAL; goto out; } - r = LUKS_benchmarkt_iterations(options->hash, &PBKDF2perSecond); - if (r < 0) goto out; - - header.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000.0)); -#ifdef LUKS_DEBUG - logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations); -#endif get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, options->timeout, options->flags, NULL); if(!password) { @@ -492,7 +492,8 @@ int crypt_luksFormat(struct crypt_options *options) if(r < 0) goto out; /* Set key, also writes phdr */ - r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, NULL); + r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, + options->iteration_time, &PBKDF2perSecond, NULL); if(r < 0) goto out; r = 0; @@ -522,7 +523,7 @@ int crypt_luksOpen(struct crypt_options *options) return -EEXIST; } - if (!LUKS_device_ready(options->device, O_RDONLY | excl)) + if (!device_ready(cd, options->device, O_RDONLY | excl)) return -ENOTBLK; if (get_device_infos(options->device, &infos, cd) < 0) { @@ -557,7 +558,11 @@ start: r = -EINVAL; goto out; } - r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, cd); + r = LUKS_read_phdr(options->device, &hdr, 1, cd); + if(r < 0) + return r; + + r = LUKS_open_key_with_hdr(options->device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd); if (r == -EPERM) log_err(cd, "No key available with this passphrase.\n"); if (r < 0) @@ -628,11 +633,11 @@ int crypt_luksAddKey(struct crypt_options *options) struct luks_phdr hdr; char *password=NULL; unsigned int passwordLen; unsigned int keyIndex; - unsigned int PBKDF2perSecond = 0; + uint64_t PBKDF2perSecond = 0; const char *device = options->device; int r; - if (!LUKS_device_ready(options->device, O_RDWR)) + if (!device_ready(cd, options->device, O_RDWR)) return -ENOTBLK; r = LUKS_read_phdr(device, &hdr, 1, cd); @@ -655,7 +660,7 @@ int crypt_luksAddKey(struct crypt_options *options) if(!password) { r = -EINVAL; goto out; } - r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, cd); + r = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd); if(r < 0) { options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n"); r = -EPERM; goto out; @@ -673,11 +678,7 @@ int crypt_luksAddKey(struct crypt_options *options) r = -EINVAL; goto out; } - r = LUKS_benchmarkt_iterations(hdr.hashSpec, &PBKDF2perSecond); - if (r < 0) goto out; - hdr.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000)); - - r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, cd); + r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, options->iteration_time, &PBKDF2perSecond, cd); if(r < 0) goto out; r = 0; diff --git a/luks/keymanage.c b/luks/keymanage.c index f095afa..298e09f 100644 --- a/luks/keymanage.c +++ b/luks/keymanage.c @@ -2,7 +2,7 @@ * LUKS - Linux Unified Key Setup * * Copyright (C) 2004-2006, Clemens Fruhwirth - * + * * 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. @@ -16,17 +16,13 @@ * 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 #include +#include #include #include #include -#include -#include #include #include @@ -47,11 +43,13 @@ 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) +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; } @@ -66,7 +64,7 @@ void LUKS_dealloc_masterkey(struct luks_masterkey *mk) struct luks_masterkey *LUKS_generate_masterkey(int keylength) { - struct luks_masterkey *mk=LUKS_alloc_masterkey(keylength); + struct luks_masterkey *mk=LUKS_alloc_masterkey(keylength, NULL); if(NULL == mk) return NULL; int r = getRandom(mk->key,keylength); @@ -77,11 +75,10 @@ struct luks_masterkey *LUKS_generate_masterkey(int keylength) return mk; } -int LUKS_read_phdr( - const char *device, - struct luks_phdr *hdr, - int require_luks_device, - struct crypt_device *ctx) +int LUKS_read_phdr(const char *device, + struct luks_phdr *hdr, + int require_luks_device, + struct crypt_device *ctx) { int devfd = 0, r = 0; unsigned int i; @@ -137,10 +134,9 @@ int LUKS_read_phdr( return r; } -int LUKS_write_phdr( - const char *device, - struct luks_phdr *hdr, - struct crypt_device *ctx) +int LUKS_write_phdr(const char *device, + struct luks_phdr *hdr, + struct crypt_device *ctx) { int devfd = 0; unsigned int i; @@ -176,16 +172,22 @@ int LUKS_write_phdr( log_err(ctx, _("Error during update of LUKS header on device %s.\n"), device); close(devfd); + /* Re-read header from disk to be sure that in-memory and on-disk data are the same. */ + if (!r) { + r = LUKS_read_phdr(device, hdr, 1, ctx); + if (r) + log_err(ctx, _("Error re-reading LUKS header after update on device %s.\n"), device); + } + return r; } -int LUKS_generate_phdr( - struct luks_phdr *header, - const struct luks_masterkey *mk, - const char *cipherName, const char *cipherMode, const char *hashSpec, - unsigned int stripes, - unsigned int alignPayload, - struct crypt_device *ctx) +int LUKS_generate_phdr(struct luks_phdr *header, + const struct luks_masterkey *mk, + const char *cipherName, const char *cipherMode, const char *hashSpec, + const char *uuid, unsigned int stripes, + unsigned int alignPayload, + struct crypt_device *ctx) { unsigned int i=0; unsigned int blocksPerStripeSet = div_round_up(mk->keyLength*stripes,SECTOR_SIZE); @@ -241,7 +243,12 @@ int LUKS_generate_phdr( header->payloadOffset=currentSector; - uuid_generate(partitionUuid); + if (uuid && !uuid_parse(uuid, partitionUuid)) { + log_err(ctx, _("Wrong UUID format provided, generating new one.\n")); + uuid = NULL; + } + if (!uuid) + uuid_generate(partitionUuid); uuid_unparse(partitionUuid, header->uuid); log_dbg("Data offset %d, UUID %s", header->payloadOffset, header->uuid); @@ -249,14 +256,12 @@ int LUKS_generate_phdr( return 0; } -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 crypt_device *ctx) +int LUKS_set_key(const char *device, unsigned int keyIndex, + const char *password, size_t passwordLen, + struct luks_phdr *hdr, struct luks_masterkey *mk, + uint32_t iteration_time_ms, + uint64_t *PBKDF2_per_sec, + struct crypt_device *ctx) { char derivedKey[hdr->keyBytes]; char *AfKey; @@ -274,6 +279,21 @@ int LUKS_set_key( return -EINVAL; } + log_dbg("Calculating data for key slot %d", keyIndex); + + if (!*PBKDF2_per_sec) { + if (PBKDF2_performance_check(hdr->hashSpec, PBKDF2_per_sec) < 0) { + log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s)."), hdr->hashSpec); + return -EINVAL; + } + log_dbg("PBKDF2: %" PRIu64 " iterations per second using hash %s.", *PBKDF2_per_sec, hdr->hashSpec); + } + + /* Avoid floating point operation - don't tell anyone that second have no 1024 miliseconds :-) */ + iteration_time_ms = at_least_one(iteration_time_ms / 1024); + hdr->keyblock[keyIndex].passwordIterations = at_least_one((uint32_t)(*PBKDF2_per_sec/2) * iteration_time_ms); + log_dbg("Key slot %d use %d password iterations.", keyIndex, hdr->keyblock[keyIndex].passwordIterations); + r = getRandom(hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE); if(r < 0) return r; @@ -315,7 +335,9 @@ int LUKS_set_key( } /* Mark the key as active in phdr */ - hdr->keyblock[keyIndex].active = LUKS_KEY_ENABLED; + r = LUKS_keyslot_set(hdr, (int)keyIndex, 1); + if(r < 0) goto out; + r = LUKS_write_phdr(device, hdr, ctx); if(r < 0) goto out; @@ -325,25 +347,43 @@ 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) +{ + char checkHashBuf[LUKS_DIGESTSIZE]; + + if (PBKDF2_HMAC(hdr->hashSpec, mk->key, mk->keyLength, + hdr->mkDigestSalt, LUKS_SALTSIZE, + hdr->mkDigestIterations, checkHashBuf, + LUKS_DIGESTSIZE) < 0) + return -EINVAL; + + if (memcmp(checkHashBuf, hdr->mkDigest, LUKS_DIGESTSIZE)) + return -EPERM; + + return 0; +} + /* Try to open a particular key slot */ -int LUKS_open_key( - const char *device, - unsigned int keyIndex, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey *mk, - struct crypt_device *ctx) +int LUKS_open_key(const char *device, + unsigned int keyIndex, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey *mk, + struct crypt_device *ctx) { + crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); char derivedKey[hdr->keyBytes]; char *AfKey; size_t AFEKSize; - char checkHashBuf[LUKS_DIGESTSIZE]; int r; - if(hdr->keyblock[keyIndex].active != LUKS_KEY_ENABLED) { + log_dbg("Trying to open key slot %d [%d].", keyIndex, (int)ki); + + if (ki < SLOT_ACTIVE) return -ENOENT; - } // assert((mk->keyLength % TWOFISH_BLOCKSIZE) == 0); FIXME @@ -374,13 +414,7 @@ int LUKS_open_key( r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec); if(r < 0) goto out; - r = PBKDF2_HMAC(hdr->hashSpec,mk->key,mk->keyLength, - hdr->mkDigestSalt,LUKS_SALTSIZE, - hdr->mkDigestIterations, - checkHashBuf,LUKS_DIGESTSIZE); - if(r < 0) goto out; - - r = (memcmp(checkHashBuf,hdr->mkDigest, LUKS_DIGESTSIZE) == 0)?0:-EPERM; + r = LUKS_verify_master_key(hdr, mk); if (r >= 0) log_std(ctx, _("Key slot %d unlocked.\n"), keyIndex); out: @@ -388,36 +422,23 @@ out: return r; } -/* Tries to open any key from a given LUKS device reading the header on its own */ -int LUKS_open_any_key( - const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **mk, - struct crypt_device *ctx) +int LUKS_open_key_with_hdr(const char *device, + int keyIndex, + const char *password, + size_t passwordLen, + struct luks_phdr *hdr, + struct luks_masterkey **mk, + struct crypt_device *ctx) { + unsigned int i; int r; - r = LUKS_read_phdr(device, hdr, 1, ctx); - if(r < 0) - return r; - return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk, ctx); -} + *mk = LUKS_alloc_masterkey(hdr->keyBytes, NULL); -int LUKS_open_any_key_with_hdr( - const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **mk, - struct crypt_device *ctx) -{ - unsigned int i; - int r; + if (keyIndex >= 0) + return LUKS_open_key(device, keyIndex, password, passwordLen, hdr, *mk, ctx); - *mk=LUKS_alloc_masterkey(hdr->keyBytes); - for(i=0; i= LUKS_NUMKEYS || hdr.keyblock[keyIndex].active != LUKS_KEY_ENABLED) { + if (r) + return r; + + r = LUKS_keyslot_set(&hdr, keyIndex, 0); + if (r) { log_err(ctx, _("Key slot %d is invalid, please select keyslot between 0 and %d.\n"), keyIndex, LUKS_NUMKEYS - 1); - r = -ENOENT; - } else { - /* secure deletion of key material */ - startOffset = hdr.keyblock[keyIndex].keyMaterialOffset; - stripesLen = hdr.keyBytes * hdr.keyblock[keyIndex].stripes; - endOffset = startOffset + div_round_up(stripesLen, SECTOR_SIZE); - - r = wipe(device, startOffset, endOffset); - if(r == 0) { - /* mark the key as inactive in header */ - hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED; - r = LUKS_write_phdr(device, &hdr, ctx); - } + return r; } + /* secure deletion of key material */ + startOffset = hdr.keyblock[keyIndex].keyMaterialOffset; + stripesLen = hdr.keyBytes * hdr.keyblock[keyIndex].stripes; + endOffset = startOffset + div_round_up(stripesLen, SECTOR_SIZE); + + r = wipe(device, startOffset, endOffset); + if (r) { + log_err(ctx, _("Cannot wipe device %s.\n"), device); + return r; + } + + r = LUKS_write_phdr(device, &hdr, ctx); + return r; } -int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex) +crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot) { - struct luks_phdr hdr; - unsigned int i; - int r; + int i; - r = LUKS_read_phdr(device, &hdr, 1, NULL); - if(r < 0) return r; + if(keyslot >= LUKS_NUMKEYS || keyslot < 0) + return SLOT_INVALID; - for(i = 0; i < LUKS_NUMKEYS; i++) { - if(i != keyIndex && hdr.keyblock[i].active == LUKS_KEY_ENABLED) - return 0; - } - return 1; + if (hdr->keyblock[keyslot].active == LUKS_KEY_DISABLED) + return SLOT_INACTIVE; + + if (hdr->keyblock[keyslot].active != LUKS_KEY_ENABLED) + return SLOT_INVALID; + + for(i = 0; i < LUKS_NUMKEYS; i++) + if(i != keyslot && hdr->keyblock[i].active == LUKS_KEY_ENABLED) + return SLOT_ACTIVE; + + return SLOT_ACTIVE_LAST; } -int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count) +int LUKS_keyslot_find_empty(struct luks_phdr *hdr) { - if (PBKDF2_performance_check(hash, count) < 0) { - set_error(_("Not compatible options (using hash algorithm %s)."), hash); + int i; + + for (i = 0; i < LUKS_NUMKEYS; i++) + if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) + break; + + if (i == LUKS_NUMKEYS) return -EINVAL; - } - *count /= 2; - return 0; + return i; } -int LUKS_device_ready(const char *device, int mode) +int LUKS_keyslot_active_count(struct luks_phdr *hdr) { - int devfd; - struct stat st; + int i, num = 0; - if(stat(device, &st) < 0) { - set_error(_("Device %s doesn't exist or access denied."), device); - return 0; - } + for (i = 0; i < LUKS_NUMKEYS; i++) + if(hdr->keyblock[i].active == LUKS_KEY_ENABLED) + num++; - devfd = open(device, mode | O_DIRECT | O_SYNC); - if(devfd < 0) { - set_error(_("Can't open device %s for %s%saccess."), device, - (mode & O_EXCL)?_("exclusive "):"", - (mode & O_RDWR)?_("writable "):"read-only "); - return 0; - } - close(devfd); + return num; +} + +int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable) +{ + crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyslot); + + if (ki == SLOT_INVALID) + return -EINVAL; - return 1; + hdr->keyblock[keyslot].active = enable ? LUKS_KEY_ENABLED : LUKS_KEY_DISABLED; + log_dbg("Key slot %d was %s in LUKS header.", keyslot, enable ? "enabled" : "disabled"); + return 0; } diff --git a/luks/luks.h b/luks/luks.h index ab5b575..c433bc5 100644 --- a/luks/luks.h +++ b/luks/luks.h @@ -5,10 +5,7 @@ * LUKS partition header */ -#include -#include #include "libcryptsetup.h" -#include "internal.h" #define LUKS_CIPHERNAME_L 32 #define LUKS_CIPHERMODE_L 32 @@ -78,16 +75,19 @@ struct luks_masterkey { char key[]; }; -struct luks_masterkey *LUKS_alloc_masterkey(int keylength); - +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_generate_phdr( struct luks_phdr *header, const struct luks_masterkey *mk, - const char *cipherName, const char *cipherMode, const char *hashSpec, + const char *cipherName, + const char *cipherMode, + const char *hashSpec, + const char *uuid, unsigned int stripes, unsigned int alignPayload, struct crypt_device *ctx); @@ -110,6 +110,8 @@ int LUKS_set_key( size_t passwordLen, struct luks_phdr *hdr, struct luks_masterkey *mk, + uint32_t iteration_time_ms, + uint64_t *PBKDF2_per_sec, struct crypt_device *ctx); int LUKS_open_key( @@ -121,16 +123,9 @@ int LUKS_open_key( struct luks_masterkey *mk, struct crypt_device *ctx); -int LUKS_open_any_key( - const char *device, - const char *password, - size_t passwordLen, - struct luks_phdr *hdr, - struct luks_masterkey **mk, - struct crypt_device *ctx); - -int LUKS_open_any_key_with_hdr( +int LUKS_open_key_with_hdr( const char *device, + int keyIndex, const char *password, size_t passwordLen, struct luks_phdr *hdr, @@ -142,8 +137,10 @@ int LUKS_del_key( unsigned int keyIndex, struct crypt_device *ctx); -int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex); -int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count); +crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot); +int LUKS_keyslot_find_empty(struct luks_phdr *hdr); +int LUKS_keyslot_active_count(struct luks_phdr *hdr); +int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable); int LUKS_encrypt_to_storage( char *src, size_t srcLength, @@ -161,5 +158,4 @@ int LUKS_decrypt_from_storage( unsigned int sector, struct crypt_device *ctx); -int LUKS_device_ready(const char *device, int mode); #endif diff --git a/luks/pbkdf.c b/luks/pbkdf.c index 9581095..15c2de1 100644 --- a/luks/pbkdf.c +++ b/luks/pbkdf.c @@ -29,14 +29,14 @@ #include #include -static volatile unsigned int __PBKDF2_global_j = 0; -static volatile unsigned int __PBKDF2_performance = 0; +static volatile uint64_t __PBKDF2_global_j = 0; +static volatile uint64_t __PBKDF2_performance = 0; static int init_crypto(void) { if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) { - if (!gcry_check_version (GCRYPT_VERSION)) - return -ENOSYS; + //if (!gcry_check_version (GCRYPT_VERSION)) + // return -ENOSYS; gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); gcry_control (GCRYCTL_RESUME_SECMEM_WARN); @@ -219,7 +219,7 @@ static int pkcs5_pbkdf2(const char *hash, } if (perfcheck) - __PBKDF2_global_j--; + __PBKDF2_global_j++; } memcpy(DK + (i - 1) * hLen, T, (uint) i == l ? r : hLen); @@ -255,21 +255,18 @@ int PBKDF2_HMAC_ready(const char *hash) static void sigvtalarm(int foo) { - __PBKDF2_performance = ~(0U) - __PBKDF2_global_j; - __PBKDF2_global_j = 0; + __PBKDF2_performance = __PBKDF2_global_j; } /* This code benchmarks PBKDF2 and returns iterations/second using wth specified hash */ -int PBKDF2_performance_check(const char *hash, unsigned int *iter) +int PBKDF2_performance_check(const char *hash, uint64_t *iter) { int r; char buf; struct itimerval it; - if(__PBKDF2_performance != 0) { - *iter = __PBKDF2_performance; - return 0; - } + if (__PBKDF2_global_j) + return -EBUSY; if (!PBKDF2_HMAC_ready(hash)) return -EINVAL; @@ -284,8 +281,8 @@ int PBKDF2_performance_check(const char *hash, unsigned int *iter) r = pkcs5_pbkdf2(hash, "foo", 3, "bar", 3, ~(0U), 1, &buf, 1); - __PBKDF2_global_j = 0; - *iter = __PBKDF2_performance; + __PBKDF2_global_j = 0; + __PBKDF2_performance = 0; return r; } diff --git a/luks/pbkdf.h b/luks/pbkdf.h index 1488dec..ae602fe 100644 --- a/luks/pbkdf.h +++ b/luks/pbkdf.h @@ -11,7 +11,7 @@ int PBKDF2_HMAC(const char *hash, char *dKey, size_t dKeyLen); -int PBKDF2_performance_check(const char *hash, unsigned int *iter); +int PBKDF2_performance_check(const char *hash, uint64_t *iter); int PBKDF2_HMAC_ready(const char *hash); #endif