geli xts support
This commit is contained in:
parent
574d268020
commit
171e2be183
3 changed files with 34 additions and 6 deletions
|
@ -234,6 +234,11 @@ grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
|
||||||
case GRUB_CRYPTODISK_MODE_IV_PLAIN:
|
case GRUB_CRYPTODISK_MODE_IV_PLAIN:
|
||||||
iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF);
|
iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF);
|
||||||
break;
|
break;
|
||||||
|
case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
|
||||||
|
iv[1] = grub_cpu_to_le32 (sector >> (32 - dev->log_sector_size));
|
||||||
|
iv[0] = grub_cpu_to_le32 ((sector << dev->log_sector_size)
|
||||||
|
& 0xFFFFFFFF);
|
||||||
|
break;
|
||||||
case GRUB_CRYPTODISK_MODE_IV_BENBI:
|
case GRUB_CRYPTODISK_MODE_IV_BENBI:
|
||||||
{
|
{
|
||||||
grub_uint64_t num = (sector << dev->benbi_log) + 1;
|
grub_uint64_t num = (sector << dev->benbi_log) + 1;
|
||||||
|
|
|
@ -95,6 +95,7 @@ const char *algorithms[] = {
|
||||||
[0x0b] = "aes",
|
[0x0b] = "aes",
|
||||||
/* FIXME: 0x10 is null. */
|
/* FIXME: 0x10 is null. */
|
||||||
[0x15] = "camellia128",
|
[0x15] = "camellia128",
|
||||||
|
[0x16] = "aes"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_PASSPHRASE 256
|
#define MAX_PASSPHRASE 256
|
||||||
|
@ -135,7 +136,7 @@ static grub_cryptodisk_t
|
||||||
configure_ciphers (const struct grub_geli_phdr *header)
|
configure_ciphers (const struct grub_geli_phdr *header)
|
||||||
{
|
{
|
||||||
grub_cryptodisk_t newdev;
|
grub_cryptodisk_t newdev;
|
||||||
grub_crypto_cipher_handle_t cipher = NULL;
|
grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
|
||||||
const struct gcry_cipher_spec *ciph;
|
const struct gcry_cipher_spec *ciph;
|
||||||
const char *ciphername = NULL;
|
const char *ciphername = NULL;
|
||||||
const gcry_md_spec_t *hash = NULL, *iv_hash = NULL;
|
const gcry_md_spec_t *hash = NULL, *iv_hash = NULL;
|
||||||
|
@ -196,6 +197,13 @@ configure_ciphers (const struct grub_geli_phdr *header)
|
||||||
if (!cipher)
|
if (!cipher)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (grub_le_to_cpu16 (header->alg) == 0x16)
|
||||||
|
{
|
||||||
|
secondary_cipher = grub_crypto_cipher_open (ciph);
|
||||||
|
if (!secondary_cipher)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_le_to_cpu16 (header->keylen) > 1024)
|
if (grub_le_to_cpu16 (header->keylen) > 1024)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
|
||||||
|
@ -225,12 +233,20 @@ configure_ciphers (const struct grub_geli_phdr *header)
|
||||||
if (!newdev)
|
if (!newdev)
|
||||||
return NULL;
|
return NULL;
|
||||||
newdev->cipher = cipher;
|
newdev->cipher = cipher;
|
||||||
|
newdev->secondary_cipher = secondary_cipher;
|
||||||
newdev->offset = 0;
|
newdev->offset = 0;
|
||||||
newdev->source_disk = NULL;
|
newdev->source_disk = NULL;
|
||||||
newdev->benbi_log = 0;
|
newdev->benbi_log = 0;
|
||||||
|
if (grub_le_to_cpu16 (header->alg) == 0x16)
|
||||||
|
{
|
||||||
|
newdev->mode = GRUB_CRYPTODISK_MODE_XTS;
|
||||||
|
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
newdev->mode = GRUB_CRYPTODISK_MODE_CBC;
|
newdev->mode = GRUB_CRYPTODISK_MODE_CBC;
|
||||||
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH;
|
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH;
|
||||||
newdev->secondary_cipher = NULL;
|
}
|
||||||
newdev->essiv_cipher = NULL;
|
newdev->essiv_cipher = NULL;
|
||||||
newdev->essiv_hash = NULL;
|
newdev->essiv_hash = NULL;
|
||||||
newdev->hash = hash;
|
newdev->hash = hash;
|
||||||
|
@ -360,17 +376,23 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header,
|
||||||
/* Set the master key. */
|
/* Set the master key. */
|
||||||
if (!dev->rekey)
|
if (!dev->rekey)
|
||||||
{
|
{
|
||||||
|
grub_size_t real_keysize = keysize;
|
||||||
|
if (grub_le_to_cpu16 (header->alg) == 0x16)
|
||||||
|
real_keysize *= 2;
|
||||||
gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key,
|
gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key,
|
||||||
keysize);
|
real_keysize);
|
||||||
if (gcry_err)
|
if (gcry_err)
|
||||||
return grub_crypto_gcry_error (gcry_err);
|
return grub_crypto_gcry_error (gcry_err);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
grub_size_t real_keysize = keysize;
|
||||||
|
if (grub_le_to_cpu16 (header->alg) == 0x16)
|
||||||
|
real_keysize *= 2;
|
||||||
/* For a reason I don't know, the IV key is used in rekeying. */
|
/* For a reason I don't know, the IV key is used in rekeying. */
|
||||||
grub_memcpy (dev->rekey_key, candidate_key.iv_key,
|
grub_memcpy (dev->rekey_key, candidate_key.iv_key,
|
||||||
sizeof (candidate_key.iv_key));
|
sizeof (candidate_key.iv_key));
|
||||||
dev->rekey_derived_size = keysize;
|
dev->rekey_derived_size = real_keysize;
|
||||||
dev->last_rekey = -1;
|
dev->last_rekey = -1;
|
||||||
COMPILE_TIME_ASSERT (sizeof (dev->rekey_key)
|
COMPILE_TIME_ASSERT (sizeof (dev->rekey_key)
|
||||||
>= sizeof (candidate_key.iv_key));
|
>= sizeof (candidate_key.iv_key));
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef enum
|
||||||
GRUB_CRYPTODISK_MODE_IV_PLAIN64,
|
GRUB_CRYPTODISK_MODE_IV_PLAIN64,
|
||||||
GRUB_CRYPTODISK_MODE_IV_ESSIV,
|
GRUB_CRYPTODISK_MODE_IV_ESSIV,
|
||||||
GRUB_CRYPTODISK_MODE_IV_BENBI,
|
GRUB_CRYPTODISK_MODE_IV_BENBI,
|
||||||
|
GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64,
|
||||||
GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH
|
GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH
|
||||||
} grub_cryptodisk_mode_iv_t;
|
} grub_cryptodisk_mode_iv_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue