|
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*/
|