Fix support for LUKS header created by cryptsetup-1.0.0
authorMilan Broz <gmazyland@gmail.com>
Mon, 9 Apr 2012 20:47:19 +0000 (22:47 +0200)
committerMilan Broz <gmazyland@gmail.com>
Mon, 9 Apr 2012 21:11:52 +0000 (23:11 +0200)
(no 4k alignment for the first keyslot).
Also skip repair for such header.

Thanks to Dick Middleton for reporting the issue.

ChangeLog
lib/luks1/keymanage.c
tests/evil_hdr-luks_hdr_damage.bz2

index b56724f..7000963 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
-2012-04-02  Milan Broz  <gmazyland@gmail.com>
+2012-04-09  Milan Broz  <gmazyland@gmail.com>
+       * Fix header check to support old (cryptsetup 1.0.0) header alignment. (1.4.0)
        * Version 1.4.2.
 
 2012-03-16  Milan Broz  <gmazyland@gmail.com>
index d83f752..78c1ebc 100644 (file)
@@ -87,7 +87,7 @@ static int LUKS_check_keyslot_size(const struct luks_phdr *phdr, unsigned int ke
        uint32_t secs_per_stripes;
 
        /* First sectors is the header itself */
-       if (phdr->keyblock[keyIndex].keyMaterialOffset * SECTOR_SIZE < LUKS_ALIGN_KEYSLOTS) {
+       if (phdr->keyblock[keyIndex].keyMaterialOffset * SECTOR_SIZE < sizeof(*phdr)) {
                log_dbg("Invalid offset %u in keyslot %u.",
                        phdr->keyblock[keyIndex].keyMaterialOffset, keyIndex);
                return 1;
@@ -310,6 +310,12 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
                log_err(ctx, _("Non standard key size, manual repair required.\n"));
                return -EINVAL;
        }
+       /* cryptsetup 1.0 did not align to 4k, cannot repair this one */
+       if (phdr->keyblock[0].keyMaterialOffset < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) {
+               log_err(ctx, _("Non standard keyslots alignment, manual repair required.\n"));
+               return -EINVAL;
+       }
+
        vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
 
        log_verbose(ctx, _("Repairing keyslots.\n"));
@@ -328,6 +334,11 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
        }
 
        for(i = 0; i < LUKS_NUMKEYS; ++i) {
+               if (phdr->keyblock[i].active == LUKS_KEY_ENABLED)  {
+                       log_dbg("Skipping repair for active keyslot %i.", i);
+                       continue;
+               }
+
                bad = 0;
                if (phdr->keyblock[i].keyMaterialOffset != temp_phdr.keyblock[i].keyMaterialOffset) {
                        log_err(ctx, _("Keyslot %i: offset repaired (%u -> %u).\n"), i,
@@ -345,20 +356,17 @@ static int _keyslot_repair(const char *device, struct luks_phdr *phdr, struct cr
                        bad = 1;
                }
 
-               /* if enabled, do not try to wipe salt */
-               if (phdr->keyblock[i].active != LUKS_KEY_ENABLED) {
-                       /* Known case - MSDOS partition table signature */
-                       if (i == 6 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa) {
-                               log_err(ctx, _("Keyslot %i: bogus partition signature.\n"), i);
-                               bad = 1;
-                       }
-
-                       if(bad) {
-                               log_err(ctx, _("Keyslot %i: salt wiped.\n"), i);
-                               phdr->keyblock[i].active = LUKS_KEY_DISABLED;
-                               memset(&phdr->keyblock[i].passwordSalt, 0x00, LUKS_SALTSIZE);
-                               phdr->keyblock[i].passwordIterations = 0;
-                       }
+               /* Known case - MSDOS partition table signature */
+               if (i == 6 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa) {
+                       log_err(ctx, _("Keyslot %i: bogus partition signature.\n"), i);
+                       bad = 1;
+               }
+
+               if(bad) {
+                       log_err(ctx, _("Keyslot %i: salt wiped.\n"), i);
+                       phdr->keyblock[i].active = LUKS_KEY_DISABLED;
+                       memset(&phdr->keyblock[i].passwordSalt, 0x00, LUKS_SALTSIZE);
+                       phdr->keyblock[i].passwordIterations = 0;
                }
 
                if (bad)
index b228048..b4970be 100644 (file)
Binary files a/tests/evil_hdr-luks_hdr_damage.bz2 and b/tests/evil_hdr-luks_hdr_damage.bz2 differ