Various cleanups and wrapper functions. Allocate disk id for LUKS.
This commit is contained in:
parent
63d7ad01eb
commit
414f919237
4 changed files with 206 additions and 39 deletions
|
@ -33,8 +33,6 @@
|
|||
#include <grub/command.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
extern gcry_md_spec_t _gcry_digest_spec_md5;
|
||||
|
||||
/* This prefix is used by xnu and boot-132 to hash
|
||||
together with volume serial. */
|
||||
static grub_uint8_t hash_prefix[16]
|
||||
|
@ -49,18 +47,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_uint8_t *xnu_uuid;
|
||||
char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
|
||||
char *ptr;
|
||||
grub_uint8_t ctx[_gcry_digest_spec_md5.contextsize];
|
||||
grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
|
||||
|
||||
serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
|
||||
|
||||
_gcry_digest_spec_md5.init (&ctx);
|
||||
_gcry_digest_spec_md5.write (&ctx, hash_prefix, sizeof (hash_prefix));
|
||||
_gcry_digest_spec_md5.write (&ctx, &serial, sizeof (serial));
|
||||
_gcry_digest_spec_md5.final (&ctx);
|
||||
xnu_uuid = _gcry_digest_spec_md5.read (&ctx);
|
||||
GRUB_MD_MD5->init (&ctx);
|
||||
GRUB_MD_MD5->write (&ctx, hash_prefix, sizeof (hash_prefix));
|
||||
GRUB_MD_MD5->write (&ctx, &serial, sizeof (serial));
|
||||
GRUB_MD_MD5->final (&ctx);
|
||||
xnu_uuid = GRUB_MD_MD5->read (&ctx);
|
||||
|
||||
grub_sprintf (uuid_string,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
|
|
|
@ -26,6 +26,20 @@ conf = open (os.path.join (outdir, "conf", "gcry.rmk"), "w")
|
|||
conf.write ("# -*- makefile -*-\n\n")
|
||||
chlog = ""
|
||||
|
||||
mdblocksizes = {"_gcry_digest_spec_crc32" : 1,
|
||||
"_gcry_digest_spec_crc32_rfc1510" : 1,
|
||||
"_gcry_digest_spec_crc24_rfc2440" : 1,
|
||||
"_gcry_digest_spec_md4" : 64,
|
||||
"_gcry_digest_spec_md5" : 64,
|
||||
"_gcry_digest_spec_rmd160" : 64,
|
||||
"_gcry_digest_spec_sha1" : 64,
|
||||
"_gcry_digest_spec_sha224" : 64,
|
||||
"_gcry_digest_spec_sha256" : 64,
|
||||
"_gcry_digest_spec_sha384" : 128,
|
||||
"_gcry_digest_spec_sha512" : 128,
|
||||
"_gcry_digest_spec_tiger" : 64,
|
||||
"_gcry_digest_spec_whirlpool" : 64}
|
||||
|
||||
for cipher_file in cipher_files:
|
||||
infile = os.path.join (cipher_dir_in, cipher_file)
|
||||
outfile = os.path.join (cipher_dir_out, cipher_file)
|
||||
|
@ -44,6 +58,8 @@ for cipher_file in cipher_files:
|
|||
hold = False
|
||||
skip = False
|
||||
skip2 = False
|
||||
ismd = False
|
||||
iscomma = False
|
||||
for line in f:
|
||||
if skip:
|
||||
if line[0] == "}":
|
||||
|
@ -53,6 +69,16 @@ for cipher_file in cipher_files:
|
|||
if not re.search (" *};", line) is None:
|
||||
skip2 = False
|
||||
continue
|
||||
if ismd:
|
||||
if not re.search (" *};", line) is None:
|
||||
if not mdblocksizes.has_key (mdname):
|
||||
print ("ERROR: Unknown digest blocksize: %s\n" % mdname)
|
||||
exit (1)
|
||||
if not iscomma:
|
||||
fw.write (" ,\n")
|
||||
fw.write (" .blocksize = %s\n" % mdblocksizes [mdname])
|
||||
ismd = False
|
||||
iscomma = not re.search (",$", line) is None
|
||||
if hold:
|
||||
hold = False
|
||||
# We're optimising for size.
|
||||
|
@ -85,9 +111,11 @@ for cipher_file in cipher_files:
|
|||
ciphernames.append (ciphername)
|
||||
m = re.match ("gcry_md_spec_t", line)
|
||||
if isc and not m is None:
|
||||
assert (not ismd)
|
||||
mdname = line [len ("gcry_md_spec_t"):].strip ()
|
||||
mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
|
||||
mdnames.append (mdname)
|
||||
ismd = True
|
||||
m = re.match ("static const char \*selftest.*;$", line)
|
||||
if not m is None:
|
||||
fname = line[len ("static const char \*"):]
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -127,35 +129,6 @@ typedef struct gcry_cipher_spec
|
|||
struct gcry_cipher_spec *next;
|
||||
} gcry_cipher_spec_t;
|
||||
|
||||
/* Definition of a function used to report selftest failures.
|
||||
DOMAIN is a string describing the function block:
|
||||
"cipher", "digest", "pubkey or "random",
|
||||
ALGO is the algorithm under test,
|
||||
WHAT is a string describing what has been tested,
|
||||
DESC is a string describing the error. */
|
||||
typedef void (*selftest_report_func_t)(const char *domain,
|
||||
int algo,
|
||||
const char *what,
|
||||
const char *errdesc);
|
||||
|
||||
/* Definition of the selftest functions. */
|
||||
typedef gpg_err_code_t (*selftest_func_t)
|
||||
(int algo, int extended, selftest_report_func_t report);
|
||||
|
||||
/* The type used to convey additional information to a cipher. */
|
||||
typedef gpg_err_code_t (*cipher_set_extra_info_t)
|
||||
(void *c, int what, const void *buffer, grub_size_t buflen);
|
||||
|
||||
|
||||
/* Extra module specification structures. These are used for internal
|
||||
modules which provide more functions than available through the
|
||||
public algorithm register APIs. */
|
||||
typedef struct cipher_extra_spec
|
||||
{
|
||||
selftest_func_t selftest;
|
||||
cipher_set_extra_info_t set_extra_info;
|
||||
} cipher_extra_spec_t;
|
||||
|
||||
/* Type for the md_init function. */
|
||||
typedef void (*gcry_md_init_t) (void *c);
|
||||
|
||||
|
@ -180,12 +153,14 @@ typedef struct gcry_md_spec
|
|||
unsigned char *asnoid;
|
||||
int asnlen;
|
||||
gcry_md_oid_spec_t *oids;
|
||||
int mdlen;
|
||||
grub_size_t mdlen;
|
||||
gcry_md_init_t init;
|
||||
gcry_md_write_t write;
|
||||
gcry_md_final_t final;
|
||||
gcry_md_read_t read;
|
||||
grub_size_t contextsize; /* allocate this amount of context */
|
||||
/* Block size, needed for HMAC. */
|
||||
grub_size_t blocksize;
|
||||
struct gcry_md_spec *next;
|
||||
} gcry_md_spec_t;
|
||||
|
||||
|
@ -199,7 +174,7 @@ grub_cipher_register (gcry_cipher_spec_t *cipher)
|
|||
grub_ciphers = cipher;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static inline void
|
||||
grub_cipher_unregister (gcry_cipher_spec_t *cipher)
|
||||
{
|
||||
gcry_cipher_spec_t **ciph;
|
||||
|
@ -224,7 +199,172 @@ grub_md_unregister (gcry_md_spec_t *cipher)
|
|||
*ciph = (*ciph)->next;
|
||||
}
|
||||
|
||||
static inline void
|
||||
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
|
||||
grub_size_t inlen)
|
||||
{
|
||||
grub_uint8_t ctx[hash->contextsize];
|
||||
hash->init (&ctx);
|
||||
hash->write (&ctx, in, inlen);
|
||||
hash->final (&ctx);
|
||||
grub_memcpy (out, hash->read (&ctx), hash->mdlen);
|
||||
}
|
||||
|
||||
static inline const gcry_md_spec_t *
|
||||
grub_crypto_lookup_md_by_name (const char *name)
|
||||
{
|
||||
const gcry_md_spec_t *md;
|
||||
for (md = grub_digests; md; md = md->next)
|
||||
if (grub_strcasecmp (name, md->name) == 0)
|
||||
return md;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct grub_crypto_cipher_handle
|
||||
{
|
||||
const struct gcry_cipher_spec *cipher;
|
||||
char ctx[0];
|
||||
} *grub_crypto_cipher_handle_t;
|
||||
|
||||
static inline const gcry_cipher_spec_t *
|
||||
grub_crypto_lookup_cipher_by_name (const char *name)
|
||||
{
|
||||
const gcry_cipher_spec_t *ciph;
|
||||
for (ciph = grub_ciphers; ciph; ciph = ciph->next)
|
||||
{
|
||||
const char **alias;
|
||||
if (grub_strcasecmp (name, ciph->name) == 0)
|
||||
return ciph;
|
||||
if (!ciph->aliases)
|
||||
continue;
|
||||
for (alias = ciph->aliases; *alias; alias++)
|
||||
if (grub_strcasecmp (name, *alias) == 0)
|
||||
return ciph;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static inline grub_crypto_cipher_handle_t
|
||||
grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher)
|
||||
{
|
||||
grub_crypto_cipher_handle_t ret;
|
||||
ret = grub_malloc (sizeof (*ret) + cipher->contextsize);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->cipher = cipher;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline gcry_err_code_t
|
||||
grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned keylen)
|
||||
{
|
||||
return cipher->cipher->setkey (cipher->ctx, key, keylen);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
|
||||
{
|
||||
grub_free (cipher);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
|
||||
{
|
||||
const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
|
||||
grub_uint8_t *outptr = out;
|
||||
while (size--)
|
||||
{
|
||||
*outptr = *in1ptr ^ *in2ptr;
|
||||
in1ptr++;
|
||||
in2ptr++;
|
||||
outptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline grub_err_t
|
||||
grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"This encryption can't decrypt partial blocks");
|
||||
end = (grub_uint8_t *) in + size;
|
||||
for (inptr = in, outptr = out; inptr < end;
|
||||
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
|
||||
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline grub_err_t
|
||||
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"This encryption can't decrypt partial blocks");
|
||||
end = (grub_uint8_t *) in + size;
|
||||
for (inptr = in, outptr = out; inptr < end;
|
||||
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
|
||||
cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline grub_err_t
|
||||
grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size,
|
||||
void *iv_in)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
void *iv;
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"This encryption can't decrypt partial blocks");
|
||||
end = (grub_uint8_t *) in + size;
|
||||
iv = iv_in;
|
||||
for (inptr = in, outptr = out; inptr < end;
|
||||
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
|
||||
{
|
||||
grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
|
||||
cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
|
||||
iv = outptr;
|
||||
}
|
||||
grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline grub_err_t
|
||||
grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size,
|
||||
void *iv)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
grub_uint8_t ivt[cipher->cipher->blocksize];
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"This encryption can't decrypt partial blocks");
|
||||
end = (grub_uint8_t *) in + size;
|
||||
for (inptr = in, outptr = out; inptr < end;
|
||||
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
|
||||
{
|
||||
grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
|
||||
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
|
||||
grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
|
||||
grub_memcpy (iv, ivt, cipher->cipher->blocksize);
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
void EXPORT_FUNC(grub_burn_stack) (grub_size_t size);
|
||||
|
||||
extern gcry_md_spec_t _gcry_digest_spec_md5;
|
||||
#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@ enum grub_disk_dev_id
|
|||
GRUB_DISK_DEVICE_PXE_ID,
|
||||
GRUB_DISK_DEVICE_SCSI_ID,
|
||||
GRUB_DISK_DEVICE_FILE_ID,
|
||||
GRUB_DISK_DEVICE_LUKS_ID
|
||||
};
|
||||
|
||||
struct grub_disk;
|
||||
|
|
Loading…
Reference in a new issue