* grub-core/disk/AFSplitter.c: Remove variable length arrays.
* grub-core/disk/cryptodisk.c: Likewise. * grub-core/disk/geli.c: Likewise. * grub-core/disk/luks.c: Likewise.
This commit is contained in:
parent
15decd26cc
commit
c35fcdc0b7
5 changed files with 61 additions and 23 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2013-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/disk/AFSplitter.c: Remove variable length arrays.
|
||||||
|
* grub-core/disk/cryptodisk.c: Likewise.
|
||||||
|
* grub-core/disk/geli.c: Likewise.
|
||||||
|
* grub-core/disk/luks.c: Likewise.
|
||||||
|
|
||||||
2013-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/tests/legacy_password_test.c: New test.
|
* grub-core/tests/legacy_password_test.c: New test.
|
||||||
|
|
|
@ -37,8 +37,8 @@ diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||||
|
|
||||||
grub_size_t fullblocks = size / hash->mdlen;
|
grub_size_t fullblocks = size / hash->mdlen;
|
||||||
int padding = size % hash->mdlen;
|
int padding = size % hash->mdlen;
|
||||||
grub_uint8_t final[hash->mdlen];
|
grub_uint8_t final[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
grub_uint8_t temp[sizeof (IV) + hash->mdlen];
|
grub_uint8_t temp[sizeof (IV) + GRUB_CRYPTO_MAX_MDLEN];
|
||||||
|
|
||||||
/* hash block the whole data set with different IVs to produce
|
/* hash block the whole data set with different IVs to produce
|
||||||
* more than just a single data block
|
* more than just a single data block
|
||||||
|
@ -76,6 +76,9 @@ AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst,
|
||||||
if (bufblock == NULL)
|
if (bufblock == NULL)
|
||||||
return GPG_ERR_OUT_OF_MEMORY;
|
return GPG_ERR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
|
|
||||||
grub_memset (bufblock, 0, blocksize);
|
grub_memset (bufblock, 0, blocksize);
|
||||||
for (i = 0; i < blocknumbers - 1; i++)
|
for (i = 0; i < blocknumbers - 1; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,7 +109,9 @@ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *iv)
|
void *iv)
|
||||||
{
|
{
|
||||||
grub_uint8_t *inptr, *outptr, *end;
|
grub_uint8_t *inptr, *outptr, *end;
|
||||||
grub_uint8_t ivt[cipher->cipher->blocksize];
|
grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
|
||||||
|
if (cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
if (!cipher->cipher->decrypt)
|
if (!cipher->cipher->decrypt)
|
||||||
return GPG_ERR_NOT_SUPPORTED;
|
return GPG_ERR_NOT_SUPPORTED;
|
||||||
if (size % cipher->cipher->blocksize != 0)
|
if (size % cipher->cipher->blocksize != 0)
|
||||||
|
@ -132,7 +134,9 @@ grub_crypto_pcbc_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *iv)
|
void *iv)
|
||||||
{
|
{
|
||||||
grub_uint8_t *inptr, *outptr, *end;
|
grub_uint8_t *inptr, *outptr, *end;
|
||||||
grub_uint8_t ivt[cipher->cipher->blocksize];
|
grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
|
||||||
|
if (cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
if (!cipher->cipher->decrypt)
|
if (!cipher->cipher->decrypt)
|
||||||
return GPG_ERR_NOT_SUPPORTED;
|
return GPG_ERR_NOT_SUPPORTED;
|
||||||
if (size % cipher->cipher->blocksize != 0)
|
if (size % cipher->cipher->blocksize != 0)
|
||||||
|
@ -218,6 +222,9 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||||
grub_size_t i;
|
grub_size_t i;
|
||||||
gcry_err_code_t err;
|
gcry_err_code_t err;
|
||||||
|
|
||||||
|
if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
|
|
||||||
/* The only mode without IV. */
|
/* The only mode without IV. */
|
||||||
if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
|
if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
|
||||||
return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len)
|
return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len)
|
||||||
|
@ -228,7 +235,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||||
grub_size_t sz = ((dev->cipher->cipher->blocksize
|
grub_size_t sz = ((dev->cipher->cipher->blocksize
|
||||||
+ sizeof (grub_uint32_t) - 1)
|
+ sizeof (grub_uint32_t) - 1)
|
||||||
/ sizeof (grub_uint32_t));
|
/ sizeof (grub_uint32_t));
|
||||||
grub_uint32_t iv[sz];
|
grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4];
|
||||||
|
|
||||||
if (dev->rekey)
|
if (dev->rekey)
|
||||||
{
|
{
|
||||||
|
@ -242,7 +249,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_memset (iv, 0, sz * sizeof (iv[0]));
|
grub_memset (iv, 0, sizeof (iv));
|
||||||
switch (dev->mode_iv)
|
switch (dev->mode_iv)
|
||||||
{
|
{
|
||||||
case GRUB_CRYPTODISK_MODE_IV_NULL:
|
case GRUB_CRYPTODISK_MODE_IV_NULL:
|
||||||
|
@ -250,9 +257,11 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||||
case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
|
case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
|
||||||
{
|
{
|
||||||
grub_uint64_t tmp;
|
grub_uint64_t tmp;
|
||||||
GRUB_PROPERLY_ALIGNED_ARRAY (ctx, dev->iv_hash->contextsize);
|
void *ctx;
|
||||||
|
|
||||||
grub_memset (ctx, 0, sizeof (ctx));
|
ctx = grub_zalloc (dev->iv_hash->contextsize);
|
||||||
|
if (!ctx)
|
||||||
|
return GPG_ERR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
tmp = grub_cpu_to_le64 (sector << dev->log_sector_size);
|
tmp = grub_cpu_to_le64 (sector << dev->log_sector_size);
|
||||||
dev->iv_hash->init (ctx);
|
dev->iv_hash->init (ctx);
|
||||||
|
@ -261,6 +270,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||||
dev->iv_hash->final (ctx);
|
dev->iv_hash->final (ctx);
|
||||||
|
|
||||||
grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
|
grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
|
||||||
|
grub_free (ctx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
|
case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
|
||||||
|
@ -407,7 +417,9 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke
|
||||||
if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
|
if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
|
||||||
{
|
{
|
||||||
grub_size_t essiv_keysize = dev->essiv_hash->mdlen;
|
grub_size_t essiv_keysize = dev->essiv_hash->mdlen;
|
||||||
grub_uint8_t hashed_key[essiv_keysize];
|
grub_uint8_t hashed_key[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
|
if (essiv_keysize > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
|
|
||||||
grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize);
|
grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize);
|
||||||
err = grub_crypto_cipher_set_key (dev->essiv_cipher,
|
err = grub_crypto_cipher_set_key (dev->essiv_cipher,
|
||||||
|
|
|
@ -146,7 +146,10 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno)
|
||||||
grub_uint64_t zone;
|
grub_uint64_t zone;
|
||||||
} __attribute__ ((packed)) tohash
|
} __attribute__ ((packed)) tohash
|
||||||
= { {'e', 'k', 'e', 'y'}, grub_cpu_to_le64 (zoneno) };
|
= { {'e', 'k', 'e', 'y'}, grub_cpu_to_le64 (zoneno) };
|
||||||
GRUB_PROPERLY_ALIGNED_ARRAY (key, dev->hash->mdlen);
|
GRUB_PROPERLY_ALIGNED_ARRAY (key, GRUB_CRYPTO_MAX_MDLEN);
|
||||||
|
|
||||||
|
if (dev->hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return GPG_ERR_INV_ARG;
|
||||||
|
|
||||||
grub_dprintf ("geli", "rekeying %" PRIuGRUB_UINT64_T " keysize=%d\n",
|
grub_dprintf ("geli", "rekeying %" PRIuGRUB_UINT64_T " keysize=%d\n",
|
||||||
zoneno, dev->rekey_derived_size);
|
zoneno, dev->rekey_derived_size);
|
||||||
|
@ -163,11 +166,13 @@ static inline gcry_err_code_t
|
||||||
make_uuid (const struct grub_geli_phdr *header,
|
make_uuid (const struct grub_geli_phdr *header,
|
||||||
char *uuid)
|
char *uuid)
|
||||||
{
|
{
|
||||||
grub_uint8_t uuidbin[GRUB_MD_SHA256->mdlen];
|
grub_uint8_t uuidbin[GRUB_CRYPTODISK_MAX_UUID_LENGTH];
|
||||||
gcry_err_code_t err;
|
gcry_err_code_t err;
|
||||||
grub_uint8_t *iptr;
|
grub_uint8_t *iptr;
|
||||||
char *optr;
|
char *optr;
|
||||||
|
|
||||||
|
if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH)
|
||||||
|
return GPG_ERR_TOO_LARGE;
|
||||||
err = grub_crypto_hmac_buffer (GRUB_MD_SHA256,
|
err = grub_crypto_hmac_buffer (GRUB_MD_SHA256,
|
||||||
header->salt, sizeof (header->salt),
|
header->salt, sizeof (header->salt),
|
||||||
"uuid", sizeof ("uuid") - 1, uuidbin);
|
"uuid", sizeof ("uuid") - 1, uuidbin);
|
||||||
|
@ -175,7 +180,7 @@ make_uuid (const struct grub_geli_phdr *header,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
optr = uuid;
|
optr = uuid;
|
||||||
for (iptr = uuidbin; iptr < &uuidbin[ARRAY_SIZE (uuidbin)]; iptr++)
|
for (iptr = uuidbin; iptr < &uuidbin[GRUB_MD_SHA256->mdlen]; iptr++)
|
||||||
{
|
{
|
||||||
grub_snprintf (optr, 3, "%02x", *iptr);
|
grub_snprintf (optr, 3, "%02x", *iptr);
|
||||||
optr += 2;
|
optr += 2;
|
||||||
|
@ -242,10 +247,13 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||||
const struct gcry_cipher_spec *ciph;
|
const struct gcry_cipher_spec *ciph;
|
||||||
const char *ciphername = NULL;
|
const char *ciphername = NULL;
|
||||||
gcry_err_code_t gcry_err;
|
gcry_err_code_t gcry_err;
|
||||||
char uuid[GRUB_MD_SHA256->mdlen * 2 + 1];
|
char uuid[GRUB_CRYPTODISK_MAX_UUID_LENGTH];
|
||||||
grub_disk_addr_t sector;
|
grub_disk_addr_t sector;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
|
if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
sector = grub_disk_get_size (disk);
|
sector = grub_disk_get_size (disk);
|
||||||
if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
|
if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -379,10 +387,10 @@ static grub_err_t
|
||||||
recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
{
|
{
|
||||||
grub_size_t keysize;
|
grub_size_t keysize;
|
||||||
grub_uint8_t digest[dev->hash->mdlen];
|
grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
grub_uint8_t geomkey[dev->hash->mdlen];
|
grub_uint8_t geomkey[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
grub_uint8_t verify_key[dev->hash->mdlen];
|
grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
grub_uint8_t zero[dev->cipher->cipher->blocksize];
|
grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
|
||||||
char passphrase[MAX_PASSPHRASE] = "";
|
char passphrase[MAX_PASSPHRASE] = "";
|
||||||
unsigned i;
|
unsigned i;
|
||||||
gcry_err_code_t gcry_err;
|
gcry_err_code_t gcry_err;
|
||||||
|
@ -391,6 +399,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
grub_disk_addr_t sector;
|
grub_disk_addr_t sector;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
|
if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||||
|
return grub_error (GRUB_ERR_BUG, "cipher block is too long");
|
||||||
|
|
||||||
|
if (dev->hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||||
|
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||||
|
|
||||||
sector = grub_disk_get_size (source);
|
sector = grub_disk_get_size (source);
|
||||||
if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
|
if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
|
||||||
return grub_error (GRUB_ERR_BUG, "not a geli");
|
return grub_error (GRUB_ERR_BUG, "not a geli");
|
||||||
|
@ -452,12 +466,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
||||||
sizeof (geomkey), "\1", 1, digest);
|
dev->hash->mdlen, "\1", 1, digest);
|
||||||
if (gcry_err)
|
if (gcry_err)
|
||||||
return grub_crypto_gcry_error (gcry_err);
|
return grub_crypto_gcry_error (gcry_err);
|
||||||
|
|
||||||
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
||||||
sizeof (geomkey), "\0", 1, verify_key);
|
dev->hash->mdlen, "\0", 1, verify_key);
|
||||||
if (gcry_err)
|
if (gcry_err)
|
||||||
return grub_crypto_gcry_error (gcry_err);
|
return grub_crypto_gcry_error (gcry_err);
|
||||||
|
|
||||||
|
@ -467,7 +481,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
for (i = 0; i < ARRAY_SIZE (header.keys); i++)
|
for (i = 0; i < ARRAY_SIZE (header.keys); i++)
|
||||||
{
|
{
|
||||||
struct grub_geli_key candidate_key;
|
struct grub_geli_key candidate_key;
|
||||||
grub_uint8_t key_hmac[dev->hash->mdlen];
|
grub_uint8_t key_hmac[GRUB_CRYPTO_MAX_MDLEN];
|
||||||
|
|
||||||
/* Check if keyslot is enabled. */
|
/* Check if keyslot is enabled. */
|
||||||
if (! (header.keys_used & (1 << i)))
|
if (! (header.keys_used & (1 << i)))
|
||||||
|
@ -488,7 +502,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||||
return grub_crypto_gcry_error (gcry_err);
|
return grub_crypto_gcry_error (gcry_err);
|
||||||
|
|
||||||
gcry_err = grub_crypto_hmac_buffer (dev->hash, verify_key,
|
gcry_err = grub_crypto_hmac_buffer (dev->hash, verify_key,
|
||||||
sizeof (verify_key),
|
dev->hash->mdlen,
|
||||||
&candidate_key,
|
&candidate_key,
|
||||||
(sizeof (candidate_key)
|
(sizeof (candidate_key)
|
||||||
- sizeof (candidate_key.hmac)),
|
- sizeof (candidate_key.hmac)),
|
||||||
|
|
|
@ -316,6 +316,8 @@ luks_recover_key (grub_disk_t source,
|
||||||
|
|
||||||
grub_puts_ (N_("Attempting to decrypt master key..."));
|
grub_puts_ (N_("Attempting to decrypt master key..."));
|
||||||
keysize = grub_be_to_cpu32 (header.keyBytes);
|
keysize = grub_be_to_cpu32 (header.keyBytes);
|
||||||
|
if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN)
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "key is too long");
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
||||||
if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
|
if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
|
||||||
|
@ -344,8 +346,8 @@ luks_recover_key (grub_disk_t source,
|
||||||
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
||||||
{
|
{
|
||||||
gcry_err_code_t gcry_err;
|
gcry_err_code_t gcry_err;
|
||||||
grub_uint8_t candidate_key[keysize];
|
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
grub_uint8_t digest[keysize];
|
grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
|
||||||
/* Check if keyslot is enabled. */
|
/* Check if keyslot is enabled. */
|
||||||
if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)
|
if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)
|
||||||
|
|
Loading…
Reference in a new issue