geli xts support

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-24 17:41:50 +02:00
parent 574d268020
commit 171e2be183
3 changed files with 34 additions and 6 deletions

View file

@ -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;

View file

@ -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;
newdev->mode = GRUB_CRYPTODISK_MODE_CBC; if (grub_le_to_cpu16 (header->alg) == 0x16)
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH; {
newdev->secondary_cipher = NULL; newdev->mode = GRUB_CRYPTODISK_MODE_XTS;
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64;
}
else
{
newdev->mode = GRUB_CRYPTODISK_MODE_CBC;
newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH;
}
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));

View file

@ -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;