]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/disk/AFSplitter.c: Remove variable length arrays.
authorVladimir Serbinenko <phcoder@gmail.com>
Tue, 12 Nov 2013 01:48:02 +0000 (02:48 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Tue, 12 Nov 2013 01:48:02 +0000 (02:48 +0100)
* grub-core/disk/cryptodisk.c: Likewise.
* grub-core/disk/geli.c: Likewise.
* grub-core/disk/luks.c: Likewise.

ChangeLog
grub-core/disk/AFSplitter.c
grub-core/disk/cryptodisk.c
grub-core/disk/geli.c
grub-core/disk/luks.c

index dc1699e977139cf783934209ac4e756eb55b5c71..661d4d2e8076b7ee33e176d8d46b08a609104870 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * grub-core/tests/legacy_password_test.c: New test.
index ebcc352215d8931171a10d34ef85aa009c528292..d76a1c44747db673b14772281efe2889350131c4 100644 (file)
@@ -37,8 +37,8 @@ diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src,
 
   grub_size_t fullblocks = size / hash->mdlen;
   int padding = size % hash->mdlen;
-  grub_uint8_t final[hash->mdlen];
-  grub_uint8_t temp[sizeof (IV) + hash->mdlen];
+  grub_uint8_t final[GRUB_CRYPTO_MAX_MDLEN];
+  grub_uint8_t temp[sizeof (IV) + GRUB_CRYPTO_MAX_MDLEN];
 
   /* hash block the whole data set with different IVs to produce
    * 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)
     return GPG_ERR_OUT_OF_MEMORY;
 
+  if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
+    return GPG_ERR_INV_ARG;
+
   grub_memset (bufblock, 0, blocksize);
   for (i = 0; i < blocknumbers - 1; i++)
     {
index 1b40afc9d175134710a24508109e5864d9ad7855..a8a9b7171263c052c0b138c84edb79a771ca0eeb 100644 (file)
@@ -109,7 +109,9 @@ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher,
                         void *iv)
 {
   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)
     return GPG_ERR_NOT_SUPPORTED;
   if (size % cipher->cipher->blocksize != 0)
@@ -132,7 +134,9 @@ grub_crypto_pcbc_encrypt (grub_crypto_cipher_handle_t cipher,
                          void *iv)
 {
   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)
     return GPG_ERR_NOT_SUPPORTED;
   if (size % cipher->cipher->blocksize != 0)
@@ -218,6 +222,9 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
   grub_size_t i;
   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.  */
   if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
     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
                         + sizeof (grub_uint32_t) - 1)
                        / sizeof (grub_uint32_t));
-      grub_uint32_t iv[sz];
+      grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4];
 
       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)
        {
        case GRUB_CRYPTODISK_MODE_IV_NULL:
@@ -250,9 +257,11 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
        case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
          {
            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);
            dev->iv_hash->init (ctx);
@@ -261,6 +270,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
            dev->iv_hash->final (ctx);
 
            grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
+           grub_free (ctx);
          }
          break;
        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)
     {
       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);
       err = grub_crypto_cipher_set_key (dev->essiv_cipher,
index 7e3e09e72886eaf3d81ab37214bb872bdc69f79a..73b325c948591c7947b6f53db6a5bd8fccae2f16 100644 (file)
@@ -146,7 +146,10 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno)
     grub_uint64_t zone;
   } __attribute__ ((packed)) tohash
       = { {'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",
                zoneno, dev->rekey_derived_size);
@@ -163,11 +166,13 @@ static inline gcry_err_code_t
 make_uuid (const struct grub_geli_phdr *header,
           char *uuid)
 {
-  grub_uint8_t uuidbin[GRUB_MD_SHA256->mdlen];
+  grub_uint8_t uuidbin[GRUB_CRYPTODISK_MAX_UUID_LENGTH];
   gcry_err_code_t err;
   grub_uint8_t *iptr;
   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,
                                 header->salt, sizeof (header->salt),
                                 "uuid", sizeof ("uuid") - 1, uuidbin);
@@ -175,7 +180,7 @@ make_uuid (const struct grub_geli_phdr *header,
     return err;
 
   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);
       optr += 2;
@@ -242,10 +247,13 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
   const struct gcry_cipher_spec *ciph;
   const char *ciphername = NULL;
   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_err_t err;
 
+  if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH)
+    return NULL;
+
   sector = grub_disk_get_size (disk);
   if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
     return NULL;
@@ -379,10 +387,10 @@ static grub_err_t
 recover_key (grub_disk_t source, grub_cryptodisk_t dev)
 {
   grub_size_t keysize;
-  grub_uint8_t digest[dev->hash->mdlen];
-  grub_uint8_t geomkey[dev->hash->mdlen];
-  grub_uint8_t verify_key[dev->hash->mdlen];
-  grub_uint8_t zero[dev->cipher->cipher->blocksize];
+  grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
+  grub_uint8_t geomkey[GRUB_CRYPTO_MAX_MDLEN];
+  grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN];
+  grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
   char passphrase[MAX_PASSPHRASE] = "";
   unsigned i;
   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_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);
   if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0)
     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,
-                                     sizeof (geomkey), "\1", 1, digest);
+                                     dev->hash->mdlen, "\1", 1, digest);
   if (gcry_err)
     return grub_crypto_gcry_error (gcry_err);
 
   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)
     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++)
     {
       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.  */
       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);
 
       gcry_err = grub_crypto_hmac_buffer (dev->hash, verify_key,
-                                         sizeof (verify_key), 
+                                         dev->hash->mdlen,
                                          &candidate_key,
                                          (sizeof (candidate_key)
                                           - sizeof (candidate_key.hmac)),
index b9805529480beb055476e0464391af9aab238cb1..46f47c2b6a8c4a853bc8421886ecd426d1a3bf26 100644 (file)
@@ -316,6 +316,8 @@ luks_recover_key (grub_disk_t source,
 
   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");
 
   for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
     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++)
     {
       gcry_err_code_t gcry_err;
-      grub_uint8_t candidate_key[keysize];
-      grub_uint8_t digest[keysize];
+      grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
+      grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN];
 
       /* Check if keyslot is enabled.  */
       if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)