grub_uint8_t candidate_digest[sizeof (header.mkDigest)];
unsigned i;
grub_size_t length;
- grub_err_t err;
+ grub_err_t err = GRUB_ERR_NONE;
+ char *err_msg = NULL;
grub_size_t max_stripes = 1;
char *tmp;
err = grub_disk_read (source, 0, 0, sizeof (header), &header);
if (err)
- return err;
+ goto fail;
grub_puts_ (N_("Attempting to decrypt master key..."));
keysize = grub_be_to_cpu32 (header.keyBytes);
if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN)
- return grub_error (GRUB_ERR_BAD_FS, "key is too long");
+ {
+ err = GRUB_ERR_BAD_FS;
+ err_msg = "key is too long";
+ goto fail;
+ }
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
split_key = grub_malloc (keysize * max_stripes);
if (!split_key)
- return grub_errno;
+ {
+ err = grub_errno;
+ goto fail;
+ }
/* Get the passphrase from the user. */
tmp = NULL;
grub_free (tmp);
if (!grub_password_get (passphrase, MAX_PASSPHRASE))
{
- grub_free (split_key);
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+ err = GRUB_ERR_BAD_ARGUMENT;
+ err_msg = "Passphrase not supplied";
+ goto fail;
}
/* Try to recover master key from each active keyslot. */
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
grub_dprintf ("luks", "PBKDF2 done\n");
gcry_err = grub_cryptodisk_setkey (dev, digest, keysize);
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
[i].keyMaterialOffset), 0,
length, split_key);
if (err)
- {
- grub_free (split_key);
- return err;
- }
+ goto fail;
gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0);
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
/* Merge the decrypted key material to get the candidate master key. */
grub_be_to_cpu32 (header.keyblock[i].stripes));
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
grub_dprintf ("luks", "candidate key recovered\n");
sizeof (candidate_digest));
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
/* Compare the calculated PBKDF2 to the digest stored
gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
if (gcry_err)
{
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
+ err = grub_crypto_gcry_error (gcry_err);
+ goto fail;
}
- grub_free (split_key);
-
- return GRUB_ERR_NONE;
+ err = GRUB_ERR_NONE;
}
+fail:
grub_free (split_key);
- return GRUB_ACCESS_DENIED;
+ if(err && err_msg)
+ grub_error (err, errmsg);
+
+ return err;
}
struct grub_cryptodisk_dev luks_crypto = {