mirror of
				https://git.proxmox.com/git/grub2
				synced 2025-10-31 06:40:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			329 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  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/>.
 | |
|  */
 | |
| 
 | |
| /* Contains elements based on gcrypt-module.h and gcrypt.h.in.
 | |
|    If it's changed please update this file.  */
 | |
| 
 | |
| #ifndef GRUB_CRYPTO_HEADER
 | |
| #define GRUB_CRYPTO_HEADER 1
 | |
| 
 | |
| #include <grub/symbol.h>
 | |
| #include <grub/types.h>
 | |
| #include <grub/err.h>
 | |
| #include <grub/mm.h>
 | |
| 
 | |
| typedef enum 
 | |
|   {
 | |
|     GPG_ERR_NO_ERROR,
 | |
|     GPG_ERR_BAD_MPI,
 | |
|     GPG_ERR_BAD_SECKEY,
 | |
|     GPG_ERR_BAD_SIGNATURE,
 | |
|     GPG_ERR_CIPHER_ALGO,
 | |
|     GPG_ERR_CONFLICT,
 | |
|     GPG_ERR_DECRYPT_FAILED,
 | |
|     GPG_ERR_DIGEST_ALGO,
 | |
|     GPG_ERR_GENERAL,
 | |
|     GPG_ERR_INTERNAL,
 | |
|     GPG_ERR_INV_ARG,
 | |
|     GPG_ERR_INV_CIPHER_MODE,
 | |
|     GPG_ERR_INV_FLAG,
 | |
|     GPG_ERR_INV_KEYLEN,
 | |
|     GPG_ERR_INV_OBJ,
 | |
|     GPG_ERR_INV_OP,
 | |
|     GPG_ERR_INV_SEXP,
 | |
|     GPG_ERR_INV_VALUE,
 | |
|     GPG_ERR_MISSING_VALUE,
 | |
|     GPG_ERR_NO_ENCRYPTION_SCHEME,
 | |
|     GPG_ERR_NO_OBJ,
 | |
|     GPG_ERR_NO_PRIME,
 | |
|     GPG_ERR_NO_SIGNATURE_SCHEME,
 | |
|     GPG_ERR_NOT_FOUND,
 | |
|     GPG_ERR_NOT_IMPLEMENTED,
 | |
|     GPG_ERR_NOT_SUPPORTED,
 | |
|     GPG_ERROR_CFLAGS,
 | |
|     GPG_ERR_PUBKEY_ALGO,
 | |
|     GPG_ERR_SELFTEST_FAILED,
 | |
|     GPG_ERR_TOO_SHORT,
 | |
|     GPG_ERR_UNSUPPORTED,
 | |
|     GPG_ERR_WEAK_KEY,
 | |
|     GPG_ERR_WRONG_KEY_USAGE,
 | |
|     GPG_ERR_WRONG_PUBKEY_ALGO,
 | |
|     GPG_ERR_OUT_OF_MEMORY
 | |
|   } gcry_err_code_t;
 | |
| #define gpg_err_code_t gcry_err_code_t
 | |
| #define gpg_error_t gcry_err_code_t
 | |
| 
 | |
| enum gcry_cipher_modes 
 | |
|   {
 | |
|     GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
 | |
|     GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
 | |
|     GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
 | |
|     GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
 | |
|     GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
 | |
|     GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
 | |
|     GCRY_CIPHER_MODE_CTR    = 6   /* Counter. */
 | |
|   };
 | |
| 
 | |
| /* Type for the cipher_setkey function.  */
 | |
| typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
 | |
| 						 const unsigned char *key,
 | |
| 						 unsigned keylen);
 | |
| 
 | |
| /* Type for the cipher_encrypt function.  */
 | |
| typedef void (*gcry_cipher_encrypt_t) (void *c,
 | |
| 				       unsigned char *outbuf,
 | |
| 				       const unsigned char *inbuf);
 | |
| 
 | |
| /* Type for the cipher_decrypt function.  */
 | |
| typedef void (*gcry_cipher_decrypt_t) (void *c,
 | |
| 				       unsigned char *outbuf,
 | |
| 				       const unsigned char *inbuf);
 | |
| 
 | |
| /* Type for the cipher_stencrypt function.  */
 | |
| typedef void (*gcry_cipher_stencrypt_t) (void *c,
 | |
| 					 unsigned char *outbuf,
 | |
| 					 const unsigned char *inbuf,
 | |
| 					 unsigned int n);
 | |
| 
 | |
| /* Type for the cipher_stdecrypt function.  */
 | |
| typedef void (*gcry_cipher_stdecrypt_t) (void *c,
 | |
| 					 unsigned char *outbuf,
 | |
| 					 const unsigned char *inbuf,
 | |
| 					 unsigned int n);
 | |
| 
 | |
| typedef struct gcry_cipher_oid_spec
 | |
| {
 | |
|   const char *oid;
 | |
|   int mode;
 | |
| } gcry_cipher_oid_spec_t;
 | |
| 
 | |
| /* Module specification structure for ciphers.  */
 | |
| typedef struct gcry_cipher_spec
 | |
| {
 | |
|   const char *name;
 | |
|   const char **aliases;
 | |
|   gcry_cipher_oid_spec_t *oids;
 | |
|   grub_size_t blocksize;
 | |
|   grub_size_t keylen;
 | |
|   grub_size_t contextsize;
 | |
|   gcry_cipher_setkey_t setkey;
 | |
|   gcry_cipher_encrypt_t encrypt;
 | |
|   gcry_cipher_decrypt_t decrypt;
 | |
|   gcry_cipher_stencrypt_t stencrypt;
 | |
|   gcry_cipher_stdecrypt_t stdecrypt;
 | |
| #ifdef GRUB_UTIL
 | |
|   const char *modname;
 | |
| #endif
 | |
|   struct gcry_cipher_spec *next;
 | |
| } gcry_cipher_spec_t;
 | |
| 
 | |
| /* Type for the md_init function.  */
 | |
| typedef void (*gcry_md_init_t) (void *c);
 | |
| 
 | |
| /* Type for the md_write function.  */
 | |
| typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes);
 | |
| 
 | |
| /* Type for the md_final function.  */
 | |
| typedef void (*gcry_md_final_t) (void *c);
 | |
| 
 | |
| /* Type for the md_read function.  */
 | |
| typedef unsigned char *(*gcry_md_read_t) (void *c);
 | |
| 
 | |
| typedef struct gcry_md_oid_spec
 | |
| {
 | |
|   const char *oidstring;
 | |
| } gcry_md_oid_spec_t;
 | |
| 
 | |
| /* Module specification structure for message digests.  */
 | |
| typedef struct gcry_md_spec
 | |
| {
 | |
|   const char *name;
 | |
|   unsigned char *asnoid;
 | |
|   int asnlen;
 | |
|   gcry_md_oid_spec_t *oids;
 | |
|   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;
 | |
| #ifdef GRUB_UTIL
 | |
|   const char *modname;
 | |
| #endif
 | |
|   struct gcry_md_spec *next;
 | |
| } gcry_md_spec_t;
 | |
| 
 | |
| struct grub_crypto_cipher_handle
 | |
| {
 | |
|   const struct gcry_cipher_spec *cipher;
 | |
|   char ctx[0];
 | |
| };
 | |
| 
 | |
| typedef struct grub_crypto_cipher_handle *grub_crypto_cipher_handle_t;
 | |
| 
 | |
| struct grub_crypto_hmac_handle;
 | |
| 
 | |
| 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);
 | |
| 
 | |
| gcry_err_code_t
 | |
| grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
 | |
| 			    const unsigned char *key,
 | |
| 			    unsigned 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 && (((grub_addr_t) in1ptr & (sizeof (grub_uint64_t) - 1))
 | |
| 		  || ((grub_addr_t) in2ptr & (sizeof (grub_uint64_t) - 1))
 | |
| 		  || ((grub_addr_t) outptr & (sizeof (grub_uint64_t) - 1))))
 | |
|     {
 | |
|       *outptr = *in1ptr ^ *in2ptr;
 | |
|       in1ptr++;
 | |
|       in2ptr++;
 | |
|       outptr++;
 | |
|       size--;
 | |
|     }
 | |
|   while (size >= sizeof (grub_uint64_t))
 | |
|     {
 | |
|       *(grub_uint64_t *) (void *) outptr
 | |
| 	= (*(grub_uint64_t *) (void *) in1ptr
 | |
| 	   ^ *(grub_uint64_t *) (void *) in2ptr);
 | |
|       in1ptr += sizeof (grub_uint64_t);
 | |
|       in2ptr += sizeof (grub_uint64_t);
 | |
|       outptr += sizeof (grub_uint64_t);
 | |
|       size -= sizeof (grub_uint64_t);
 | |
|     }
 | |
|   while (size)
 | |
|     {
 | |
|       *outptr = *in1ptr ^ *in2ptr;
 | |
|       in1ptr++;
 | |
|       in2ptr++;
 | |
|       outptr++;
 | |
|       size--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| gcry_err_code_t
 | |
| grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
 | |
| 			 void *out, const void *in, grub_size_t size);
 | |
| 
 | |
| gcry_err_code_t
 | |
| grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
 | |
| 			 void *out, const void *in, grub_size_t size);
 | |
| gcry_err_code_t
 | |
| grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
 | |
| 			 void *out, void *in, grub_size_t size,
 | |
| 			 void *iv_in);
 | |
| gcry_err_code_t
 | |
| grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
 | |
| 			 void *out, const void *in, grub_size_t size,
 | |
| 			 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, const void *in,
 | |
| 		  grub_size_t inlen);
 | |
| const gcry_md_spec_t *
 | |
| grub_crypto_lookup_md_by_name (const char *name);
 | |
| 
 | |
| grub_err_t
 | |
| grub_crypto_gcry_error (gcry_err_code_t in);
 | |
| 
 | |
| void grub_burn_stack (grub_size_t size);
 | |
| 
 | |
| struct grub_crypto_hmac_handle *
 | |
| grub_crypto_hmac_init (const struct gcry_md_spec *md,
 | |
| 		       const void *key, grub_size_t keylen);
 | |
| void
 | |
| grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
 | |
| 			const void *data,
 | |
| 			grub_size_t datalen);
 | |
| gcry_err_code_t
 | |
| grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
 | |
| 
 | |
| gcry_err_code_t
 | |
| grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
 | |
| 			 const void *key, grub_size_t keylen,
 | |
| 			 const void *data, grub_size_t datalen, void *out);
 | |
| 
 | |
| extern gcry_md_spec_t _gcry_digest_spec_md5;
 | |
| extern gcry_md_spec_t _gcry_digest_spec_sha1;
 | |
| extern gcry_md_spec_t _gcry_digest_spec_sha256;
 | |
| extern gcry_md_spec_t _gcry_digest_spec_sha512;
 | |
| extern gcry_md_spec_t _gcry_digest_spec_crc32;
 | |
| extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
 | |
| #define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
 | |
| #define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1)
 | |
| #define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256)
 | |
| #define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512)
 | |
| #define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32)
 | |
| #define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes)
 | |
| 
 | |
| /* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
 | |
|    of digest supplied by MD.  Inputs are the password P of length PLEN,
 | |
|    the salt S of length SLEN, the iteration counter C (> 0), and the
 | |
|    desired derived output length DKLEN.  Output buffer is DK which
 | |
|    must have room for at least DKLEN octets.  The output buffer will
 | |
|    be filled with the derived data.  */
 | |
| gcry_err_code_t
 | |
| grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
 | |
| 		    const grub_uint8_t *P, grub_size_t Plen,
 | |
| 		    const grub_uint8_t *S, grub_size_t Slen,
 | |
| 		    unsigned int c,
 | |
| 		    grub_uint8_t *DK, grub_size_t dkLen);
 | |
| 
 | |
| int
 | |
| grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
 | |
| 
 | |
| int
 | |
| grub_password_get (char buf[], unsigned buf_size);
 | |
| 
 | |
| /* For indistinguishibility.  */
 | |
| #define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, N_("access denied"))
 | |
| 
 | |
| extern void (*grub_crypto_autoload_hook) (const char *name);
 | |
| 
 | |
| #ifdef GRUB_UTIL
 | |
| void grub_gcry_init_all (void);
 | |
| void grub_gcry_fini_all (void);
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #endif
 | 
