crypto.h 12.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  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.  */

23 24
#ifndef GRUB_CRYPTO_HEADER
#define GRUB_CRYPTO_HEADER 1
25 26 27

#include <grub/symbol.h>
#include <grub/types.h>
28
#include <grub/err.h>
29
#include <grub/mm.h>
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

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,
67
    GPG_ERR_OUT_OF_MEMORY,
68 69
    GPG_ERR_TOO_LARGE,
    GPG_ERR_ENOMEM
70 71 72 73
  } gpg_err_code_t;
typedef gpg_err_code_t gpg_error_t;
typedef gpg_error_t gcry_error_t;
typedef gpg_err_code_t gcry_err_code_t;
74 75
#define gcry_error_t gcry_err_code_t
#if 0
76 77 78 79 80 81 82 83 84 85
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. */
  };
86
#endif
87

88 89 90
/* Don't rely on this. Check!  */
#define GRUB_CRYPTO_MAX_MDLEN 64
#define GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE 16
91
#define GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE 256
92

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
/* 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;
140 141 142
#ifdef GRUB_UTIL
  const char *modname;
#endif
143
  struct gcry_cipher_spec *next;
144 145
} gcry_cipher_spec_t;

146 147
/* Type for the md_init function.  */
typedef void (*gcry_md_init_t) (void *c);
148

149 150 151 152 153 154 155 156
/* 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);
157

158 159 160 161
typedef struct gcry_md_oid_spec
{
  const char *oidstring;
} gcry_md_oid_spec_t;
162

163 164
/* Module specification structure for message digests.  */
typedef struct gcry_md_spec
165 166
{
  const char *name;
167 168 169
  unsigned char *asnoid;
  int asnlen;
  gcry_md_oid_spec_t *oids;
170
  grub_size_t mdlen;
171 172 173 174 175
  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 */
176 177
  /* Block size, needed for HMAC.  */
  grub_size_t blocksize;
178 179 180
#ifdef GRUB_UTIL
  const char *modname;
#endif
181 182 183
  struct gcry_md_spec *next;
} gcry_md_spec_t;

184
struct gcry_mpi;
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
typedef struct gcry_mpi *gcry_mpi_t;

/* Type for the pk_generate function.  */
typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
					       unsigned int nbits,
					       unsigned long use_e,
					       gcry_mpi_t *skey,
					       gcry_mpi_t **retfactors);

/* Type for the pk_check_secret_key function.  */
typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
						       gcry_mpi_t *skey);

/* Type for the pk_encrypt function.  */
typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
					      gcry_mpi_t *resarr,
					      gcry_mpi_t data,
					      gcry_mpi_t *pkey,
					      int flags);

/* Type for the pk_decrypt function.  */
typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
					      gcry_mpi_t *result,
					      gcry_mpi_t *data,
					      gcry_mpi_t *skey,
					      int flags);

/* Type for the pk_sign function.  */
typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
					   gcry_mpi_t *resarr,
					   gcry_mpi_t data,
					   gcry_mpi_t *skey);

/* Type for the pk_verify function.  */
typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
					     gcry_mpi_t hash,
					     gcry_mpi_t *data,
					     gcry_mpi_t *pkey,
					     int (*cmp) (void *, gcry_mpi_t),
					     void *opaquev);

/* Type for the pk_get_nbits function.  */
typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);

/* Module specification structure for message digests.  */
typedef struct gcry_pk_spec
{
  const char *name;
  const char **aliases;
  const char *elements_pkey;
  const char *elements_skey;
  const char *elements_enc;
  const char *elements_sig;
  const char *elements_grip;
  int use;
  gcry_pk_generate_t generate;
  gcry_pk_check_secret_key_t check_secret_key;
  gcry_pk_encrypt_t encrypt;
  gcry_pk_decrypt_t decrypt;
  gcry_pk_sign_t sign;
  gcry_pk_verify_t verify;
  gcry_pk_get_nbits_t get_nbits;
#ifdef GRUB_UTIL
  const char *modname;
#endif
} gcry_pk_spec_t;

252
struct grub_crypto_cipher_handle
253 254 255
{
  const struct gcry_cipher_spec *cipher;
  char ctx[0];
256 257 258 259 260
};

typedef struct grub_crypto_cipher_handle *grub_crypto_cipher_handle_t;

struct grub_crypto_hmac_handle;
261

262 263
const gcry_cipher_spec_t *
grub_crypto_lookup_cipher_by_name (const char *name);
264

265 266
grub_crypto_cipher_handle_t
grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
267

268
gcry_err_code_t
269 270
grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
			    const unsigned char *key,
271
			    unsigned keylen);
272

273 274 275 276 277
static inline void
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
{
  grub_free (cipher);
}
278

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
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))
    {
296 297 298 299
      /* We've already checked that all pointers are aligned.  */
      *(grub_uint64_t *) (void *) outptr
	= (*(const grub_uint64_t *) (const void *) in1ptr
	   ^ *(const grub_uint64_t *) (const void *) in2ptr);
300 301 302 303 304 305 306 307 308 309 310 311 312 313
      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--;
    }
}
314 315

gcry_err_code_t
316
grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
317
			 void *out, const void *in, grub_size_t size);
318

319
gcry_err_code_t
320
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
321
			 void *out, const void *in, grub_size_t size);
322
gcry_err_code_t
323
grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
324
			 void *out, const void *in, grub_size_t size,
325
			 void *iv_in);
326
gcry_err_code_t
327
grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
328
			 void *out, const void *in, grub_size_t size,
329 330
			 void *iv);
void 
331 332 333 334
grub_cipher_register (gcry_cipher_spec_t *cipher);
void
grub_cipher_unregister (gcry_cipher_spec_t *cipher);
void 
335 336 337
grub_md_register (gcry_md_spec_t *digest);
void 
grub_md_unregister (gcry_md_spec_t *cipher);
338 339 340

extern struct gcry_pk_spec *grub_crypto_pk_dsa;
extern struct gcry_pk_spec *grub_crypto_pk_ecdsa;
341
extern struct gcry_pk_spec *grub_crypto_pk_ecdh;
342 343
extern struct gcry_pk_spec *grub_crypto_pk_rsa;

344
void
345
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
346 347 348
		  grub_size_t inlen);
const gcry_md_spec_t *
grub_crypto_lookup_md_by_name (const char *name);
349

350 351 352
grub_err_t
grub_crypto_gcry_error (gcry_err_code_t in);

353
void grub_burn_stack (grub_size_t size);
354

355 356 357 358
struct grub_crypto_hmac_handle *
grub_crypto_hmac_init (const struct gcry_md_spec *md,
		       const void *key, grub_size_t keylen);
void
359 360
grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
			const void *data,
361 362 363 364 365 366 367
			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,
368
			 const void *data, grub_size_t datalen, void *out);
369

370
extern gcry_md_spec_t _gcry_digest_spec_md5;
371 372
extern gcry_md_spec_t _gcry_digest_spec_sha1;
extern gcry_md_spec_t _gcry_digest_spec_sha256;
373
extern gcry_md_spec_t _gcry_digest_spec_sha512;
374
extern gcry_md_spec_t _gcry_digest_spec_crc32;
375
extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
376
#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
377
#define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1)
378
#define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256)
379
#define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512)
380
#define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32)
381
#define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes)
382 383 384 385 386 387 388 389 390 391 392 393 394

/* 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);
395

396
int
397 398 399 400 401 402
grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);

int
grub_password_get (char buf[], unsigned buf_size);

/* For indistinguishibility.  */
403
#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, N_("access denied"))
404

405 406
extern void (*grub_crypto_autoload_hook) (const char *name);

407 408 409 410
void _gcry_assert_failed (const char *expr, const char *file, int line,
                          const char *func) __attribute__ ((noreturn));

void _gcry_burn_stack (int bytes);
411
void _gcry_log_error( const char *fmt, ... )  __attribute__ ((format (__printf__, 1, 2)));
412 413


414 415 416
#ifdef GRUB_UTIL
void grub_gcry_init_all (void);
void grub_gcry_fini_all (void);
417 418 419 420

int
grub_get_random (void *out, grub_size_t len);

421 422
#endif

423
#endif