Add required parameters for changing hash used in LUKS key setup scheme.
authorMilan Broz <gmazyland@gmail.com>
Thu, 30 Jul 2009 14:57:52 +0000 (14:57 +0000)
committerMilan Broz <gmazyland@gmail.com>
Thu, 30 Jul 2009 14:57:52 +0000 (14:57 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@80 36d66b0a-2a48-0410-832c-cd162a569da5

ChangeLog
lib/setup.c
luks/keymanage.c
luks/luks.h
src/cryptsetup.c
src/cryptsetup.h

index ce82339..d3532c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
        * Remove po/cryptsetup-luks.pot, it's autogenerated.
        * Return ENOENT for empty keyslots, EINVAL will be used later for other type of error.
        * Switch PBKDF2 from internal SHA1 to libgcrypt, make hash algorithm not hardcoded to SHA1 here.
+       * Add required parameters for changing hash used in LUKS key setup scheme.
 
 2009-07-28  Milan Broz  <mbroz@redhat.com>
        * Pad luks header to 512 sector size.
index 7c3641b..601ddf2 100644 (file)
@@ -447,7 +447,7 @@ static int __crypt_luks_format(int arg, struct setup_backend *backend, struct cr
        char cipherName[LUKS_CIPHERNAME_L];
        char cipherMode[LUKS_CIPHERMODE_L];
        unsigned int passwordLen;
-       int PBKDF2perSecond;
+       unsigned int PBKDF2perSecond = 0;
         int keyIndex;
 
        if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL))
@@ -482,18 +482,17 @@ static int __crypt_luks_format(int arg, struct setup_backend *backend, struct cr
        r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode);
        if(r < 0) return r;
 
-       r = LUKS_generate_phdr(&header,mk,cipherName, cipherMode,LUKS_STRIPES, options->align_payload);
-       if(r < 0) {
-               set_error("Can't generate phdr");
-               return r; 
+       r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload);
+       if(r < 0) return r;
+
+       keyIndex = keyslot_from_option(options->key_slot, &header, options);
+       if(keyIndex == -EINVAL) {
+               r = -EINVAL; goto out;
        }
 
-        keyIndex = keyslot_from_option(options->key_slot, &header, options);
-        if(keyIndex == -EINVAL) {
-                r = -EINVAL; goto out;
-        }
+       r = LUKS_benchmarkt_iterations(options->hash, &PBKDF2perSecond);
+       if (r < 0) goto out;
 
-       PBKDF2perSecond = LUKS_benchmarkt_iterations();
        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);
@@ -617,7 +616,8 @@ static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct c
        struct luks_masterkey *mk=NULL;
        struct luks_phdr hdr;
        char *password=NULL; unsigned int passwordLen;
-        unsigned int keyIndex;
+       unsigned int keyIndex;
+       unsigned int PBKDF2perSecond = 0;
        const char *device = options->device;
        int r;
 
@@ -666,9 +666,11 @@ static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct c
                r = -EINVAL; goto out;
        }
 
-       hdr.keyblock[keyIndex].passwordIterations = at_least_one(LUKS_benchmarkt_iterations() * ((float)options->iteration_time / 1000));
+       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, backend);
+       r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
        if(r < 0) goto out;
 
        r = 0;
index 6011b90..aba9fe2 100644 (file)
@@ -81,8 +81,8 @@ struct luks_masterkey *LUKS_generate_masterkey(int keylength)
 
 int LUKS_read_phdr(const char *device, struct luks_phdr *hdr)
 {
-       int devfd = 0, r = 0; 
-       unsigned int i; 
+       int devfd = 0, r = 0;
+       unsigned int i;
        uint64_t size;
        char luksMagic[] = LUKS_MAGIC;
 
@@ -97,12 +97,12 @@ int LUKS_read_phdr(const char *device, struct luks_phdr *hdr)
        } else if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
                set_error(_("%s is not a LUKS partition\n"), device);
                r = -EINVAL;
-       } else if(memcmp(hdr->hashSpec, "sha1", 4)) { /* Check for SHA1 - other hashspecs are not implemented ATM */
-               set_error(_("unknown hash spec in phdr\n"), stderr);
-               r = -EINVAL;
        } else if((hdr->version = ntohs(hdr->version)) != 1) {  /* Convert every uint16/32_t item from network byte order */
                set_error(_("unknown LUKS version %d\n"), hdr->version);
                r = -EINVAL;
+       } else if (PBKDF2_HMAC_ready(hdr->hashSpec) < 0) {
+               set_error(_("Requested LUKS hash %s is not supported.\n"), hdr->hashSpec);
+               r = -EINVAL;
        } else {
                hdr->payloadOffset      = ntohl(hdr->payloadOffset);
                hdr->keyBytes           = ntohl(hdr->keyBytes);
@@ -162,9 +162,10 @@ int LUKS_write_phdr(const char *device, struct luks_phdr *hdr)
        return r;
 }
 
-int LUKS_generate_phdr(struct luks_phdr *header, 
-                      const struct luks_masterkey *mk, const char *cipherName,
-                      const char *cipherMode, unsigned int stripes,
+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)
 {
        unsigned int i=0;
@@ -184,9 +185,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
        header->version=1;
        strncpy(header->cipherName,cipherName,LUKS_CIPHERNAME_L);
        strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L);
-
-       /* This is hard coded ATM */
-       strncpy(header->hashSpec,"sha1",LUKS_HASHSPEC_L);
+       strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L);
 
        header->keyBytes=mk->keyLength;
 
@@ -224,8 +223,8 @@ int LUKS_generate_phdr(struct luks_phdr *header,
        return 0;
 }
 
-int LUKS_set_key(const char *device, unsigned int keyIndex, 
-                const char *password, size_t passwordLen, 
+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 setup_backend *backend)
 {
@@ -291,11 +290,11 @@ out:
 }
 
 /* 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, 
+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 setup_backend *backend)
 {
@@ -497,18 +496,15 @@ int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex)
        return 1;
 }
 
-
-int LUKS_benchmarkt_iterations()
+int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count)
 {
-       unsigned int count;
-       char *hash = "sha1";
-
-       if (PBKDF2_performance_check(hash, &count) < 0) {
+       if (PBKDF2_performance_check(hash, count) < 0) {
                set_error(_("Not compatible options (using hash algorithm %s)."), hash);
                return -EINVAL;
        }
 
-       return count/2;
+       *count /= 2;
+       return 0;
 }
 
 int LUKS_device_ready(const char *device, int mode)
index caa4a99..31057f1 100644 (file)
@@ -89,8 +89,9 @@ void LUKS_dealloc_masterkey(struct luks_masterkey *mk);
 struct luks_masterkey *LUKS_generate_masterkey(int keylength);
 
 int LUKS_generate_phdr(struct luks_phdr *header,
-                      const struct luks_masterkey *mk, const char *cipherName,
-                      const char *cipherMode, unsigned int stripes,
+                      const struct luks_masterkey *mk,
+                      const char *cipherName, const char *cipherMode, const char *hashSpec,
+                      unsigned int stripes,
                       unsigned int alignPayload);
 
 int LUKS_read_phdr(const char *device, struct luks_phdr *hdr);
@@ -130,14 +131,14 @@ int LUKS_open_any_key_with_hdr(const char *device,
 
 int LUKS_del_key(const char *device, unsigned int keyIndex);
 int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex);
-int LUKS_benchmarkt_iterations();
+int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count);
 
 int LUKS_encrypt_to_storage(char *src, size_t srcLength,
                            struct luks_phdr *hdr,
                            char *key, size_t keyLength,
                            const char *device,
                            unsigned int sector, struct setup_backend *backend);
-       
+
 int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
                              struct luks_phdr *hdr,
                              char *key, size_t keyLength,
index 179d351..3a1e42f 100644 (file)
@@ -16,7 +16,7 @@
 
 static int opt_verbose = 1;
 static char *opt_cipher = NULL;
-static char *opt_hash = DEFAULT_HASH;
+static char *opt_hash = NULL;
 static int opt_verify_passphrase = 0;
 static char *opt_key_file = NULL;
 static unsigned int opt_key_size = 0;
@@ -153,7 +153,7 @@ static int action_create(int reload)
                .name = action_argv[0],
                .device = action_argv[1],
                .cipher = opt_cipher?opt_cipher:DEFAULT_CIPHER,
-               .hash = opt_hash,
+               .hash = opt_hash ?: DEFAULT_HASH,
                .key_file = opt_key_file,
                .key_size = ((opt_key_size)?opt_key_size:DEFAULT_KEY_SIZE)/8,
                .key_slot = opt_key_slot,
@@ -258,6 +258,9 @@ static int action_luksFormat(int arg)
                .key_slot = opt_key_slot,
                .device = action_argv[0],
                .cipher = opt_cipher?opt_cipher:DEFAULT_LUKS_CIPHER,
+               .hash = DEFAULT_LUKS_HASH,
+               // FIXME: enable other hash use here
+               //.hash = opt_hash ?: DEFAULT_LUKS_HASH,
                .new_key_file = action_argc > 1 ? action_argv[1] : NULL,
                .flags = opt_verify_passphrase ? CRYPT_FLAG_VERIFY : (!opt_batch_mode?CRYPT_FLAG_VERIFY_IF_POSSIBLE :  0),
                .iteration_time = opt_iteration_time,
index 7e35824..14f6763 100644 (file)
@@ -29,6 +29,7 @@
 #define DEFAULT_CIPHER         "aes"
 #define DEFAULT_LUKS_CIPHER     "aes-cbc-essiv:sha256"
 #define DEFAULT_HASH           "ripemd160"
+#define DEFAULT_LUKS_HASH      "sha1"
 #define DEFAULT_KEY_SIZE       256
 #define DEFAULT_LUKS_KEY_SIZE  128