return 0;
}
-static int verify_other_keyslot(struct crypt_device *cd,
- const char *key_file,
- int keyIndex)
-{
- struct volume_key *vk = NULL;
- crypt_keyslot_info ki;
- int openedIndex, r;
- char *password = NULL;
- size_t passwordLen;
-
- r = crypt_get_key(_("Enter any remaining LUKS passphrase: "),
- &password, &passwordLen, 0, key_file, cd->timeout,
- cd->password_verify, cd);
- if(r < 0)
- goto out;
-
- ki = crypt_keyslot_status(cd, keyIndex);
- if (ki == CRYPT_SLOT_ACTIVE) /* Not last slot */
- LUKS_keyslot_set(&cd->hdr, keyIndex, 0);
-
- openedIndex = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT,
- password, passwordLen,
- &cd->hdr, &vk, cd);
-
- if (ki == CRYPT_SLOT_ACTIVE)
- LUKS_keyslot_set(&cd->hdr, keyIndex, 1);
-
- if (openedIndex < 0)
- r = -EPERM;
- else
- log_verbose(cd, _("Key slot %d verified.\n"), openedIndex);
-out:
- crypt_free_volume_key(vk);
- crypt_safe_free(password);
- return r;
-}
-
-static int find_keyslot_by_passphrase(struct crypt_device *cd,
- const char *key_file,
- char *message)
-{
- struct volume_key *vk = NULL;
- char *password = NULL;
- size_t passwordLen;
- int r;
-
- r = crypt_get_key(message,&password,&passwordLen, 0, key_file,
- cd->timeout, cd->password_verify, cd);
- if (r < 0)
- goto out;
-
- r = LUKS_open_key_with_hdr(cd->device, CRYPT_ANY_SLOT, password,
- passwordLen, &cd->hdr, &vk, cd);
-out:
- crypt_free_volume_key(vk);
- crypt_safe_free(password);
- return r;
-}
-
-static int luks_remove_helper(struct crypt_device *cd,
- int key_slot,
- const char *other_key_file,
- const char *key_file,
- int verify)
-{
- crypt_keyslot_info ki;
- int r = -EINVAL;
-
- if (key_slot == CRYPT_ANY_SLOT) {
- key_slot = find_keyslot_by_passphrase(cd, key_file,
- _("Enter LUKS passphrase to be deleted: "));
- if(key_slot < 0) {
- r = -EPERM;
- goto out;
- }
-
- log_std(cd, _("Key slot %d selected for deletion.\n"), key_slot);
- }
-
- ki = crypt_keyslot_status(cd, key_slot);
- if (ki == CRYPT_SLOT_INVALID) {
- log_err(cd, _("Key slot %d is invalid, please select between 0 and %d.\n"),
- key_slot, LUKS_NUMKEYS - 1);
- r = -EINVAL;
- goto out;
- }
- if (ki <= CRYPT_SLOT_INACTIVE) {
- log_err(cd, _("Key %d not active. Can't wipe.\n"), key_slot);
- r = -EINVAL;
- goto out;
- }
-
- if (ki == CRYPT_SLOT_ACTIVE_LAST && cd->confirm &&
- !(cd->confirm(_("This is the last keyslot."
- " Device will become unusable after purging this key."),
- cd->confirm_usrptr))) {
- r = -EINVAL;
- goto out;
- }
-
- if(verify)
- r = verify_other_keyslot(cd, other_key_file, key_slot);
- else
- r = 0;
-
- if (!r)
- r = crypt_keyslot_destroy(cd, key_slot);
-out:
- return (r < 0) ? r : 0;
-}
-
static int create_device_helper(struct crypt_device *cd,
const char *name,
const char *hash,
return r;
}
-static void log_wrapper(int level, const char *msg, void *usrptr)
-{
- void (*xlog)(int level, char *msg) = usrptr;
- xlog(level, (char *)msg);
-}
-
-static int yesDialog_wrapper(const char *msg, void *usrptr)
-{
- int (*xyesDialog)(char *msg) = usrptr;
- return xyesDialog((char*)msg);
-}
-
int crypt_confirm(struct crypt_device *cd, const char *msg)
{
if (!cd || !cd->confirm)
cd->timeout, 0, cd);
}
-static int _crypt_init(struct crypt_device **cd,
- const char *type,
- struct crypt_options *options,
- int load, int need_dm)
-{
- int init_by_name, r;
-
- /* if it is plain device and mapping table is being reloaded
- initialize it by name*/
- init_by_name = (type && !strcmp(type, CRYPT_PLAIN) && load);
-
- /* Some of old API calls do not require DM in kernel,
- fake initialisation by initialise it with kernel_check disabled */
- if (!need_dm)
- (void)dm_init(NULL, 0);
- if (init_by_name)
- r = crypt_init_by_name(cd, options->name);
- else
- r = crypt_init(cd, options->device);
- if (!need_dm)
- dm_exit();
-
- if (r)
- return -EINVAL;
-
- crypt_set_log_callback(*cd, log_wrapper, options->icb->log);
- crypt_set_confirm_callback(*cd, yesDialog_wrapper, options->icb->yesDialog);
-
- crypt_set_timeout(*cd, options->timeout);
- crypt_set_password_retry(*cd, options->tries);
- crypt_set_iterarion_time(*cd, options->iteration_time ?: 1000);
- crypt_set_password_verify(*cd, options->flags & CRYPT_FLAG_VERIFY);
-
- if (load && !init_by_name)
- r = crypt_load(*cd, type, NULL);
-
- if (!r && type && !(*cd)->type) {
- (*cd)->type = strdup(type);
- if (!(*cd)->type)
- r = -ENOMEM;
- }
-
- if (r)
- crypt_free(*cd);
-
- return r;
-}
-
void crypt_set_log_callback(struct crypt_device *cd,
void (*log)(int level, const char *msg, void *usrptr),
void *usrptr)
cd->password_usrptr = usrptr;
}
-/* OPTIONS: name, cipher, device, hash, key_file, key_size, key_slot,
- * offset, size, skip, timeout, tries, passphrase_fd (ignored),
- * flags, icb */
-static int crypt_create_and_update_device(struct crypt_options *options, int update)
-{
- struct crypt_device *cd = NULL;
- char *passphrase = NULL;
- size_t passphrase_size = 0;
- uint32_t activation_flags;
- int r;
-
- activation_flags = options->flags & CRYPT_FLAG_READONLY ?
- CRYPT_ACTIVATE_READONLY : 0;
-
- r = _crypt_init(&cd, CRYPT_PLAIN, options, 0, 1);
- if (r)
- return r;
-
- r = crypt_get_key(_("Enter passphrase: "), &passphrase, &passphrase_size,
- options->key_size, options->key_file,
- cd->timeout, cd->password_verify, cd);
- if (!r)
- r = create_device_helper(cd, options->name, options->hash,
- options->cipher, NULL, options->key_file,
- passphrase, passphrase_size,
- options->key_size, options->size, options->skip,
- options->offset, NULL, activation_flags, update);
-
- crypt_safe_free(passphrase);
- crypt_free(cd);
- return r;
-}
-
-int crypt_create_device(struct crypt_options *options)
-{
- return crypt_create_and_update_device(options, 0);
-}
-
-int crypt_update_device(struct crypt_options *options)
-{
- return crypt_create_and_update_device(options, 1);
-}
-
-/* OPTIONS: name, size, icb */
-int crypt_resize_device(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- char *device = NULL, *cipher = NULL, *uuid = NULL, *key = NULL;
- const char *type = NULL;
- uint64_t size, skip, offset;
- int key_size, read_only, r;
-
- log_dbg("Resizing device %s to %" PRIu64 " sectors.", options->name, options->size);
-
- if (dm_init(NULL, 1) < 0)
- return -ENOSYS;
-
- r = dm_query_device(options->name, &device, &size, &skip, &offset,
- &cipher, &key_size, &key, &read_only, NULL, &uuid);
- if (r < 0) {
- log_err(NULL, _("Device %s is not active.\n"), options->name);
- goto out;
- }
-
- /* Try to determine type of device from UUID */
- type = CRYPT_PLAIN;
- if (uuid) {
- if (!strncmp(uuid, CRYPT_PLAIN, strlen(CRYPT_PLAIN))) {
- type = CRYPT_PLAIN;
- free (uuid);
- uuid = NULL;
- } else if (!strncmp(uuid, CRYPT_LUKS1, strlen(CRYPT_LUKS1)))
- type = CRYPT_LUKS1;
- }
-
- if (!options->device)
- options->device = device;
-
- r = _crypt_init(&cd, type, options, 1, 1);
- if (r)
- goto out;
-
- size = options->size;
- r = device_check_and_adjust(cd, device, DEV_OK, &size, &offset, &read_only);
- if (r)
- goto out;
-
- r = dm_create_device(options->name, device, cipher, type,
- crypt_get_uuid(cd), size, skip, offset,
- key_size, key, read_only, 1);
-out:
- crypt_safe_free(key);
- free(cipher);
- if (options->device == device)
- options->device = NULL;
- free(device);
- free(uuid);
- crypt_free(cd);
- dm_exit();
- return r;
-}
-
-/* OPTIONS: name, icb */
-int crypt_query_device(struct crypt_options *options)
-{
- int read_only, r;
-
- log_dbg("Query device %s.", options->name);
-
- if (dm_init(NULL, 1) < 0)
- return -ENOSYS;
-
- r = dm_status_device(options->name);
- if (r < 0)
- goto out;
-
- r = dm_query_device(options->name, (char **)&options->device, &options->size,
- &options->skip, &options->offset, (char **)&options->cipher,
- &options->key_size, NULL, &read_only, NULL, NULL);
- if (r >= 0) {
- if (read_only)
- options->flags |= CRYPT_FLAG_READONLY;
-
- options->flags |= CRYPT_FLAG_FREE_DEVICE;
- options->flags |= CRYPT_FLAG_FREE_CIPHER;
-
- r = 1;
- }
-out:
- if (r == -ENODEV)
- r = 0;
-
- dm_exit();
- return r;
-}
-
-/* OPTIONS: name, icb */
-int crypt_remove_device(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r;
-
- r = crypt_init_by_name(&cd, options->name);
- if (r == 0)
- r = crypt_deactivate(cd, options->name);
-
- crypt_free(cd);
- return r;
-
-}
-
-/* OPTIONS: device, cipher, hash, align_payload, key_size (master key), key_slot
- * new_key_file, iteration_time, timeout, flags, icb */
-int crypt_luksFormat(struct crypt_options *options)
-{
- char cipherName[LUKS_CIPHERNAME_L];
- char cipherMode[LUKS_CIPHERMODE_L];
- char *password=NULL;
- size_t passwordLen;
- struct crypt_device *cd = NULL;
- struct crypt_params_luks1 cp = {
- .hash = options->hash,
- .data_alignment = options->align_payload
- };
- int r;
-
- r = crypt_parse_name_and_mode(options->cipher, cipherName, NULL, cipherMode);
- if(r < 0) {
- log_err(cd, _("No known cipher specification pattern detected.\n"));
- return r;
- }
-
- if ((r = _crypt_init(&cd, CRYPT_LUKS1, options, 0, 1)))
- return r;
-
- if (options->key_slot >= LUKS_NUMKEYS && options->key_slot != CRYPT_ANY_SLOT) {
- log_err(cd, _("Key slot %d is invalid, please select between 0 and %d.\n"),
- options->key_slot, LUKS_NUMKEYS - 1);
- r = -EINVAL;
- goto out;
- }
-
- r = crypt_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen, 0,
- options->new_key_file, cd->timeout, cd->password_verify, cd);
-
- if(r < 0)
- goto out;
-
- r = crypt_format(cd, CRYPT_LUKS1, cipherName, cipherMode,
- NULL, NULL, options->key_size, &cp);
- if (r < 0)
- goto out;
-
- /* Add keyslot using internally stored volume key generated during format */
- r = crypt_keyslot_add_by_volume_key(cd, options->key_slot, NULL, 0,
- password, passwordLen);
-out:
- crypt_free(cd);
- crypt_safe_free(password);
- return (r < 0) ? r : 0;
-}
-
-/* OPTIONS: name, device, key_size, key_file, timeout, tries, flags, icb */
-int crypt_luksOpen(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- uint32_t flags = 0;
- int r;
-
- if (!options->name)
- return -EINVAL;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
- if (r)
- return r;
-
- if (options->flags & CRYPT_FLAG_READONLY)
- flags |= CRYPT_ACTIVATE_READONLY;
-
- if (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS)
- flags |= CRYPT_ACTIVATE_NO_UUID;
-
- if (options->key_file)
- r = crypt_activate_by_keyfile(cd, options->name,
- CRYPT_ANY_SLOT, options->key_file, 0,
- flags);
- else
- r = crypt_activate_by_passphrase(cd, options->name,
- CRYPT_ANY_SLOT, options->passphrase,
- options->passphrase ? strlen(options->passphrase) : 0,
- flags);
-
- crypt_free(cd);
- return (r < 0) ? r : 0;
-}
-
-/* OPTIONS: device, keys_slot, key_file, timeout, flags, icb */
-int crypt_luksKillSlot(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
- if (r)
- return r;
-
- r = luks_remove_helper(cd, options->key_slot, options->key_file, NULL,
- options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY);
-
- crypt_free(cd);
- return (r < 0) ? r : 0;
-}
-
-/* OPTIONS: device, new_key_file, key_file, timeout, flags, icb */
-int crypt_luksRemoveKey(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
- if (r)
- return r;
-
- r = luks_remove_helper(cd, CRYPT_ANY_SLOT, options->key_file, options->new_key_file,
- options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY);
-
- crypt_free(cd);
- return (r < 0) ? r : 0;
-}
-
-
-/* OPTIONS: device, new_key_file, key_file, key_slot, flags,
- iteration_time, timeout, icb */
-int crypt_luksAddKey(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r = -EINVAL;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 1);
- if (r)
- return r;
-
- if (options->key_file || options->new_key_file)
- r = crypt_keyslot_add_by_keyfile(cd, options->key_slot,
- options->key_file, 0,
- options->new_key_file, 0);
- else
- r = crypt_keyslot_add_by_passphrase(cd, options->key_slot,
- NULL, 0, NULL, 0);
-
- crypt_free(cd);
- return (r < 0) ? r : 0;
-}
-
-/* OPTIONS: device, icb */
-int crypt_luksUUID(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- const char *uuid;
- int r;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
- if (r)
- return r;
-
- uuid = crypt_get_uuid(cd);
- log_std(cd, "%s\n", uuid ?: "");
- crypt_free(cd);
- return 0;
-}
-
-/* OPTIONS: device, icb */
-int crypt_isLuks(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r;
-
- log_dbg("Check device %s for LUKS header.", options->device);
-
- r = init_crypto(cd);
- if (r < 0)
- return r;
-
- r = crypt_init(&cd, options->device);
- if (r < 0)
- return -EINVAL;
-
- /* Do print fail here, no need to crypt_load() */
- r = LUKS_read_phdr(cd->device, &cd->hdr, 0, cd) ? -EINVAL : 0;
-
- crypt_free(cd);
- return r;
-}
-
-/* OPTIONS: device, icb */
-int crypt_luksDump(struct crypt_options *options)
-{
- struct crypt_device *cd = NULL;
- int r;
-
- r = _crypt_init(&cd, CRYPT_LUKS1, options, 1, 0);
- if(r < 0)
- return r;
-
- r = crypt_dump(cd);
-
- crypt_free(cd);
- return r;
-}
-
void crypt_get_error(char *buf, size_t size)
{
const char *error = get_error();
buf[0] = '\0';
}
-void crypt_put_options(struct crypt_options *options)
-{
- if (options->flags & CRYPT_FLAG_FREE_DEVICE) {
- free((char *)options->device);
- options->device = NULL;
- options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
- }
- if (options->flags & CRYPT_FLAG_FREE_CIPHER) {
- free((char *)options->cipher);
- options->cipher = NULL;
- options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
- }
-}
-
const char *crypt_get_dir(void)
{
return dm_get_dir();