TCRYPT: fix activation and hidden device offsets.
authorMilan Broz <gmazyland@gmail.com>
Tue, 27 Nov 2012 16:13:53 +0000 (17:13 +0100)
committerMilan Broz <gmazyland@gmail.com>
Tue, 27 Nov 2012 16:13:53 +0000 (17:13 +0100)
lib/setup.c
lib/tcrypt/tcrypt.c
lib/tcrypt/tcrypt.h

index 156e27042fa297ae9d44a2d877658b2d915f6b2d..f712b29835a9a3aed10095e190b0f53049340614 100644 (file)
@@ -2434,7 +2434,7 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd)
                return cd->loopaes_hdr.offset;
 
        if (isTCRYPT(cd->type))
-               return TCRYPT_get_data_offset(&cd->tcrypt_hdr);
+               return TCRYPT_get_data_offset(cd, &cd->tcrypt_hdr, &cd->tcrypt_params);
 
        return 0;
 }
@@ -2451,7 +2451,7 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd)
                return cd->loopaes_hdr.skip;
 
        if (isTCRYPT(cd->type))
-               return TCRYPT_get_iv_offset(&cd->tcrypt_hdr);
+               return TCRYPT_get_iv_offset(cd, &cd->tcrypt_hdr, &cd->tcrypt_params);
 
        return 0;
 }
@@ -2524,8 +2524,8 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
                return -ENOTSUP;
 
        if (cd && isTCRYPT(cd->type)) {
-               cad->offset     = TCRYPT_get_data_offset(&cd->tcrypt_hdr);
-               cad->iv_offset  = TCRYPT_get_iv_offset(&cd->tcrypt_hdr);
+               cad->offset     = TCRYPT_get_data_offset(cd, &cd->tcrypt_hdr, &cd->tcrypt_params);
+               cad->iv_offset  = TCRYPT_get_iv_offset(cd, &cd->tcrypt_hdr, &cd->tcrypt_params);
        } else {
                cad->offset     = dmd.u.crypt.offset;
                cad->iv_offset  = dmd.u.crypt.iv_offset;
index 89442a0fbf591983155d3669fcaabbeeb36fa231..4d2cdb382211ca42639d482327ed698dc30643f7 100644 (file)
@@ -508,9 +508,10 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
        r = hdr_from_disk(hdr, params, i, r);
        if (!r) {
                log_dbg("TCRYPT: Header version: %d, req. %d, sector %d"
-                       ", PBKDF2 hash %s", (int)hdr->d.version,
+                       ", mk_offset %" PRIu64 ", hidden_size %" PRIu64
+                       ", volume size %" PRIu64, (int)hdr->d.version,
                        (int)hdr->d.version_tc, (int)hdr->d.sector_size,
-                       params->hash_name);
+                       hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
                log_dbg("TCRYPT: Header cipher %s-%s, key size %d",
                        params->cipher, params->mode, params->key_size);
        }
@@ -627,6 +628,11 @@ int TCRYPT_activate(struct crypt_device *cd,
        if (!algs)
                return -EINVAL;
 
+       if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
+               dmd.size = hdr->d.hidden_volume_size / hdr->d.sector_size;
+       else
+               dmd.size = hdr->d.volume_size / hdr->d.sector_size;
+
        r = device_block_adjust(cd, dmd.data_device, DEV_EXCL,
                                dmd.u.crypt.offset, &dmd.size, &dmd.flags);
        if (r)
@@ -802,19 +808,49 @@ int TCRYPT_init_by_name(struct crypt_device *cd, const char *name,
        return 0;
 }
 
-uint64_t TCRYPT_get_data_offset(struct tcrypt_phdr *hdr)
+uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
+                                struct tcrypt_phdr *hdr,
+                                struct crypt_params_tcrypt *params)
 {
+       uint64_t size;
+
+       if (params->mode && !strncmp(params->mode, "xts", 3)) {
+               if (hdr->d.version < 3)
+                       return 1;
+
+               if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
+                       if (hdr->d.version > 3)
+                               return (hdr->d.mk_offset / hdr->d.sector_size);
+                       if (device_size(crypt_metadata_device(cd), &size) < 0)
+                               return 0;
+                       return (size - hdr->d.hidden_volume_size +
+                               (TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
+               }
+               return (hdr->d.mk_offset / hdr->d.sector_size);
+       }
+
+       if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
+               if (device_size(crypt_metadata_device(cd), &size) < 0)
+                       return 0;
+               return (size - hdr->d.hidden_volume_size +
+                       (TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
+       }
+
        // FIXME: system vol.
-       if (!hdr->d.mk_offset)
-               return 1;
-       return (hdr->d.mk_offset / hdr->d.sector_size);
+       return hdr->d.mk_offset / hdr->d.sector_size;
 }
 
-uint64_t TCRYPT_get_iv_offset(struct tcrypt_phdr *hdr)
+uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
+                             struct tcrypt_phdr *hdr,
+                             struct crypt_params_tcrypt *params
+)
 {
-       if (!hdr->d.mk_offset)
+       if (params->mode && !strncmp(params->mode, "xts", 3))
+               return TCRYPT_get_data_offset(cd, hdr, params);
+       else if (params->mode && !strncmp(params->mode, "lrw", 3))
                return 0;
-       return (hdr->d.mk_offset / hdr->d.sector_size);
+
+       return hdr->d.mk_offset / hdr->d.sector_size;
 }
 
 int TCRYPT_get_volume_key(struct crypt_device *cd,
index d62ebe50fda79dd58f5b5a5e48c430fbc2973532..d67f8f1ab7ecbe874861c931f29e97a4f23e6457 100644 (file)
@@ -91,8 +91,13 @@ int TCRYPT_activate(struct crypt_device *cd,
 int TCRYPT_deactivate(struct crypt_device *cd,
                      const char *name);
 
-uint64_t TCRYPT_get_data_offset(struct tcrypt_phdr *hdr);
-uint64_t TCRYPT_get_iv_offset(struct tcrypt_phdr *hdr);
+uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
+                               struct tcrypt_phdr *hdr,
+                               struct crypt_params_tcrypt *params);
+
+uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
+                             struct tcrypt_phdr *hdr,
+                             struct crypt_params_tcrypt *params);
 
 int TCRYPT_get_volume_key(struct crypt_device *cd,
                          struct tcrypt_phdr *hdr,