Rewrite dm query/create function backend.
authorMilan Broz <gmazyland@gmail.com>
Sun, 17 Jul 2011 22:35:17 +0000 (22:35 +0000)
committerMilan Broz <gmazyland@gmail.com>
Sun, 17 Jul 2011 22:35:17 +0000 (22:35 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@570 36d66b0a-2a48-0410-832c-cd162a569da5

12 files changed:
lib/internal.h
lib/libcryptsetup.h
lib/libdevmapper.c
lib/loopaes/loopaes.c
lib/loopaes/loopaes.h
lib/luks1/keyencryption.c
lib/luks1/keymanage.c
lib/luks1/luks.h
lib/setup.c
lib/utils.c
lib/utils_dm.h
lib/volumekey.c

index 1803462..606c234 100644 (file)
@@ -62,7 +62,7 @@ int device_check_and_adjust(struct crypt_device *cd,
                            enum devcheck device_check,
                            uint64_t *size,
                            uint64_t *offset,
-                           int *read_only);
+                           uint32_t *flags);
 int wipe_device_header(const char *device, int sectors);
 
 void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
@@ -94,5 +94,11 @@ int crypt_plain_hash(struct crypt_device *ctx,
                     const char *hash_name,
                     char *key, size_t key_size,
                     const char *passphrase, size_t passphrase_size);
+int PLAIN_activate(struct crypt_device *cd,
+                    const char *name,
+                    struct volume_key *vk,
+                    uint64_t size,
+                    uint64_t iv_offset,
+                    uint32_t flags);
 
 #endif /* INTERNAL_H */
index 4e8089b..e32e2b1 100644 (file)
@@ -375,7 +375,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
  * Activation flags
  */
 #define CRYPT_ACTIVATE_READONLY (1 << 0)
-#define CRYPT_ACTIVATE_NO_UUID  (1 << 1)
+#define CRYPT_ACTIVATE_NO_UUID  (1 << 1) /* ignored */
 #define CRYPT_ACTIVATE_SHARED   (1 << 2)
 
 /**
index aa61c25..c1307b0 100644 (file)
@@ -396,16 +396,8 @@ static void dm_prepare_uuid(const char *name, const char *type, const char *uuid
 }
 
 int dm_create_device(const char *name,
-                    const char *device,
-                    const char *cipher,
                     const char *type,
-                    const char *uuid,
-                    uint64_t size,
-                    uint64_t skip,
-                    uint64_t offset,
-                    size_t key_size,
-                    const char *key,
-                    int read_only,
+                    struct crypt_dm_active_device *dmd,
                     int reload)
 {
        struct dm_task *dmt = NULL;
@@ -418,7 +410,8 @@ int dm_create_device(const char *name,
        uint32_t cookie = 0;
        uint16_t udev_flags = 0;
 
-       params = get_params(device, skip, offset, cipher, key_size, key);
+       params = get_params(dmd->device, dmd->iv_offset, dmd->offset,
+                           dmd->cipher, dmd->key_size, dmd->key);
        if (!params)
                goto out_no_removal;
 
@@ -433,7 +426,7 @@ int dm_create_device(const char *name,
                if (!dm_task_set_name(dmt, name))
                        goto out_no_removal;
        } else {
-               dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
+               dm_prepare_uuid(name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid));
 
                if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
                        goto out_no_removal;
@@ -450,13 +443,13 @@ int dm_create_device(const char *name,
 
        if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
                goto out_no_removal;
-       if (read_only && !dm_task_set_ro(dmt))
+       if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
                goto out_no_removal;
-       if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
+       if (!dm_task_add_target(dmt, 0, dmd->size, DM_CRYPT_TARGET, params))
                goto out_no_removal;
 
 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
-       if (device_read_ahead(device, &read_ahead) &&
+       if (device_read_ahead(dmd->device, &read_ahead) &&
            !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
                goto out_no_removal;
 #endif
@@ -470,7 +463,7 @@ int dm_create_device(const char *name,
                        goto out;
                if (!dm_task_set_name(dmt, name))
                        goto out;
-               if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
+               if (dmd->uuid && !dm_task_set_uuid(dmt, dev_uuid))
                        goto out;
                if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
                        goto out;
@@ -513,10 +506,9 @@ out_no_removal:
        return r;
 }
 
-int dm_status_device(const char *name)
+static int dm_status_dmi(const char *name, struct dm_info *dmi)
 {
        struct dm_task *dmt;
-       struct dm_info dmi;
        uint64_t start, length;
        char *target_type, *params;
        void *next = NULL;
@@ -531,10 +523,10 @@ int dm_status_device(const char *name)
        if (!dm_task_run(dmt))
                goto out;
 
-       if (!dm_task_get_info(dmt, &dmi))
+       if (!dm_task_get_info(dmt, dmi))
                goto out;
 
-       if (!dmi.exists) {
+       if (!dmi->exists) {
                r = -ENODEV;
                goto out;
        }
@@ -545,7 +537,7 @@ int dm_status_device(const char *name)
            start != 0 || next)
                r = -EINVAL;
        else
-               r = (dmi.open_count > 0);
+               r = 0;
 out:
        if (dmt)
                dm_task_destroy(dmt);
@@ -553,17 +545,32 @@ out:
        return r;
 }
 
-int dm_query_device(const char *name,
-                   char **device,
-                   uint64_t *size,
-                   uint64_t *skip,
-                   uint64_t *offset,
-                   char **cipher,
-                   int *key_size,
-                   char **key,
-                   int *read_only,
-                   int *suspended,
-                   char **uuid)
+int dm_status_device(const char *name)
+{
+       int r;
+       struct dm_info dmi;
+
+       r = dm_status_dmi(name, &dmi);
+       if (r < 0)
+               return r;
+
+       return (dmi.open_count > 0);
+}
+
+int dm_status_suspended(const char *name)
+{
+       int r;
+       struct dm_info dmi;
+
+       r = dm_status_dmi(name, &dmi);
+       if (r < 0)
+               return r;
+
+       return dmi.suspended ? 1 : 0;
+}
+
+int dm_query_device(const char *name, uint32_t get_flags,
+                   struct crypt_dm_active_device *dmd)
 {
        struct dm_task *dmt;
        struct dm_info dmi;
@@ -571,7 +578,10 @@ int dm_query_device(const char *name,
        char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3];
        const char *tmp_uuid;
        void *next = NULL;
-       int i, r = -EINVAL;
+       unsigned int i;
+       int r = -EINVAL;
+
+       memset(dmd, 0, sizeof(*dmd));
 
        if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
                goto out;
@@ -592,19 +602,20 @@ int dm_query_device(const char *name,
                goto out;
        }
 
+       tmp_uuid = dm_task_get_uuid(dmt);
+
        next = dm_get_next_target(dmt, next, &start, &length,
                                  &target_type, &params);
        if (!target_type || strcmp(target_type, DM_CRYPT_TARGET) != 0 ||
            start != 0 || next)
                goto out;
 
-       if (size)
-               *size = length;
+       dmd->size = length;
 
        rcipher = strsep(&params, " ");
        /* cipher */
-       if (cipher)
-               *cipher = strdup(rcipher);
+       if (get_flags & DM_ACTIVE_CIPHER)
+               dmd->cipher = strdup(rcipher);
 
        /* skip */
        key_ = strsep(&params, " ");
@@ -614,13 +625,13 @@ int dm_query_device(const char *name,
        if (*params != ' ')
                goto out;
        params++;
-       if (skip)
-               *skip = val64;
+
+       dmd->iv_offset = val64;
 
        /* device */
        rdevice = strsep(&params, " ");
-       if (device)
-               *device = crypt_lookup_dev(rdevice);
+       if (get_flags & DM_ACTIVE_DEVICE)
+               dmd->device = crypt_lookup_dev(rdevice);
 
        /*offset */
        if (!params)
@@ -628,43 +639,41 @@ int dm_query_device(const char *name,
        val64 = strtoull(params, &params, 10);
        if (*params)
                goto out;
-       if (offset)
-               *offset = val64;
+       dmd->offset = val64;
 
        /* key_size */
-       if (key_size)
-               *key_size = strlen(key_) / 2;
+       dmd->key_size = strlen(key_) / 2;
 
        /* key */
-       if (key_size && key) {
-               *key = crypt_safe_alloc(*key_size);
-               if (!*key) {
+       if (dmd->key_size && (get_flags & DM_ACTIVE_KEY)) {
+               dmd->key = crypt_safe_alloc(dmd->key_size);
+               if (!dmd->key) {
                        r = -ENOMEM;
                        goto out;
                }
 
                buffer[2] = '\0';
-               for(i = 0; i < *key_size; i++) {
+               for(i = 0; i < dmd->key_size; i++) {
                        memcpy(buffer, &key_[i * 2], 2);
-                       (*key)[i] = strtoul(buffer, &endp, 16);
+                       dmd->key[i] = strtoul(buffer, &endp, 16);
                        if (endp != &buffer[2]) {
-                               crypt_safe_free(key);
-                               *key = NULL;
+                               crypt_safe_free(dmd->key);
+                               dmd->key = NULL;
                                goto out;
                        }
                }
        }
        memset(key_, 0, strlen(key_));
 
-       if (read_only)
-               *read_only = dmi.read_only;
-
-       if (suspended)
-               *suspended = dmi.suspended;
+       if (dmi.read_only)
+               dmd->flags |= CRYPT_ACTIVATE_READONLY;
 
-       if (uuid && (tmp_uuid = dm_task_get_uuid(dmt)) &&
-           !strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
-               *uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+       if (!tmp_uuid)
+               dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
+       else if (get_flags & DM_ACTIVE_UUID) {
+               if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
+                       dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+       }
 
        r = (dmi.open_count > 0);
 out:
@@ -767,23 +776,22 @@ int dm_is_dm_kernel_name(const char *name)
 
 int dm_check_segment(const char *name, uint64_t offset, uint64_t size)
 {
-       uint64_t seg_size, seg_offset;
+       struct crypt_dm_active_device dmd;
        int r;
 
        log_dbg("Checking segments for device %s.", name);
 
-       r = dm_query_device(name, NULL, &seg_size, NULL, &seg_offset,
-                           NULL, NULL, NULL, NULL, NULL, NULL);
+       r = dm_query_device(name, 0, &dmd);
        if (r < 0)
                return r;
 
-       if (offset >= (seg_offset + seg_size) || (offset + size) <= seg_offset)
+       if (offset >= (dmd.offset + dmd.size) || (offset + size) <= dmd.offset)
                r = 0;
        else
                r = -EBUSY;
 
        log_dbg("seg: %" PRIu64 " - %" PRIu64 ", new %" PRIu64 " - %" PRIu64 "%s",
-              seg_offset, seg_offset + seg_size, offset, offset + size,
+              dmd.offset, dmd.offset + dmd.size, offset, offset + size,
               r ? " (overlapping)" : " (ok)");
 
        return r;
index e6fe827..5bddc2c 100644 (file)
@@ -185,22 +185,26 @@ int LOOPAES_activate(struct crypt_device *cd,
                     const char *base_cipher,
                     unsigned int keys_count,
                     struct volume_key *vk,
-                    uint64_t offset,
                     uint64_t skip,
                     uint32_t flags)
 {
-       uint64_t size;
+       char *cipher = NULL;
        uint32_t req_flags;
-       char *cipher;
-       const char *device;
-       int read_only, r;
-
-       size = 0;
-       /* Initial IV (skip) is always the same as offset */
-       device = crypt_get_device_name(cd);
-       read_only = flags & CRYPT_ACTIVATE_READONLY;
-
-       r = device_check_and_adjust(cd, device, DEV_EXCL, &size, &offset, &read_only);
+       int r;
+       struct crypt_dm_active_device dmd = {
+               .device = crypt_get_device_name(cd),
+               .cipher = NULL,
+               .uuid   = crypt_get_uuid(cd),
+               .key    = vk->key,
+               .key_size = vk->keylength,
+               .offset = crypt_get_data_offset(cd),
+               .iv_offset = skip,
+               .size   = 0,
+               .flags  = flags
+       };
+
+
+       r = device_check_and_adjust(cd, dmd.device, DEV_EXCL, &dmd.size, &dmd.offset, &flags);
        if (r)
                return r;
 
@@ -214,12 +218,10 @@ int LOOPAES_activate(struct crypt_device *cd,
        if (r < 0)
                return -ENOMEM;
 
-       log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, cipher);
-       r = dm_create_device(name, device,
-                            cipher, CRYPT_LOOPAES,
-                            crypt_get_uuid(cd),
-                            size, skip, offset, vk->keylength, vk->key,
-                            read_only, 0);
+       dmd.cipher = cipher;
+       log_dbg("Trying to activate loop-AES device %s using cipher %s.", name, dmd.cipher);
+
+       r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);
 
        if (!r && !(dm_flags() & req_flags)) {
                log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));
index 32ecded..73a824c 100644 (file)
@@ -18,7 +18,6 @@ int LOOPAES_activate(struct crypt_device *cd,
                     const char *base_cipher,
                     unsigned int keys_count,
                     struct volume_key *vk,
-                    uint64_t offset,
                     uint64_t skip,
                     uint32_t flags);
 #endif
index c37724a..b05cbfd 100644 (file)
@@ -56,7 +56,17 @@ static int setup_mapping(const char *cipher, const char *name,
                         int mode, struct crypt_device *ctx)
 {
        int device_sector_size = sector_size_for_device(device);
-       uint64_t size;
+       struct crypt_dm_active_device dmd = {
+               .device = device,
+               .cipher = cipher,
+               .uuid   = NULL,
+               .key    = (char*)key,
+               .key_size = keyLength,
+               .offset = sector,
+               .iv_offset = 0,
+               .size   = 0,
+               .flags  = (mode == O_RDONLY) ? CRYPT_ACTIVATE_READONLY : 0
+       };
 
        /*
         * we need to round this to nearest multiple of the underlying
@@ -66,11 +76,11 @@ static int setup_mapping(const char *cipher, const char *name,
                log_err(ctx, _("Unable to obtain sector size for %s"), device);
                return -EINVAL;
        }
-       size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
-       cleaner_size = size;
 
-       return dm_create_device(name, device, cipher, "TEMP", NULL, size, 0, sector,
-                               keyLength, key, (mode == O_RDONLY), 0);
+       dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
+       cleaner_size = dmd.size;
+
+       return dm_create_device(name, "TEMP", &dmd, 0);
 }
 
 static void sigint_handler(int sig __attribute__((unused)))
index 6c07492..1b1b858 100644 (file)
@@ -897,3 +897,38 @@ int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable)
        log_dbg("Key slot %d was %s in LUKS header.", keyslot, enable ? "enabled" : "disabled");
        return 0;
 }
+
+int LUKS1_activate(struct crypt_device *cd,
+                  const char *name,
+                  struct volume_key *vk,
+                  uint32_t flags)
+{
+       int r;
+       char *dm_cipher = NULL;
+       struct crypt_dm_active_device dmd = {
+               .device = crypt_get_device_name(cd),
+               .cipher = NULL,
+               .uuid   = crypt_get_uuid(cd),
+               .key    = vk->key,
+               .key_size = vk->keylength,
+               .offset = crypt_get_data_offset(cd),
+               .iv_offset = 0,
+               .size   = 0,
+               .flags  = flags
+       };
+
+       r = device_check_and_adjust(cd, dmd.device, DEV_EXCL,
+                                   &dmd.size, &dmd.offset, &flags);
+       if (r)
+               return r;
+
+       r = asprintf(&dm_cipher, "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
+       if (r < 0)
+               return -ENOMEM;
+
+       dmd.cipher = dm_cipher;
+       r = dm_create_device(name, CRYPT_LUKS1, &dmd, 0);
+
+       free(dm_cipher);
+       return r;
+}
index d188438..3c1203c 100644 (file)
@@ -173,4 +173,9 @@ int LUKS_decrypt_from_storage(
        unsigned int sector,
        struct crypt_device *ctx);
 
+int LUKS1_activate(struct crypt_device *cd,
+                  const char *name,
+                  struct volume_key *vk,
+                  uint32_t flags);
+
 #endif
index fd68109..cfbee7b 100644 (file)
@@ -135,43 +135,21 @@ static int init_crypto(struct crypt_device *ctx)
        return r;
 }
 
-/*
- * Password processing behaviour matrix of process_key
- *
- * from binary file: check if there is sufficently large key material
- * interactive & from fd: hash if requested, otherwise crop or pad with '0'
- */
-static char *process_key(struct crypt_device *cd, const char *hash_name,
-                        const char *key_file, size_t key_size,
-                        const char *pass, size_t passLen)
+static int process_key(struct crypt_device *cd, const char *hash_name,
+                      size_t key_size, const char *pass, size_t passLen,
+                      struct volume_key **vk)
 {
-       char *key;
        int r;
 
        if (!key_size)
-               return NULL;
-
-       key = crypt_safe_alloc(key_size);
-       if (!key)
-               return NULL;
-       memset(key, 0, key_size);
-
-       /* key is coming from binary file */
-       if (key_file && strcmp(key_file, "-")) {
-               if(passLen < key_size) {
-                       log_err(cd, ngettext("Cannot read %d byte from key file %s.\n",
-                               "Cannot read %d bytes from key file %s.\n", key_size),
-                               (int)key_size, key_file);
-                       crypt_safe_free(key);
-                       return NULL;
-               }
-               memcpy(key, pass, key_size);
-               return key;
-       }
+               return -EINVAL;
+
+       *vk = crypt_alloc_volume_key(key_size, NULL);
+       if (!*vk)
+               return -ENOMEM;
 
-       /* key is coming from tty, fd or binary stdin */
        if (hash_name) {
-               r = crypt_plain_hash(cd, hash_name, key, key_size, pass, passLen);
+               r = crypt_plain_hash(cd, hash_name, (*vk)->key, key_size, pass, passLen);
                if (r < 0) {
                        if (r == -ENOENT)
                                log_err(cd, _("Hash algorithm %s not supported.\n"),
@@ -179,16 +157,17 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
                        else
                                log_err(cd, _("Key processing error (using hash %s).\n"),
                                        hash_name);
-                       crypt_safe_free(key);
-                       return NULL;
+                       crypt_free_volume_key(*vk);
+                       *vk = NULL;
+                       return -EINVAL;
                }
        } else if (passLen > key_size) {
-               memcpy(key, pass, key_size);
+               memcpy((*vk)->key, pass, key_size);
        } else {
-               memcpy(key, pass, passLen);
+               memcpy((*vk)->key, pass, passLen);
        }
 
-       return key;
+       return 0;
 }
 
 static int isPLAIN(const char *type)
@@ -233,108 +212,50 @@ static int keyslot_verify_or_find_empty(struct crypt_device *cd, int *keyslot)
        return 0;
 }
 
-static int create_device_helper(struct crypt_device *cd,
-                               const char *name,
-                               const char *hash,
-                               const char *cipher,
-                               const char *cipher_mode,
-                               const char *key_file,
-                               const char *passphrase,
-                               size_t passphrase_size,
-                               size_t key_size,
-                               uint64_t size,
-                               uint64_t skip,
-                               uint64_t offset,
-                               const char *uuid,
-                               uint32_t activation_flags,
-                               int reload)
+int PLAIN_activate(struct crypt_device *cd,
+                    const char *name,
+                    struct volume_key *vk,
+                    uint64_t size,
+                    uint64_t iv_offset,
+                    uint32_t flags)
 {
-       crypt_status_info ci;
+       int r;
        char *dm_cipher = NULL;
-       char *processed_key = NULL;
-       enum devcheck device_check;
-       int r, read_only;
-
-       if (!name)
-               return -EINVAL;
-
-       read_only = activation_flags & CRYPT_ACTIVATE_READONLY ? 1 : 0;
-       if (reload)
-               device_check = DEV_OK;
-       else if (activation_flags & CRYPT_ACTIVATE_SHARED)
-               device_check = DEV_SHARED;
-       else
-               device_check = DEV_EXCL;
-
-       ci = crypt_status(cd, name);
-       if (ci == CRYPT_INVALID)
-               return -EINVAL;
-
-       if (reload && ci < CRYPT_ACTIVE)
-               return -EINVAL;
-
-       if (!reload && ci >= CRYPT_ACTIVE) {
-               log_err(cd, _("Device %s already exists.\n"), name);
-               return -EEXIST;
-       }
-
-       if (key_size > 1024) {
-               log_err(cd, _("Invalid key size %d.\n"), (int)key_size);
-               return -EINVAL;
-       }
-
-       r = device_check_and_adjust(cd, cd->device, device_check, &size, &offset, &read_only);
+       struct crypt_dm_active_device dmd = {
+               .device = crypt_get_device_name(cd),
+               .cipher = NULL,
+               .uuid   = crypt_get_uuid(cd),
+               .key    = vk->key,
+               .key_size = vk->keylength,
+               .offset = crypt_get_data_offset(cd),
+               .iv_offset = iv_offset,
+               .size   = size,
+               .flags  = flags
+       };
+
+       r = device_check_and_adjust(cd, dmd.device,
+                                   (dmd.flags & CRYPT_ACTIVATE_SHARED) ? DEV_SHARED : DEV_EXCL,
+                                   &dmd.size, &dmd.offset, &flags);
        if (r)
                return r;
 
-       if (cipher_mode && asprintf(&dm_cipher, "%s-%s", cipher, cipher_mode) < 0)
+       if (crypt_get_cipher_mode(cd))
+               r = asprintf(&dm_cipher, "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
+       else
+               r = asprintf(&dm_cipher, "%s", crypt_get_cipher(cd));
+       if (r < 0)
                return -ENOMEM;
 
-       processed_key = process_key(cd, hash, key_file, key_size, passphrase, passphrase_size);
-       if (!processed_key) {
-               r = -ENOENT;
-               goto out;
-       }
-
-       r = dm_create_device(name, cd->device, dm_cipher ?: cipher, cd->type, uuid, size, skip, offset,
-                            key_size, processed_key, read_only, reload);
+       dmd.cipher = dm_cipher;
+       log_dbg("Trying to activate PLAIN device %s using cipher %s.", name, dmd.cipher);
 
-       if (isPLAIN(cd->type) && !uuid)
-               (void)dm_query_device(name, NULL, NULL, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL, &cd->plain_uuid);
-out:
-       free(dm_cipher);
-       crypt_safe_free(processed_key);
-       return r;
-}
+       r = dm_create_device(name, CRYPT_PLAIN, &dmd, 0);
 
-static int open_from_hdr_and_vk(struct crypt_device *cd,
-                               struct volume_key *vk,
-                               const char *name,
-                               uint32_t flags)
-{
-       uint64_t size, offset;
-       char *cipher;
-       int read_only, no_uuid, r;
-
-       size = 0;
-       offset = crypt_get_data_offset(cd);
-       read_only = flags & CRYPT_ACTIVATE_READONLY;
-       no_uuid = flags & CRYPT_ACTIVATE_NO_UUID;
-
-       r = device_check_and_adjust(cd, cd->device, DEV_EXCL, &size, &offset, &read_only);
-       if (r)
-               return r;
+       // FIXME
+       if (!cd->plain_uuid && dm_query_device(name, DM_ACTIVE_UUID, &dmd) >= 0)
+               cd->plain_uuid = (char*)dmd.uuid;
 
-       if (asprintf(&cipher, "%s-%s", crypt_get_cipher(cd),
-                    crypt_get_cipher_mode(cd)) < 0)
-               r = -ENOMEM;
-       else
-               r = dm_create_device(name, cd->device, cipher, cd->type,
-                                    no_uuid ? NULL : crypt_get_uuid(cd),
-                                    size, 0, offset, vk->keylength, vk->key,
-                                    read_only, 0);
-       free(cipher);
+       free(dm_cipher);
        return r;
 }
 
@@ -474,11 +395,6 @@ const char *crypt_get_dir(void)
        return dm_get_dir();
 }
 
-/////////////////////////////////
-//
-// New API
-//
-
 int crypt_init(struct crypt_device **cd, const char *device)
 {
        struct crypt_device *h = NULL;
@@ -558,11 +474,9 @@ bad:
 int crypt_init_by_name(struct crypt_device **cd, const char *name)
 {
        crypt_status_info ci;
-       struct crypt_active_device cad;
-       char *device = NULL, *cipher_full = NULL, *device_uuid = NULL;
+       struct crypt_dm_active_device dmd;
        char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
-       char *key = NULL;
-       int key_size = 0, key_nums, r;
+       int key_nums, r;
 
 
        log_dbg("Allocating crypt device context by device %s.", name);
@@ -576,24 +490,22 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
                return -ENODEV;
        }
 
-       r = dm_query_device(name, &device, &cad.size, &cad.iv_offset, &cad.offset,
-                           &cipher_full, &key_size, &key, NULL, NULL,
-                           &device_uuid);
+       r = dm_query_device(name, DM_ACTIVE_ALL, &dmd);
        if (r < 0)
                goto out;
 
        *cd = NULL;
-       r = crypt_init(cd, device);
+       r = crypt_init(cd, dmd.device);
 
        /* Underlying device disappeared but mapping still active */
-       if (!device || r == -ENOTBLK)
+       if (!dmd.device || r == -ENOTBLK)
                log_verbose(NULL, _("Underlying device for crypt device %s disappeared.\n"),
                            name);
 
        /* Underlying device is not readable but crypt mapping exists */
        if (r == -ENOTBLK) {
-               free(device);
-               device = NULL;
+               free((char*)dmd.device);
+               dmd.device = NULL;
                r = crypt_init(cd, NULL);
        }
 
@@ -602,54 +514,54 @@ int crypt_init_by_name(struct crypt_device **cd, const char *name)
 
        /* Try to initialise basic parameters from active device */
 
-       if (!(*cd)->backing_file && device && crypt_loop_device(device) &&
-           !((*cd)->backing_file = crypt_loop_backing_file(device))) {
+       if (!(*cd)->backing_file && dmd.device && crypt_loop_device(dmd.device) &&
+           !((*cd)->backing_file = crypt_loop_backing_file(dmd.device))) {
                r = -ENOMEM;
                goto out;
        }
 
-       if (device_uuid) {
-               if (!strncmp(CRYPT_PLAIN, device_uuid, sizeof(CRYPT_PLAIN)-1)) {
+       if (dmd.uuid) {
+               if (!strncmp(CRYPT_PLAIN, dmd.uuid, sizeof(CRYPT_PLAIN)-1)) {
                        (*cd)->type = strdup(CRYPT_PLAIN);
-                       (*cd)->plain_uuid = strdup(device_uuid);
+                       (*cd)->plain_uuid = strdup(dmd.uuid);
                        (*cd)->plain_hdr.hash = NULL; /* no way to get this */
-                       (*cd)->plain_hdr.offset = cad.offset;
-                       (*cd)->plain_hdr.skip = cad.iv_offset;
-                       (*cd)->volume_key = crypt_alloc_volume_key(key_size, key);
+                       (*cd)->plain_hdr.offset = dmd.offset;
+                       (*cd)->plain_hdr.skip = dmd.iv_offset;
+                       (*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key);
                        if (!(*cd)->volume_key) {
                                r = -ENOMEM;
                                goto out;
                        }
 
-                       r = crypt_parse_name_and_mode(cipher_full, cipher, NULL, cipher_mode);
+                       r = crypt_parse_name_and_mode(dmd.cipher, cipher, NULL, cipher_mode);
                        if (!r) {
                                (*cd)->plain_cipher = strdup(cipher);
                                (*cd)->plain_cipher_mode = strdup(cipher_mode);
                        }
-               } else if (!strncmp(CRYPT_LOOPAES, device_uuid, sizeof(CRYPT_LOOPAES)-1)) {
+               } else if (!strncmp(CRYPT_LOOPAES, dmd.uuid, sizeof(CRYPT_LOOPAES)-1)) {
                        (*cd)->type = strdup(CRYPT_LOOPAES);
-                       (*cd)->loopaes_uuid = strdup(device_uuid);
-                       (*cd)->loopaes_hdr.offset = cad.offset;
+                       (*cd)->loopaes_uuid = strdup(dmd.uuid);
+                       (*cd)->loopaes_hdr.offset = dmd.offset;
 
-                       r = crypt_parse_name_and_mode(cipher_full, cipher,
+                       r = crypt_parse_name_and_mode(dmd.cipher, cipher,
                                                      &key_nums, cipher_mode);
                        if (!r) {
                                (*cd)->loopaes_cipher = strdup(cipher);
                                (*cd)->loopaes_cipher_mode = strdup(cipher_mode);
                                /* version 3 uses last key for IV */
-                               if (key_size % key_nums)
+                               if (dmd.key_size % key_nums)
                                        key_nums++;
-                               (*cd)->loopaes_key_size = key_size / key_nums;
+                               (*cd)->loopaes_key_size = dmd.key_size / key_nums;
                        }
-               } else if (!strncmp(CRYPT_LUKS1, device_uuid, sizeof(CRYPT_LUKS1)-1)) {
-                       if (device) {
+               } else if (!strncmp(CRYPT_LUKS1, dmd.uuid, sizeof(CRYPT_LUKS1)-1)) {
+                       if (dmd.device) {
                                if (crypt_load(*cd, CRYPT_LUKS1, NULL) < 0 ||
-                                   crypt_volume_key_verify(*cd, key, key_size) < 0) {
+                                   crypt_volume_key_verify(*cd, dmd.key, dmd.key_size) < 0) {
                                        log_dbg("LUKS device header does not match active device.");
                                        goto out;
                                }
 
-                               (*cd)->volume_key = crypt_alloc_volume_key(key_size, key);
+                               (*cd)->volume_key = crypt_alloc_volume_key(dmd.key_size, dmd.key);
                                if (!(*cd)->volume_key) {
                                        r = -ENOMEM;
                                        goto out;
@@ -664,10 +576,10 @@ out:
                crypt_free(*cd);
                *cd = NULL;
        }
-       crypt_safe_free(key);
-       free(device);
-       free(cipher_full);
-       free(device_uuid);
+       crypt_safe_free(dmd.key);
+       free((char*)dmd.device);
+       free((char*)dmd.cipher);
+       free((char*)dmd.uuid);
        return r;
 }
 
@@ -881,9 +793,8 @@ int crypt_load(struct crypt_device *cd,
 
 int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
 {
-       char *device = NULL, *cipher = NULL, *uuid = NULL, *key = NULL;
-       uint64_t size, skip, offset;
-       int key_size, read_only, r;
+       struct crypt_dm_active_device dmd;
+       int r;
 
        /* Device context type must be initialised */
        if (!cd->type || !crypt_get_uuid(cd))
@@ -891,37 +802,34 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
 
        log_dbg("Resizing device %s to %" PRIu64 " sectors.", name, new_size);
 
-       r = dm_query_device(name, &device, &size, &skip, &offset,
-                           &cipher, &key_size, &key, &read_only, NULL, &uuid);
+       r = dm_query_device(name, DM_ACTIVE_ALL, &dmd);
        if (r < 0) {
                log_err(NULL, _("Device %s is not active.\n"), name);
                goto out;
        }
 
-       if (!uuid) {
+       if (!dmd.uuid) {
                r = -EINVAL;
                goto out;
        }
 
-       r = device_check_and_adjust(cd, device, DEV_OK, &new_size, &offset, &read_only);
+       r = device_check_and_adjust(cd, dmd.device, DEV_OK, &new_size, &dmd.offset, &dmd.flags);
        if (r)
                goto out;
 
-       if (new_size == size) {
+       if (new_size == dmd.size) {
                log_dbg("Device has already requested size %" PRIu64
-                       " sectors.", size);
+                       " sectors.", dmd.size);
                r = 0;
-               goto out;
+       } else {
+               dmd.size = new_size;
+               r = dm_create_device(name, cd->type, &dmd, 1);
        }
-
-       r = dm_create_device(name, device, cipher, cd->type,
-                            crypt_get_uuid(cd), new_size, skip, offset,
-                            key_size, key, read_only, 1);
 out:
-       crypt_safe_free(key);
-       free(cipher);
-       free(device);
-       free(uuid);
+       crypt_safe_free(dmd.key);
+       free((char*)dmd.cipher);
+       free((char*)dmd.device);
+       free((char*)dmd.uuid);
 
        return r;
 }
@@ -1023,7 +931,7 @@ int crypt_suspend(struct crypt_device *cd,
                  const char *name)
 {
        crypt_status_info ci;
-       int r, suspended = 0;
+       int r;
 
        log_dbg("Suspending volume %s.", name);
 
@@ -1036,12 +944,11 @@ int crypt_suspend(struct crypt_device *cd,
        if (!cd && dm_init(NULL, 1) < 0)
                return -ENOSYS;
 
-       r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended, NULL);
+       r = dm_status_suspended(name);
        if (r < 0)
                goto out;
 
-       if (suspended) {
+       if (r) {
                log_err(cd, _("Volume %s is already suspended.\n"), name);
                r = -EINVAL;
                goto out;
@@ -1065,7 +972,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
                               size_t passphrase_size)
 {
        struct volume_key *vk = NULL;
-       int r, suspended = 0;
+       int r;
 
        log_dbg("Resuming volume %s.", name);
 
@@ -1075,12 +982,11 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
                goto out;
        }
 
-       r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended, NULL);
+       r = dm_status_suspended(name);
        if (r < 0)
                return r;
 
-       if (!suspended) {
+       if (!r) {
                log_err(cd, _("Volume %s is not suspended.\n"), name);
                return -EINVAL;
        }
@@ -1114,7 +1020,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
        struct volume_key *vk = NULL;
        char *passphrase_read = NULL;
        size_t passphrase_size_read;
-       int r, suspended = 0;
+       int r;
 
        log_dbg("Resuming volume %s.", name);
 
@@ -1124,12 +1030,11 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
                goto out;
        }
 
-       r = dm_query_device(name, NULL, NULL, NULL, NULL,
-                           NULL, NULL, NULL, NULL, &suspended, NULL);
+       r = dm_status_suspended(name);
        if (r < 0)
                return r;
 
-       if (!suspended) {
+       if (!r) {
                log_err(cd, _("Volume %s is not suspended.\n"), name);
                return -EINVAL;
        }
@@ -1412,6 +1317,9 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
 
        /* plain, use hashed passphrase */
        if (isPLAIN(cd->type)) {
+               if (!name)
+                       return -EINVAL;
+
                if (!passphrase) {
                        r = key_from_terminal(cd, NULL, &read_passphrase,
                                              &passphraseLen, 0);
@@ -1420,12 +1328,16 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
                        passphrase = read_passphrase;
                        passphrase_size = passphraseLen;
                }
-               r = create_device_helper(cd, name, cd->plain_hdr.hash,
-                                        cd->plain_cipher, cd->plain_cipher_mode,
-                                        NULL, passphrase, passphrase_size,
-                                        cd->volume_key->keylength, cd->plain_hdr.size,
-                                        cd->plain_hdr.skip, cd->plain_hdr.offset,
-                                        cd->plain_uuid, flags, 0);
+
+               r = process_key(cd, cd->plain_hdr.hash,
+                               cd->volume_key->keylength,
+                               passphrase, passphrase_size, &vk);
+               if (r < 0)
+                       goto out;
+
+               r = PLAIN_activate(cd, name, vk,
+                                  cd->plain_hdr.size,
+                                  cd->plain_hdr.skip, flags);
                keyslot = 0;
        } else if (isLUKS(cd->type)) {
                /* provided passphrase, do not retry */
@@ -1438,7 +1350,7 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
                if (r >= 0) {
                        keyslot = r;
                        if (name)
-                               r = open_from_hdr_and_vk(cd, vk, name, flags);
+                               r = LUKS1_activate(cd, name, vk, flags);
                }
        } else
                r = -EINVAL;
@@ -1480,17 +1392,24 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
                return -EINVAL;
 
        if (isPLAIN(cd->type)) {
+               if (!name)
+                       return -EINVAL;
+
                r = key_from_file(cd, _("Enter passphrase: "),
                                  &passphrase_read, &passphrase_size_read,
                                  keyfile, keyfile_size);
                if (r < 0)
                        goto out;
-               r = create_device_helper(cd, name, cd->plain_hdr.hash,
-                                        cd->plain_cipher, cd->plain_cipher_mode,
-                                        NULL, passphrase_read, passphrase_size_read,
-                                        cd->volume_key->keylength, cd->plain_hdr.size,
-                                        cd->plain_hdr.skip, cd->plain_hdr.offset,
-                                        cd->plain_uuid, flags, 0);
+
+               r = process_key(cd, cd->plain_hdr.hash,
+                               cd->volume_key->keylength,
+                               passphrase_read, passphrase_size_read, &vk);
+               if (r < 0)
+                       goto out;
+
+               r = PLAIN_activate(cd, name, vk,
+                                  cd->plain_hdr.size,
+                                  cd->plain_hdr.skip, flags);
        } else if (isLUKS(cd->type)) {
                r = key_from_file(cd, _("Enter passphrase: "), &passphrase_read,
                          &passphrase_size_read, keyfile, keyfile_size);
@@ -1503,7 +1422,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
                keyslot = r;
 
                if (name) {
-                       r = open_from_hdr_and_vk(cd, vk, name, flags);
+                       r = LUKS1_activate(cd, name, vk, flags);
                        if (r < 0)
                                goto out;
                }
@@ -1520,7 +1439,6 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
                if (name)
                        r = LOOPAES_activate(cd, name, cd->loopaes_cipher,
                                             key_count, vk,
-                                            cd->loopaes_hdr.offset,
                                             cd->loopaes_hdr.skip,
                                             flags);
        } else
@@ -1540,30 +1458,11 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
        uint32_t flags)
 {
        crypt_status_info ci;
-       struct volume_key *vk;
-       int r;
+       struct volume_key *vk = NULL;
+       int r = -EINVAL;
 
        log_dbg("Activating volume %s by volume key.", name);
 
-       /* use key directly, no hash */
-       if (isPLAIN(cd->type)) {
-               if (!volume_key || !volume_key_size || !cd->volume_key ||
-                       volume_key_size != cd->volume_key->keylength) {
-                       log_err(cd, _("Incorrect volume key specified for plain device.\n"));
-                       return -EINVAL;
-               }
-
-               return create_device_helper(cd, name, NULL,
-                       cd->plain_cipher, cd->plain_cipher_mode, NULL, volume_key, volume_key_size,
-                       cd->volume_key->keylength, cd->plain_hdr.size, cd->plain_hdr.skip,
-                       cd->plain_hdr.offset, cd->plain_uuid, flags, 0);
-       }
-
-       if (!isLUKS(cd->type)) {
-               log_err(cd, _("Device type is not properly initialised.\n"));
-               return -EINVAL;
-       }
-
        if (name) {
                ci = crypt_status(NULL, name);
                if (ci == CRYPT_INVALID)
@@ -1574,26 +1473,47 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
                }
        }
 
-       /* If key is not provided, try to use internal key */
-       if (!volume_key) {
-               if (!cd->volume_key) {
-                       log_err(cd, _("Volume key does not match the volume.\n"));
+       /* use key directly, no hash */
+       if (isPLAIN(cd->type)) {
+               if (!name)
+                       return -EINVAL;
+
+               if (!volume_key || !volume_key_size || !cd->volume_key ||
+                       volume_key_size != cd->volume_key->keylength) {
+                       log_err(cd, _("Incorrect volume key specified for plain device.\n"));
                        return -EINVAL;
                }
-               volume_key_size = cd->volume_key->keylength;
-               volume_key = cd->volume_key->key;
-       }
 
-       vk = crypt_alloc_volume_key(volume_key_size, volume_key);
-       if (!vk)
-               return -ENOMEM;
-       r = LUKS_verify_volume_key(&cd->hdr, vk);
+               vk = crypt_alloc_volume_key(volume_key_size, volume_key);
+               if (!vk)
+                       return -ENOMEM;
 
-       if (r == -EPERM)
-               log_err(cd, _("Volume key does not match the volume.\n"));
+               r = PLAIN_activate(cd, name, vk,
+                                  cd->plain_hdr.size,
+                                  cd->plain_hdr.skip, flags);
+       } else if (isLUKS(cd->type)) {
+               /* If key is not provided, try to use internal key */
+               if (!volume_key) {
+                       if (!cd->volume_key) {
+                               log_err(cd, _("Volume key does not match the volume.\n"));
+                               return -EINVAL;
+                       }
+                       volume_key_size = cd->volume_key->keylength;
+                       volume_key = cd->volume_key->key;
+               }
 
-       if (!r && name)
-               r = open_from_hdr_and_vk(cd, vk, name, flags);
+               vk = crypt_alloc_volume_key(volume_key_size, volume_key);
+               if (!vk)
+                       return -ENOMEM;
+               r = LUKS_verify_volume_key(&cd->hdr, vk);
+
+               if (r == -EPERM)
+                       log_err(cd, _("Volume key does not match the volume.\n"));
+
+               if (!r && name)
+                       r = LUKS1_activate(cd, name, vk, flags);
+       } else
+               log_err(cd, _("Device type is not properly initialised.\n"));
 
        crypt_free_volume_key(vk);
 
@@ -1642,10 +1562,9 @@ int crypt_volume_key_get(struct crypt_device *cd,
        const char *passphrase,
        size_t passphrase_size)
 {
-       struct volume_key *vk;
-       char *processed_key = NULL;
+       struct volume_key *vk = NULL;
        unsigned key_len;
-       int r;
+       int r = -EINVAL;
 
        key_len = crypt_get_volume_key_size(cd);
        if (key_len > *volume_key_size) {
@@ -1654,33 +1573,24 @@ int crypt_volume_key_get(struct crypt_device *cd,
        }
 
        if (isPLAIN(cd->type) && cd->plain_hdr.hash) {
-               processed_key = process_key(cd, cd->plain_hdr.hash, NULL, key_len,
-                                           passphrase, passphrase_size);
-               if (!processed_key) {
+               r = process_key(cd, cd->plain_hdr.hash, key_len,
+                               passphrase, passphrase_size, &vk);
+               if (r < 0)
                        log_err(cd, _("Cannot retrieve volume key for plain device.\n"));
-                       return -EINVAL;
-               }
-               memcpy(volume_key, processed_key, key_len);
-               *volume_key_size = key_len;
-               crypt_safe_free(processed_key);
-               return 0;
-       }
-
-       if (isLUKS(cd->type)) {
+       } else if (isLUKS(cd->type)) {
                r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
                                        passphrase_size, &cd->hdr, &vk, cd);
 
-               if (r >= 0) {
-                       memcpy(volume_key, vk->key, vk->keylength);
-                       *volume_key_size = vk->keylength;
-               }
+       } else
+               log_err(cd, _("This operation is not supported for %s crypt device.\n"), cd->type ?: "(none)");
 
-               crypt_free_volume_key(vk);
-               return r;
+       if (r >= 0) {
+               memcpy(volume_key, vk->key, vk->keylength);
+               *volume_key_size = vk->keylength;
        }
 
-       log_err(cd, _("This operation is not supported for %s crypt device.\n"), cd->type ?: "(none)");
-       return -EINVAL;
+       crypt_free_volume_key(vk);
+       return r;
 }
 
 int crypt_volume_key_verify(struct crypt_device *cd,
@@ -1940,14 +1850,17 @@ int crypt_get_active_device(struct crypt_device *cd __attribute__((unused)),
                            const char *name,
                            struct crypt_active_device *cad)
 {
-       int r, readonly;
+       struct crypt_dm_active_device dmd;
+       int r;
 
-       r = dm_query_device(name, NULL, &cad->size, &cad->iv_offset, &cad->offset,
-                           NULL, NULL, NULL, &readonly, NULL, NULL);
+       r = dm_query_device(name, 0, &dmd);
        if (r < 0)
                return r;
 
-       cad->flags = readonly ? CRYPT_ACTIVATE_READONLY : 0;
+       cad->offset     = dmd.offset;
+       cad->iv_offset  = dmd.iv_offset;
+       cad->size       = dmd.size;
+       cad->flags      = dmd.flags;
 
        return 0;
 }
index 7e56728..b61947b 100644 (file)
@@ -397,7 +397,7 @@ int device_check_and_adjust(struct crypt_device *cd,
                            enum devcheck device_check,
                            uint64_t *size,
                            uint64_t *offset,
-                           int *read_only)
+                           uint32_t *flags)
 {
        int r, real_readonly;
        uint64_t real_size;
@@ -442,10 +442,10 @@ int device_check_and_adjust(struct crypt_device *cd,
        }
 
        if (real_readonly)
-               *read_only = 1;
+               *flags |= CRYPT_ACTIVATE_READONLY;
 
        log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".",
-               *size, *read_only ? "RO" : "RW", *offset);
+               *size, real_readonly ? "RO" : "RW", *offset);
        return 0;
 }
 
index 59b29a8..2dd13f6 100644 (file)
@@ -13,27 +13,43 @@ struct crypt_device;
 #define DM_PLAIN64_SUPPORTED  (1 << 3) /* plain64 IV */
 uint32_t dm_flags(void);
 
+#define DM_ACTIVE_DEVICE       (1 << 0)
+#define DM_ACTIVE_CIPHER       (1 << 1)
+#define DM_ACTIVE_UUID         (1 << 2)
+#define DM_ACTIVE_KEY          (1 << 3)
+
+#define DM_ACTIVE_ALL ( \
+       DM_ACTIVE_DEVICE | \
+       DM_ACTIVE_CIPHER | \
+       DM_ACTIVE_UUID | \
+       DM_ACTIVE_KEY)
+
+struct crypt_dm_active_device {
+       const char *device;
+       const char *cipher;
+       const char *uuid;
+       char *key;
+       size_t key_size;
+
+       /* struct crypt_active_device */
+       uint64_t offset;        /* offset in sectors */
+       uint64_t iv_offset;     /* IV initilisation sector */
+       uint64_t size;          /* active device size */
+       uint32_t flags;         /* activation flags */
+};
+
 const char *dm_get_dir(void);
 int dm_init(struct crypt_device *context, int check_kernel);
 void dm_exit(void);
 int dm_remove_device(const char *name, int force, uint64_t size);
 int dm_status_device(const char *name);
-int dm_query_device(const char *name,
-                   char **device,
-                   uint64_t *size,
-                   uint64_t *skip,
-                   uint64_t *offset,
-                   char **cipher,
-                   int *key_size,
-                   char **key,
-                   int *read_only,
-                   int *suspended,
-                   char **uuid);
-int dm_create_device(const char *name, const char *device, const char *cipher,
-                    const char *type, const char *uuid,
-                    uint64_t size, uint64_t skip, uint64_t offset,
-                    size_t key_size, const char *key,
-                    int read_only, int reload);
+int dm_status_suspended(const char *name);
+int dm_query_device(const char *name, uint32_t get_flags,
+                   struct crypt_dm_active_device *dmd);
+int dm_create_device(const char *name,
+                     const char *type,
+                     struct crypt_dm_active_device *dmd,
+                     int reload);
 int dm_suspend_and_wipe_key(const char *name);
 int dm_resume_and_reinstate_key(const char *name,
                                size_t key_size,
index d281565..6156a0d 100644 (file)
@@ -33,6 +33,8 @@ struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key)
        vk->keylength = keylength;
        if (key)
                memcpy(&vk->key, key, keylength);
+       else
+               memset(&vk->key, 0, keylength);
 
        return vk;
 }