Blame cipher/cipher-internal.h

Packit 0680ba
/* cipher-internal.h  - Internal defs for cipher.c
Packit 0680ba
 * Copyright (C) 2011 Free Software Foundation, Inc.
Packit 0680ba
 *
Packit 0680ba
 * This file is part of Libgcrypt.
Packit 0680ba
 *
Packit 0680ba
 * Libgcrypt is free software; you can redistribute it and/or modify
Packit 0680ba
 * it under the terms of the GNU Lesser general Public License as
Packit 0680ba
 * published by the Free Software Foundation; either version 2.1 of
Packit 0680ba
 * the License, or (at your option) any later version.
Packit 0680ba
 *
Packit 0680ba
 * Libgcrypt is distributed in the hope that it will be useful,
Packit 0680ba
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0680ba
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 0680ba
 * GNU Lesser General Public License for more details.
Packit 0680ba
 *
Packit 0680ba
 * You should have received a copy of the GNU Lesser General Public
Packit 0680ba
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 0680ba
 */
Packit 0680ba
Packit 0680ba
#ifndef G10_CIPHER_INTERNAL_H
Packit 0680ba
#define G10_CIPHER_INTERNAL_H
Packit 0680ba
Packit 0680ba
/* The maximum supported size of a block in bytes.  */
Packit 0680ba
#define MAX_BLOCKSIZE 16
Packit 0680ba
Packit 0680ba
/* Magic values for the context structure.  */
Packit 0680ba
#define CTX_MAGIC_NORMAL 0x24091964
Packit 0680ba
#define CTX_MAGIC_SECURE 0x46919042
Packit 0680ba
Packit 0680ba
/* Try to use 16 byte aligned cipher context for better performance.
Packit 0680ba
   We use the aligned attribute, thus it is only possible to implement
Packit 0680ba
   this with gcc.  */
Packit 0680ba
#undef NEED_16BYTE_ALIGNED_CONTEXT
Packit 0680ba
#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
Packit 0680ba
# define NEED_16BYTE_ALIGNED_CONTEXT 1
Packit 0680ba
#endif
Packit 0680ba
Packit 0680ba
/* Undef this symbol to trade GCM speed for 256 bytes of memory per context */
Packit 0680ba
#define GCM_USE_TABLES 1
Packit 0680ba
Packit 0680ba
Packit 0680ba
/* GCM_USE_INTEL_PCLMUL inidicates whether to compile GCM with Intel PCLMUL
Packit 0680ba
   code.  */
Packit 0680ba
#undef GCM_USE_INTEL_PCLMUL
Packit 0680ba
#if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES)
Packit 0680ba
# if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
Packit 0680ba
#  if __GNUC__ >= 4
Packit 0680ba
#   define GCM_USE_INTEL_PCLMUL 1
Packit 0680ba
#  endif
Packit 0680ba
# endif
Packit 0680ba
#endif /* GCM_USE_INTEL_PCLMUL */
Packit 0680ba
Packit 0680ba
Packit 0680ba
/* A VIA processor with the Padlock engine as well as the Intel AES_NI
Packit 0680ba
   instructions require an alignment of most data on a 16 byte
Packit 0680ba
   boundary.  Because we trick out the compiler while allocating the
Packit 0680ba
   context, the align attribute as used in rijndael.c does not work on
Packit 0680ba
   its own.  Thus we need to make sure that the entire context
Packit 0680ba
   structure is a aligned on that boundary.  We achieve this by
Packit 0680ba
   defining a new type and use that instead of our usual alignment
Packit 0680ba
   type.  */
Packit 0680ba
typedef union
Packit 0680ba
{
Packit 0680ba
  PROPERLY_ALIGNED_TYPE foo;
Packit 0680ba
#ifdef NEED_16BYTE_ALIGNED_CONTEXT
Packit 0680ba
  char bar[16] __attribute__ ((aligned (16)));
Packit 0680ba
#endif
Packit 0680ba
  char c[1];
Packit 0680ba
} cipher_context_alignment_t;
Packit 0680ba
Packit 0680ba
Packit 0680ba
/* The handle structure.  */
Packit 0680ba
struct gcry_cipher_handle
Packit 0680ba
{
Packit 0680ba
  int magic;
Packit 0680ba
  size_t actual_handle_size;     /* Allocated size of this handle. */
Packit 0680ba
  size_t handle_offset;          /* Offset to the malloced block.  */
Packit 0680ba
  gcry_cipher_spec_t *spec;
Packit 0680ba
Packit 0680ba
  /* The algorithm id.  This is a hack required because the module
Packit 0680ba
     interface does not easily allow to retrieve this value. */
Packit 0680ba
  int algo;
Packit 0680ba
Packit 0680ba
  /* A structure with function pointers for bulk operations.  Due to
Packit 0680ba
     limitations of the module system (we don't want to change the
Packit 0680ba
     API) we need to keep these function pointers here.  The cipher
Packit 0680ba
     open function intializes them and the actual encryption routines
Packit 0680ba
     use them if they are not NULL.  */
Packit 0680ba
  struct {
Packit 0680ba
    void (*cfb_enc)(void *context, unsigned char *iv,
Packit 0680ba
                    void *outbuf_arg, const void *inbuf_arg,
Packit 0680ba
                    size_t nblocks);
Packit 0680ba
    void (*cfb_dec)(void *context, unsigned char *iv,
Packit 0680ba
                    void *outbuf_arg, const void *inbuf_arg,
Packit 0680ba
                    size_t nblocks);
Packit 0680ba
    void (*cbc_enc)(void *context, unsigned char *iv,
Packit 0680ba
                    void *outbuf_arg, const void *inbuf_arg,
Packit 0680ba
                    size_t nblocks, int cbc_mac);
Packit 0680ba
    void (*cbc_dec)(void *context, unsigned char *iv,
Packit 0680ba
                    void *outbuf_arg, const void *inbuf_arg,
Packit 0680ba
                    size_t nblocks);
Packit 0680ba
    void (*ctr_enc)(void *context, unsigned char *iv,
Packit 0680ba
                    void *outbuf_arg, const void *inbuf_arg,
Packit 0680ba
                    size_t nblocks);
Packit 0680ba
  } bulk;
Packit 0680ba
Packit 0680ba
Packit 0680ba
  int mode;
Packit 0680ba
  unsigned int flags;
Packit 0680ba
Packit 0680ba
  struct {
Packit 0680ba
    unsigned int key:1; /* Set to 1 if a key has been set.  */
Packit 0680ba
    unsigned int iv:1;  /* Set to 1 if a IV has been set.  */
Packit 0680ba
    unsigned int tag:1; /* Set to 1 if a tag is finalized. */
Packit 0680ba
  } marks;
Packit 0680ba
Packit 0680ba
  /* The initialization vector.  For best performance we make sure
Packit 0680ba
     that it is properly aligned.  In particular some implementations
Packit 0680ba
     of bulk operations expect an 16 byte aligned IV.  IV is also used
Packit 0680ba
     to store CBC-MAC in CCM mode; counter IV is stored in U_CTR.  */
Packit 0680ba
  union {
Packit 0680ba
    cipher_context_alignment_t iv_align;
Packit 0680ba
    unsigned char iv[MAX_BLOCKSIZE];
Packit 0680ba
  } u_iv;
Packit 0680ba
Packit 0680ba
  /* The counter for CTR mode.  This field is also used by AESWRAP and
Packit 0680ba
     thus we can't use the U_IV union.  */
Packit 0680ba
  union {
Packit 0680ba
    cipher_context_alignment_t iv_align;
Packit 0680ba
    unsigned char ctr[MAX_BLOCKSIZE];
Packit 0680ba
  } u_ctr;
Packit 0680ba
Packit 0680ba
  /* Space to save an IV or CTR for chaining operations.  */
Packit 0680ba
  unsigned char lastiv[MAX_BLOCKSIZE];
Packit 0680ba
  int unused;  /* Number of unused bytes in LASTIV. */
Packit 0680ba
Packit 0680ba
  union {
Packit 0680ba
#ifdef HAVE_U64_TYPEDEF
Packit 0680ba
    /* Mode specific storage for CCM mode. */
Packit 0680ba
    struct {
Packit 0680ba
      u64 encryptlen;
Packit 0680ba
      u64 aadlen;
Packit 0680ba
      unsigned int authlen;
Packit 0680ba
Packit 0680ba
      /* Space to save partial input lengths for MAC. */
Packit 0680ba
      unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
Packit 0680ba
      int mac_unused;  /* Number of unprocessed bytes in MACBUF. */
Packit 0680ba
Packit 0680ba
      unsigned char s0[GCRY_CCM_BLOCK_LEN];
Packit 0680ba
Packit 0680ba
      unsigned int nonce:1;/* Set to 1 if nonce has been set.  */
Packit 0680ba
      unsigned int lengths:1; /* Set to 1 if CCM length parameters has been
Packit 0680ba
                                 processed.  */
Packit 0680ba
    } ccm;
Packit 0680ba
#endif
Packit 0680ba
Packit 0680ba
    /* Mode specific storage for CMAC mode. */
Packit 0680ba
    struct {
Packit 0680ba
      unsigned int tag:1; /* Set to 1 if tag has been finalized.  */
Packit 0680ba
Packit 0680ba
      /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */
Packit 0680ba
      unsigned char subkeys[2][MAX_BLOCKSIZE];
Packit 0680ba
    } cmac;
Packit 0680ba
Packit 0680ba
    /* Mode specific storage for GCM mode. */
Packit 0680ba
    struct {
Packit 0680ba
      /* The interim tag for GCM mode.  */
Packit 0680ba
      union {
Packit 0680ba
        cipher_context_alignment_t iv_align;
Packit 0680ba
        unsigned char tag[MAX_BLOCKSIZE];
Packit 0680ba
      } u_tag;
Packit 0680ba
Packit 0680ba
      /* Space to save partial input lengths for MAC. */
Packit 0680ba
      unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
Packit 0680ba
      int mac_unused;  /* Number of unprocessed bytes in MACBUF. */
Packit 0680ba
Packit 0680ba
      /* byte counters for GCM */
Packit 0680ba
      u32 aadlen[2];
Packit 0680ba
      u32 datalen[2];
Packit 0680ba
Packit 0680ba
      /* encrypted tag counter */
Packit 0680ba
      unsigned char tagiv[MAX_BLOCKSIZE];
Packit 0680ba
Packit 0680ba
      unsigned int ghash_data_finalized:1;
Packit 0680ba
      unsigned int ghash_aad_finalized:1;
Packit 0680ba
Packit 0680ba
      unsigned int datalen_over_limits:1;
Packit 0680ba
      unsigned int disallow_encryption_because_of_setiv_in_fips_mode:1;
Packit 0680ba
Packit 0680ba
      /* --- Following members are not cleared in gcry_cipher_reset --- */
Packit 0680ba
Packit 0680ba
      /* GHASH multiplier from key.  */
Packit 0680ba
      union {
Packit 0680ba
        cipher_context_alignment_t iv_align;
Packit 0680ba
        unsigned char key[MAX_BLOCKSIZE];
Packit 0680ba
      } u_ghash_key;
Packit 0680ba
Packit 0680ba
#ifdef GCM_USE_INTEL_PCLMUL
Packit 0680ba
      /* Use Intel PCLMUL instructions for accelerated GHASH. */
Packit 0680ba
      unsigned int use_intel_pclmul:1;
Packit 0680ba
#endif
Packit 0680ba
Packit 0680ba
      /* Pre-calculated table for GCM. */
Packit 0680ba
#ifdef GCM_USE_TABLES
Packit 0680ba
 #if defined(HAVE_U64_TYPEDEF) && (SIZEOF_UNSIGNED_LONG == 8 \
Packit 0680ba
                                   || defined(__x86_64__))
Packit 0680ba
      #define GCM_TABLES_USE_U64 1
Packit 0680ba
      u64 gcm_table[2 * 16];
Packit 0680ba
 #else
Packit 0680ba
      #undef GCM_TABLES_USE_U64
Packit 0680ba
      u32 gcm_table[4 * 16];
Packit 0680ba
 #endif
Packit 0680ba
#endif
Packit 0680ba
    } gcm;
Packit 0680ba
  } u_mode;
Packit 0680ba
Packit 0680ba
  /* What follows are two contexts of the cipher in use.  The first
Packit 0680ba
     one needs to be aligned well enough for the cipher operation
Packit 0680ba
     whereas the second one is a copy created by cipher_setkey and
Packit 0680ba
     used by cipher_reset.  That second copy has no need for proper
Packit 0680ba
     aligment because it is only accessed by memcpy.  */
Packit 0680ba
  cipher_context_alignment_t context;
Packit 0680ba
};
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*-- cipher-cbc.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_cbc_encrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_cbc_decrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
Packit 0680ba
/*-- cipher-cfb.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_cfb_encrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_cfb_decrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*-- cipher-ofb.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_ofb_encrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
Packit 0680ba
/*-- cipher-ctr.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_ctr_encrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*-- cipher-aeswrap.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_aeswrap_encrypt
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   byte *outbuf, size_t outbuflen,
Packit 0680ba
                   const byte *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_aeswrap_decrypt
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   byte *outbuf, size_t outbuflen,
Packit 0680ba
                   const byte *inbuf, size_t inbuflen);
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*-- cipher-ccm.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_encrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_decrypt
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                 const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_set_nonce
Packit 0680ba
/*           */ (gcry_cipher_hd_t c, const unsigned char *nonce,
Packit 0680ba
                 size_t noncelen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_authenticate
Packit 0680ba
/*           */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
Packit 0680ba
#ifdef HAVE_U64_TYPEDEF
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_set_lengths
Packit 0680ba
/*           */ (gcry_cipher_hd_t c, u64 encryptedlen, u64 aadlen, u64 taglen);
Packit 0680ba
#endif
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_get_tag
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 unsigned char *outtag, size_t taglen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_ccm_check_tag
Packit 0680ba
/*           */ (gcry_cipher_hd_t c,
Packit 0680ba
                 const unsigned char *intag, size_t taglen);
Packit 0680ba
Packit 0680ba
Packit 0680ba
/*-- cipher-gcm.c --*/
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_encrypt
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                   const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_decrypt
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   unsigned char *outbuf, size_t outbuflen,
Packit 0680ba
                   const unsigned char *inbuf, size_t inbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_setiv
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   const unsigned char *iv, size_t ivlen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_authenticate
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   const unsigned char *aadbuf, size_t aadbuflen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_get_tag
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   unsigned char *outtag, size_t taglen);
Packit 0680ba
gcry_err_code_t _gcry_cipher_gcm_check_tag
Packit 0680ba
/*           */   (gcry_cipher_hd_t c,
Packit 0680ba
                   const unsigned char *intag, size_t taglen);
Packit 0680ba
void _gcry_cipher_gcm_setkey
Packit 0680ba
/*           */   (gcry_cipher_hd_t c);
Packit 0680ba
Packit 0680ba
Packit 0680ba
#endif /*G10_CIPHER_INTERNAL_H*/