/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file is loosely based on FreeBSD geli implementation
(but no code was directly copied). FreeBSD geli is distributed under
following terms: */
/*-
* Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <grub/cryptodisk.h>
#include <grub/partition.h>
GRUB_MOD_LICENSE ("GPLv3+");
/* Dirty trick to solve circular dependency. */
#ifdef GRUB_UTIL
static const gcry_md_spec_t *
grub_md_sha256_real (void)
{
if (!ret)
grub_util_error ("Coulnd't load sha256");
return ret;
}
static const gcry_md_spec_t *
grub_md_sha512_real (void)
{
if (!ret)
grub_util_error ("Coulnd't load sha512");
return ret;
}
#endif
struct grub_geli_key
{
} __attribute__ ((packed));
struct grub_geli_phdr
{
} __attribute__ ((packed));
enum
{
};
/* FIXME: support version 0. */
/* FIXME: support big-endian pre-version-4 volumes. */
/* FIXME: support for keyfiles. */
/* FIXME: support for HMAC. */
const char *algorithms[] = {
[0x01] = "des",
[0x02] = "3des",
[0x03] = "blowfish",
[0x04] = "cast5",
/* FIXME: 0x05 is skipjack, but we don't have it. */
[0x0b] = "aes",
/* FIXME: 0x10 is null. */
[0x15] = "camellia128",
[0x16] = "aes"
};
static gcry_err_code_t
{
const struct {
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
}
static inline int
ascii2hex (char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0;
}
static inline gcry_err_code_t
char *uuid)
{
char *optr;
if (err)
return err;
{
optr += 2;
}
*optr = 0;
return GPG_ERR_NO_ERROR;
}
#ifdef GRUB_UTIL
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
char *
{
unsigned log_secsize;
char *uuid;
if (fd < 0)
return NULL;
grub_util_error (_("couldn't read ELI metadata"));
/* Look for GELI magic sequence. */
grub_util_error (_("wrong ELI magic or version"));
if (err)
return NULL;
return uuid;
}
#endif
static grub_cryptodisk_t
int boot_only)
{
return NULL;
/* Read the GELI header. */
if (err)
return NULL;
/* Look for GELI magic sequence. */
{
return NULL;
}
{
return NULL;
}
{
return NULL;
}
{
return NULL;
}
if (gcry_err)
{
return NULL;
}
{
return NULL;
}
{
return NULL;
}
if (!ciph)
{
return NULL;
}
/* Configure the cipher used for the bulk data. */
if (!cipher)
return NULL;
{
if (!secondary_cipher)
return NULL;
}
{
return NULL;
}
if (!newdev)
return NULL;
{
}
else
{
}
for (newdev->log_sector_size = 0;
newdev->log_sector_size++);
{
}
#ifdef GRUB_UTIL
#endif
return newdev;
}
static grub_err_t
{
unsigned i;
char *tmp;
/* Read the GELI header. */
if (err)
return err;
/* Get the passphrase from the user. */
/* Calculate the PBKDF2 of the user supplied passphrase. */
{
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
}
else
{
if (!hnd)
return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
}
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
/* Try to recover master key from each active keyslot. */
{
/* Check if keyslot is enabled. */
continue;
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
sizeof (candidate_key),
zero);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
sizeof (verify_key),
(sizeof (candidate_key)
- sizeof (candidate_key.hmac)),
key_hmac);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
continue;
/* Set the master key. */
{
real_keysize *= 2;
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
}
else
{
real_keysize *= 2;
/* For a reason I don't know, the IV key is used in rekeying. */
sizeof (candidate_key.iv_key));
>= sizeof (candidate_key.iv_key));
}
sizeof (candidate_key.iv_key));
return GRUB_ERR_NONE;
}
return GRUB_ACCESS_DENIED;
}
};
{
}
{
}