Created crypto module. Moved some functions to it.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-12 22:40:14 +01:00
parent 414f919237
commit d944246c6a
4 changed files with 263 additions and 182 deletions

View file

@ -164,205 +164,58 @@ typedef struct gcry_md_spec
struct gcry_md_spec *next;
} gcry_md_spec_t;
extern gcry_cipher_spec_t *EXPORT_VAR (grub_ciphers);
extern gcry_md_spec_t *EXPORT_VAR (grub_digests);
static inline void
grub_cipher_register (gcry_cipher_spec_t *cipher)
{
cipher->next = grub_ciphers;
grub_ciphers = cipher;
}
static inline void
grub_cipher_unregister (gcry_cipher_spec_t *cipher)
{
gcry_cipher_spec_t **ciph;
for (ciph = &grub_ciphers; *ciph; ciph = &((*ciph)->next))
if (*ciph == cipher)
*ciph = (*ciph)->next;
}
static inline void
grub_md_register (gcry_md_spec_t *digest)
{
digest->next = grub_digests;
grub_digests = digest;
}
static inline void
grub_md_unregister (gcry_md_spec_t *cipher)
{
gcry_md_spec_t **ciph;
for (ciph = &grub_digests; *ciph; ciph = &((*ciph)->next))
if (*ciph == 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;
}
const gcry_cipher_spec_t *
grub_crypto_lookup_cipher_by_name (const char *name);
grub_crypto_cipher_handle_t
grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
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
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);
}
unsigned keylen);
void
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher);
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
void
grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size);
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;
}
void *out, void *in, grub_size_t size);
static inline grub_err_t
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
void *out, void *in, grub_size_t size);
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
void *iv_in);
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 *iv);
void
grub_cipher_register (gcry_cipher_spec_t *cipher);
void
grub_cipher_unregister (gcry_cipher_spec_t *cipher);
void
grub_md_register (gcry_md_spec_t *digest);
void
grub_md_unregister (gcry_md_spec_t *cipher);
void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
grub_size_t inlen);
const gcry_md_spec_t *
grub_crypto_lookup_md_by_name (const char *name);
void EXPORT_FUNC(grub_burn_stack) (grub_size_t size);
void 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)