Created crypto module. Moved some functions to it.
This commit is contained in:
parent
414f919237
commit
d944246c6a
4 changed files with 263 additions and 182 deletions
|
@ -619,4 +619,9 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
|
||||||
setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
||||||
setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
|
pkglib_MODULES += crypto.mod
|
||||||
|
crypto_mod_SOURCES = lib/crypto.c
|
||||||
|
crypto_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
|
crypto_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
include $(srcdir)/conf/gcry.mk
|
include $(srcdir)/conf/gcry.mk
|
||||||
|
|
|
@ -58,15 +58,13 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
|
||||||
kern/generic/millisleep.c \
|
kern/generic/millisleep.c \
|
||||||
kern/env.c \
|
kern/env.c \
|
||||||
term/i386/pc/console.c term/i386/vga_common.c \
|
term/i386/pc/console.c term/i386/vga_common.c \
|
||||||
kern/crypto.c \
|
|
||||||
symlist.c
|
symlist.c
|
||||||
kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
|
kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
|
||||||
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
|
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
|
||||||
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
|
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
|
||||||
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
|
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
|
||||||
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
|
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
|
||||||
machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \
|
machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h
|
||||||
crypto.h
|
|
||||||
kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS)
|
kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS)
|
||||||
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
|
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
|
||||||
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
|
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
|
||||||
|
|
|
@ -164,205 +164,58 @@ typedef struct gcry_md_spec
|
||||||
struct gcry_md_spec *next;
|
struct gcry_md_spec *next;
|
||||||
} gcry_md_spec_t;
|
} 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
|
typedef struct grub_crypto_cipher_handle
|
||||||
{
|
{
|
||||||
const struct gcry_cipher_spec *cipher;
|
const struct gcry_cipher_spec *cipher;
|
||||||
char ctx[0];
|
char ctx[0];
|
||||||
} *grub_crypto_cipher_handle_t;
|
} *grub_crypto_cipher_handle_t;
|
||||||
|
|
||||||
static inline const gcry_cipher_spec_t *
|
const gcry_cipher_spec_t *
|
||||||
grub_crypto_lookup_cipher_by_name (const char *name)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
grub_crypto_cipher_handle_t
|
||||||
|
grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
|
||||||
|
|
||||||
static inline grub_crypto_cipher_handle_t
|
gcry_err_code_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,
|
grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
|
||||||
const unsigned char *key,
|
const unsigned char *key,
|
||||||
unsigned keylen)
|
unsigned keylen);
|
||||||
{
|
|
||||||
return cipher->cipher->setkey (cipher->ctx, key, keylen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher);
|
||||||
|
|
||||||
static inline void
|
void
|
||||||
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
|
grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size);
|
||||||
{
|
grub_err_t
|
||||||
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,
|
grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *out, void *in, grub_size_t size)
|
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_err_t
|
||||||
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
|
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *out, void *in, grub_size_t size)
|
void *out, void *in, grub_size_t size);
|
||||||
{
|
grub_err_t
|
||||||
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,
|
grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *out, void *in, grub_size_t size,
|
void *out, void *in, grub_size_t size,
|
||||||
void *iv_in)
|
void *iv_in);
|
||||||
{
|
grub_err_t
|
||||||
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,
|
grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||||
void *out, void *in, grub_size_t size,
|
void *out, void *in, grub_size_t size,
|
||||||
void *iv)
|
void *iv);
|
||||||
{
|
void
|
||||||
grub_uint8_t *inptr, *outptr, *end;
|
grub_cipher_register (gcry_cipher_spec_t *cipher);
|
||||||
grub_uint8_t ivt[cipher->cipher->blocksize];
|
void
|
||||||
if (size % cipher->cipher->blocksize != 0)
|
grub_cipher_unregister (gcry_cipher_spec_t *cipher);
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
void
|
||||||
"This encryption can't decrypt partial blocks");
|
grub_md_register (gcry_md_spec_t *digest);
|
||||||
end = (grub_uint8_t *) in + size;
|
void
|
||||||
for (inptr = in, outptr = out; inptr < end;
|
grub_md_unregister (gcry_md_spec_t *cipher);
|
||||||
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
|
void
|
||||||
{
|
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
|
||||||
grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
|
grub_size_t inlen);
|
||||||
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
|
const gcry_md_spec_t *
|
||||||
grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
|
grub_crypto_lookup_md_by_name (const char *name);
|
||||||
grub_memcpy (iv, ivt, cipher->cipher->blocksize);
|
|
||||||
}
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void grub_burn_stack (grub_size_t size);
|
||||||
void EXPORT_FUNC(grub_burn_stack) (grub_size_t size);
|
|
||||||
|
|
||||||
extern gcry_md_spec_t _gcry_digest_spec_md5;
|
extern gcry_md_spec_t _gcry_digest_spec_md5;
|
||||||
#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
|
#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
|
||||||
|
|
225
lib/crypto.c
Normal file
225
lib/crypto.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
|
||||||
|
* 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
|
static gcry_cipher_spec_t *grub_ciphers = NULL;
|
||||||
|
static gcry_md_spec_t *grub_digests = NULL;
|
||||||
|
|
||||||
|
/* Based on libgcrypt-1.4.4/src/misc.c. */
|
||||||
|
void
|
||||||
|
grub_burn_stack (grub_size_t size)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
grub_memset (buf, 0, sizeof (buf));
|
||||||
|
if (size > sizeof (buf))
|
||||||
|
grub_burn_stack (size - sizeof (buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_cipher_register (gcry_cipher_spec_t *cipher)
|
||||||
|
{
|
||||||
|
cipher->next = grub_ciphers;
|
||||||
|
grub_ciphers = cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_md_register (gcry_md_spec_t *digest)
|
||||||
|
{
|
||||||
|
digest->next = grub_digests;
|
||||||
|
grub_digests = digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
|
||||||
|
{
|
||||||
|
grub_free (cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in a new issue