Skip to content

Commit

Permalink
Adjust to libblockdev 3.0 crypto plugin API changes
Browse files Browse the repository at this point in the history
The crypto plugin API is going through a major overhaul in 3.0.
  • Loading branch information
vojtechtrefny committed Jun 20, 2023
1 parent ea007e4 commit a04d28c
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 39 deletions.
5 changes: 3 additions & 2 deletions src/tests/dbus-tests/test_70_encrypted.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,9 @@ def _create_luks_integrity(self, device, passphrase):
extra = BlockDev.CryptoLUKSExtra()
extra.integrity = 'hmac(sha256)'

BlockDev.crypto_luks_format(device, 'aes-cbc-essiv:sha256', 512, passphrase,
None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra)
ctx = BlockDev.CryptoKeyslotContext(passphrase=passphrase)
BlockDev.crypto_luks_format(device, 'aes-cbc-essiv:sha256', 512, ctx,
0, BlockDev.CryptoLUKSVersion.LUKS2, extra)

def _get_metadata_size_from_dump(self, disk):
ret, out = self.run_command("cryptsetup luksDump %s" % disk)
Expand Down
56 changes: 38 additions & 18 deletions src/udiskslinuxencrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,28 @@ update_metadata_size (UDisksLinuxEncrypted *encrypted,
UDisksLinuxBlockObject *object)
{
UDisksLinuxDevice *device;
guint64 metadata_size;
BDCryptoLUKSInfo *info = NULL;
GError *error = NULL;

device = udisks_linux_block_object_get_device (object);

metadata_size = bd_crypto_luks_get_metadata_size (g_udev_device_get_device_file (device->udev_device),
&error);

if (error != NULL)
info = bd_crypto_luks_info (g_udev_device_get_device_file (device->udev_device),
&error);
if (!info)
{
udisks_warning ("Error getting '%s' metadata_size: %s (%s, %d)",
g_udev_device_get_device_file (device->udev_device),
error->message,
g_quark_to_string (error->domain),
error->code);
g_clear_error (&error);
udisks_encrypted_set_metadata_size (UDISKS_ENCRYPTED (encrypted), 0);
}
else
udisks_encrypted_set_metadata_size (UDISKS_ENCRYPTED (encrypted), info->metadata_size);

g_object_unref (device);
udisks_encrypted_set_metadata_size (UDISKS_ENCRYPTED (encrypted), metadata_size);
bd_crypto_luks_info_free (info);
}

static void
Expand Down Expand Up @@ -1036,6 +1038,7 @@ handle_resize (UDisksEncrypted *encrypted,
GError *error = NULL;
UDisksBaseJob *job = NULL;
GString *effective_passphrase = NULL;
BDCryptoKeyslotContext *context = NULL;

object = udisks_daemon_util_dup_object (encrypted, &error);
if (object == NULL)
Expand Down Expand Up @@ -1116,6 +1119,30 @@ handle_resize (UDisksEncrypted *encrypted,
invocation))
goto out;

if (udisks_variant_lookup_binary (options, "keyfile_contents", &effective_passphrase))
;
else if (udisks_variant_lookup_binary (options, "passphrase", &effective_passphrase))
;
else
effective_passphrase = NULL;

if (effective_passphrase)
{
context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) effective_passphrase->str,
effective_passphrase->len,
&error);
if (!context)
{
g_dbus_method_invocation_return_error (invocation,
UDISKS_ERROR,
UDISKS_ERROR_FAILED,
"Error resizing encrypted device %s: %s",
udisks_block_get_device (cleartext_block),
error->message);
goto out;
}
}

job = udisks_daemon_launch_simple_job (daemon,
UDISKS_OBJECT (object),
"encrypted-resize",
Expand All @@ -1128,21 +1155,13 @@ handle_resize (UDisksEncrypted *encrypted,
goto out;
}

if (udisks_variant_lookup_binary (options, "keyfile_contents", &effective_passphrase))
;
else if (udisks_variant_lookup_binary (options, "passphrase", &effective_passphrase))
;
else
effective_passphrase = NULL;

udisks_linux_block_encrypted_lock (block);

/* TODO: implement progress parsing for udisks_job_set_progress(_valid) */
if (! bd_crypto_luks_resize_luks2_blob (udisks_block_get_device (cleartext_block),
size / 512,
effective_passphrase ? (const guint8*) effective_passphrase->str : NULL,
effective_passphrase ? effective_passphrase->len : 0,
&error))
if (! bd_crypto_luks_resize (udisks_block_get_device (cleartext_block),
size / 512,
context,
&error))
{
g_dbus_method_invocation_return_error (invocation,
UDISKS_ERROR,
Expand All @@ -1169,6 +1188,7 @@ handle_resize (UDisksEncrypted *encrypted,
g_clear_object (&object);
g_clear_error (&error);
udisks_string_wipe_and_free (effective_passphrase);
bd_crypto_keyslot_context_free (context);
return TRUE; /* returning TRUE means that we handled the method invocation */
}

Expand Down
88 changes: 69 additions & 19 deletions src/udiskslinuxencryptedhelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ gboolean luks_format_job_func (UDisksThreadedJob *job,
{
BDCryptoLUKSVersion luks_version;
CryptoJobData *data = (CryptoJobData*) user_data;
BDCryptoKeyslotContext *context = NULL;
gboolean ret = FALSE;

if (g_strcmp0 (data->type, "luks1") == 0)
luks_version = BD_CRYPTO_LUKS_VERSION_LUKS1;
Expand All @@ -48,10 +50,15 @@ gboolean luks_format_job_func (UDisksThreadedJob *job,
return FALSE;
}

/* device, cipher, key_size, passphrase, key_file, min_entropy, luks_version, extra, error */
return bd_crypto_luks_format_luks2_blob (data->device, NULL, 0,
(const guint8*) data->passphrase->str, data->passphrase->len, 0,
luks_version, NULL, error);
context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->passphrase->str,
data->passphrase->len, error);
if (!context)
return FALSE;

/* device, cipher, key_size, context, min_entropy, luks_version, extra, error */
ret = bd_crypto_luks_format (data->device, NULL, 0, context, 0, luks_version, NULL, error);
bd_crypto_keyslot_context_free (context);
return ret;
}

gboolean luks_open_job_func (UDisksThreadedJob *job,
Expand All @@ -60,11 +67,18 @@ gboolean luks_open_job_func (UDisksThreadedJob *job,
GError **error)
{
CryptoJobData *data = (CryptoJobData*) user_data;
BDCryptoKeyslotContext *context = NULL;
gboolean ret = FALSE;

context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->passphrase->str,
data->passphrase->len, error);
if (!context)
return FALSE;

/* device, name, passphrase, key_file, read_only, error */
return bd_crypto_luks_open_blob (data->device, data->map_name,
(const guint8*) data->passphrase->str, data->passphrase->len, data->read_only,
error);
/* device, name, context, read_only, error */
ret = bd_crypto_luks_open (data->device, data->map_name, context, data->read_only, error);
bd_crypto_keyslot_context_free (context);
return ret;
}

gboolean luks_close_job_func (UDisksThreadedJob *job,
Expand All @@ -82,10 +96,26 @@ gboolean luks_change_key_job_func (UDisksThreadedJob *job,
GError **error)
{
CryptoJobData *data = (CryptoJobData*) user_data;
return bd_crypto_luks_change_key_blob (data->device,
(const guint8*) data->passphrase->str, data->passphrase->len,
(const guint8*) data->new_passphrase->str, data->new_passphrase->len,
error);
BDCryptoKeyslotContext *context = NULL;
BDCryptoKeyslotContext *ncontext = NULL;
gboolean ret = FALSE;

context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->passphrase->str,
data->passphrase->len, error);
if (!context)
return FALSE;
ncontext = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->new_passphrase->str,
data->new_passphrase->len, error);
if (!context)
{
bd_crypto_keyslot_context_free (context);
return FALSE;
}

ret = bd_crypto_luks_change_key (data->device, context, ncontext, error);
bd_crypto_keyslot_context_free (context);
bd_crypto_keyslot_context_free (ncontext);
return ret;
}

gboolean tcrypt_open_job_func (UDisksThreadedJob *job,
Expand All @@ -94,14 +124,26 @@ gboolean tcrypt_open_job_func (UDisksThreadedJob *job,
GError **error)
{
CryptoJobData *data = (CryptoJobData*) user_data;
BDCryptoKeyslotContext *context = NULL;
gboolean ret = FALSE;

/* We always use the veracrypt option, because it can unlock both VeraCrypt and legacy TrueCrypt volumes */
gboolean veracrypt = TRUE;

return bd_crypto_tc_open_full (data->device, data->map_name,
(const guint8*) data->passphrase->str, data->passphrase->len,
data->keyfiles, data->hidden, data->system, veracrypt, data->pim,
data->read_only, error);
/* passphrase can be empty for veracrypt with keyfiles */
if (data->passphrase->len > 0)
{
context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->passphrase->str,
data->passphrase->len, error);
if (!context)
return FALSE;
}

ret = bd_crypto_tc_open (data->device, data->map_name, context,
data->keyfiles, data->hidden, data->system, veracrypt, data->pim,
data->read_only, error);
bd_crypto_keyslot_context_free (context);
return ret;
}

gboolean tcrypt_close_job_func (UDisksThreadedJob *job,
Expand All @@ -119,9 +161,17 @@ gboolean bitlk_open_job_func (UDisksThreadedJob *job,
GError **error)
{
CryptoJobData *data = (CryptoJobData*) user_data;
return bd_crypto_bitlk_open (data->device, data->map_name,
(const guint8*) data->passphrase->str, data->passphrase->len,
data->read_only, error);
BDCryptoKeyslotContext *context = NULL;
gboolean ret = FALSE;

context = bd_crypto_keyslot_context_new_passphrase ((const guint8 *) data->passphrase->str,
data->passphrase->len, error);
if (!context)
return FALSE;

ret = bd_crypto_bitlk_open (data->device, data->map_name, context, data->read_only, error);
bd_crypto_keyslot_context_free (context);
return ret;
}

gboolean bitlk_close_job_func (UDisksThreadedJob *job,
Expand Down

0 comments on commit a04d28c

Please sign in to comment.