summaryrefslogtreecommitdiff
path: root/cipher/cipher.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-09-15 18:55:28 +0200
committerWerner Koch <wk@gnupg.org>2011-09-15 19:09:18 +0200
commitba7127721035ee0937167e16465cc9f40b39257d (patch)
treeef833c3dab4ecea484090f216f81f895cc902785 /cipher/cipher.c
parent889a25ed3333d1d7657b4b59ae21f6e8458f9027 (diff)
parentad792d462d001858af89485380bf8f8a4a8dcd5d (diff)
downloadlibgcrypt-ba7127721035ee0937167e16465cc9f40b39257d.tar.gz
Factor cipher mode code out to separate files.
Fixed Changelog and Makefile. Added missing cipher-aeswrap.c file.
Diffstat (limited to 'cipher/cipher.c')
-rw-r--r--cipher/cipher.c822
1 files changed, 13 insertions, 809 deletions
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 3b6e9d52..9bef3329 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -27,19 +27,7 @@
#include "g10lib.h"
#include "cipher.h"
#include "ath.h"
-
-#define MAX_BLOCKSIZE 16
-#define TABLE_SIZE 14
-#define CTX_MAGIC_NORMAL 0x24091964
-#define CTX_MAGIC_SECURE 0x46919042
-
-/* Try to use 16 byte aligned cipher context for better performance.
- We use the aligned attribute, thus it is only possible to implement
- this with gcc. */
-#undef NEED_16BYTE_ALIGNED_CONTEXT
-#if defined (__GNUC__)
-# define NEED_16BYTE_ALIGNED_CONTEXT 1
-#endif
+#include "./cipher-internal.h"
/* A dummy extraspec so that we do not need to tests the extraspec
field from the module specification against NULL and instead
@@ -140,98 +128,6 @@ static int default_ciphers_registered;
while (0)
-/* A VIA processor with the Padlock engine as well as the Intel AES_NI
- instructions require an alignment of most data on a 16 byte
- boundary. Because we trick out the compiler while allocating the
- context, the align attribute as used in rijndael.c does not work on
- its own. Thus we need to make sure that the entire context
- structure is a aligned on that boundary. We achieve this by
- defining a new type and use that instead of our usual alignment
- type. */
-typedef union
-{
- PROPERLY_ALIGNED_TYPE foo;
-#ifdef NEED_16BYTE_ALIGNED_CONTEXT
- char bar[16] __attribute__ ((aligned (16)));
-#endif
- char c[1];
-} cipher_context_alignment_t;
-
-
-/* The handle structure. */
-struct gcry_cipher_handle
-{
- int magic;
- size_t actual_handle_size; /* Allocated size of this handle. */
- size_t handle_offset; /* Offset to the malloced block. */
- gcry_cipher_spec_t *cipher;
- cipher_extra_spec_t *extraspec;
- gcry_module_t module;
-
- /* The algorithm id. This is a hack required because the module
- interface does not easily allow to retrieve this value. */
- int algo;
-
- /* A structure with function pointers for bulk operations. Due to
- limitations of the module system (we don't want to change the
- API) we need to keep these function pointers here. The cipher
- open function intializes them and the actual encryption routines
- use them if they are not NULL. */
- struct {
- void (*cfb_enc)(void *context, unsigned char *iv,
- void *outbuf_arg, const void *inbuf_arg,
- unsigned int nblocks);
- void (*cfb_dec)(void *context, unsigned char *iv,
- void *outbuf_arg, const void *inbuf_arg,
- unsigned int nblocks);
- void (*cbc_enc)(void *context, unsigned char *iv,
- void *outbuf_arg, const void *inbuf_arg,
- unsigned int nblocks, int cbc_mac);
- void (*cbc_dec)(void *context, unsigned char *iv,
- void *outbuf_arg, const void *inbuf_arg,
- unsigned int nblocks);
- void (*ctr_enc)(void *context, unsigned char *iv,
- void *outbuf_arg, const void *inbuf_arg,
- unsigned int nblocks);
- } bulk;
-
-
- int mode;
- unsigned int flags;
-
- struct {
- unsigned int key:1; /* Set to 1 if a key has been set. */
- unsigned int iv:1; /* Set to 1 if a IV has been set. */
- } marks;
-
- /* The initialization vector. For best performance we make sure
- that it is properly aligned. In particular some implementations
- of bulk operations expect an 16 byte aligned IV. */
- union {
- cipher_context_alignment_t iv_align;
- unsigned char iv[MAX_BLOCKSIZE];
- } u_iv;
-
- /* The counter for CTR mode. This field is also used by AESWRAP and
- thus we can't use the U_IV union. */
- union {
- cipher_context_alignment_t iv_align;
- unsigned char ctr[MAX_BLOCKSIZE];
- } u_ctr;
-
- /* Space to save an IV or CTR for chaining operations. */
- unsigned char lastiv[MAX_BLOCKSIZE];
- int unused; /* Number of unused bytes in LASTIV. */
-
- /* What follows are two contexts of the cipher in use. The first
- one needs to be aligned well enough for the cipher operation
- whereas the second one is a copy created by cipher_setkey and
- used by cipher_reset. That second copy has no need for proper
- aligment because it is only accessed by memcpy. */
- cipher_context_alignment_t context;
-};
-
-
/* These dummy functions are used in case a cipher implementation
refuses to provide it's own functions. */
@@ -991,700 +887,6 @@ do_ecb_decrypt (gcry_cipher_hd_t c,
}
-static gcry_err_code_t
-do_cbc_encrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned int n;
- unsigned char *ivp;
- int i;
- size_t blocksize = c->cipher->blocksize;
- unsigned nblocks = inbuflen / blocksize;
-
- if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if ((inbuflen % c->cipher->blocksize)
- && !(inbuflen > c->cipher->blocksize
- && (c->flags & GCRY_CIPHER_CBC_CTS)))
- return GPG_ERR_INV_LENGTH;
-
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
- {
- if ((inbuflen % blocksize) == 0)
- nblocks--;
- }
-
- if (c->bulk.cbc_enc)
- {
- c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
- (c->flags & GCRY_CIPHER_CBC_MAC));
- inbuf += nblocks * blocksize;
- if (!(c->flags & GCRY_CIPHER_CBC_MAC))
- outbuf += nblocks * blocksize;
- }
- else
- {
- for (n=0; n < nblocks; n++ )
- {
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- outbuf[i] = inbuf[i] ^ *ivp++;
- c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
- memcpy (c->u_iv.iv, outbuf, blocksize );
- inbuf += blocksize;
- if (!(c->flags & GCRY_CIPHER_CBC_MAC))
- outbuf += blocksize;
- }
- }
-
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
- {
- /* We have to be careful here, since outbuf might be equal to
- inbuf. */
- int restbytes;
- unsigned char b;
-
- if ((inbuflen % blocksize) == 0)
- restbytes = blocksize;
- else
- restbytes = inbuflen % blocksize;
-
- outbuf -= blocksize;
- for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
- {
- b = inbuf[i];
- outbuf[blocksize + i] = outbuf[i];
- outbuf[i] = b ^ *ivp++;
- }
- for (; i < blocksize; i++)
- outbuf[i] = 0 ^ *ivp++;
-
- c->cipher->encrypt (&c->context.c, outbuf, outbuf);
- memcpy (c->u_iv.iv, outbuf, blocksize);
- }
-
- return 0;
-}
-
-
-static gcry_err_code_t
-do_cbc_decrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned int n;
- unsigned char *ivp;
- int i;
- size_t blocksize = c->cipher->blocksize;
- unsigned int nblocks = inbuflen / blocksize;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if ((inbuflen % c->cipher->blocksize)
- && !(inbuflen > c->cipher->blocksize
- && (c->flags & GCRY_CIPHER_CBC_CTS)))
- return GPG_ERR_INV_LENGTH;
-
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
- {
- nblocks--;
- if ((inbuflen % blocksize) == 0)
- nblocks--;
- memcpy (c->lastiv, c->u_iv.iv, blocksize);
- }
-
- if (c->bulk.cbc_dec)
- {
- c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
- inbuf += nblocks * blocksize;
- outbuf += nblocks * blocksize;
- }
- else
- {
- for (n=0; n < nblocks; n++ )
- {
- /* Because outbuf and inbuf might be the same, we have to
- * save the original ciphertext block. We use LASTIV for
- * this here because it is not used otherwise. */
- memcpy (c->lastiv, inbuf, blocksize);
- c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- outbuf[i] ^= *ivp++;
- memcpy(c->u_iv.iv, c->lastiv, blocksize );
- inbuf += c->cipher->blocksize;
- outbuf += c->cipher->blocksize;
- }
- }
-
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
- {
- int restbytes;
-
- if ((inbuflen % blocksize) == 0)
- restbytes = blocksize;
- else
- restbytes = inbuflen % blocksize;
-
- memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */
- memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
-
- c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
- for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
- outbuf[i] ^= *ivp++;
-
- memcpy(outbuf + blocksize, outbuf, restbytes);
- for(i=restbytes; i < blocksize; i++)
- c->u_iv.iv[i] = outbuf[i];
- c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv);
- for(ivp=c->lastiv,i=0; i < blocksize; i++ )
- outbuf[i] ^= *ivp++;
- /* c->lastiv is now really lastlastiv, does this matter? */
- }
-
- return 0;
-}
-
-
-static gcry_err_code_t
-do_cfb_encrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned char *ivp;
- size_t blocksize = c->cipher->blocksize;
- size_t blocksize_x_2 = blocksize + blocksize;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if ( inbuflen <= c->unused )
- {
- /* Short enough to be encoded by the remaining XOR mask. */
- /* XOR the input with the IV and store input into IV. */
- for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
- inbuflen;
- inbuflen--, c->unused-- )
- *outbuf++ = (*ivp++ ^= *inbuf++);
- return 0;
- }
-
- if ( c->unused )
- {
- /* XOR the input with the IV and store input into IV */
- inbuflen -= c->unused;
- for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
- *outbuf++ = (*ivp++ ^= *inbuf++);
- }
-
- /* Now we can process complete blocks. We use a loop as long as we
- have at least 2 blocks and use conditions for the rest. This
- also allows to use a bulk encryption function if available. */
- if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
- {
- unsigned int nblocks = inbuflen / blocksize;
- c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
- outbuf += nblocks * blocksize;
- inbuf += nblocks * blocksize;
- inbuflen -= nblocks * blocksize;
- }
- else
- {
- while ( inbuflen >= blocksize_x_2 )
- {
- int i;
- /* Encrypt the IV. */
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- /* XOR the input with the IV and store input into IV. */
- for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- *outbuf++ = (*ivp++ ^= *inbuf++);
- inbuflen -= blocksize;
- }
- }
-
- if ( inbuflen >= blocksize )
- {
- int i;
- /* Save the current IV and then encrypt the IV. */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- /* XOR the input with the IV and store input into IV */
- for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- *outbuf++ = (*ivp++ ^= *inbuf++);
- inbuflen -= blocksize;
- }
- if ( inbuflen )
- {
- /* Save the current IV and then encrypt the IV. */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- c->unused = blocksize;
- /* Apply the XOR. */
- c->unused -= inbuflen;
- for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
- *outbuf++ = (*ivp++ ^= *inbuf++);
- }
- return 0;
-}
-
-
-static gcry_err_code_t
-do_cfb_decrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned char *ivp;
- unsigned long temp;
- int i;
- size_t blocksize = c->cipher->blocksize;
- size_t blocksize_x_2 = blocksize + blocksize;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if (inbuflen <= c->unused)
- {
- /* Short enough to be encoded by the remaining XOR mask. */
- /* XOR the input with the IV and store input into IV. */
- for (ivp=c->u_iv.iv+blocksize - c->unused;
- inbuflen;
- inbuflen--, c->unused--)
- {
- temp = *inbuf++;
- *outbuf++ = *ivp ^ temp;
- *ivp++ = temp;
- }
- return 0;
- }
-
- if (c->unused)
- {
- /* XOR the input with the IV and store input into IV. */
- inbuflen -= c->unused;
- for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
- {
- temp = *inbuf++;
- *outbuf++ = *ivp ^ temp;
- *ivp++ = temp;
- }
- }
-
- /* Now we can process complete blocks. We use a loop as long as we
- have at least 2 blocks and use conditions for the rest. This
- also allows to use a bulk encryption function if available. */
- if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
- {
- unsigned int nblocks = inbuflen / blocksize;
- c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
- outbuf += nblocks * blocksize;
- inbuf += nblocks * blocksize;
- inbuflen -= nblocks * blocksize;
- }
- else
- {
- while (inbuflen >= blocksize_x_2 )
- {
- /* Encrypt the IV. */
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- /* XOR the input with the IV and store input into IV. */
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- {
- temp = *inbuf++;
- *outbuf++ = *ivp ^ temp;
- *ivp++ = temp;
- }
- inbuflen -= blocksize;
- }
- }
-
- if (inbuflen >= blocksize )
- {
- /* Save the current IV and then encrypt the IV. */
- memcpy ( c->lastiv, c->u_iv.iv, blocksize);
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- /* XOR the input with the IV and store input into IV */
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- {
- temp = *inbuf++;
- *outbuf++ = *ivp ^ temp;
- *ivp++ = temp;
- }
- inbuflen -= blocksize;
- }
-
- if (inbuflen)
- {
- /* Save the current IV and then encrypt the IV. */
- memcpy ( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- c->unused = blocksize;
- /* Apply the XOR. */
- c->unused -= inbuflen;
- for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
- {
- temp = *inbuf++;
- *outbuf++ = *ivp ^ temp;
- *ivp++ = temp;
- }
- }
- return 0;
-}
-
-
-static gcry_err_code_t
-do_ofb_encrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned char *ivp;
- size_t blocksize = c->cipher->blocksize;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if ( inbuflen <= c->unused )
- {
- /* Short enough to be encoded by the remaining XOR mask. */
- /* XOR the input with the IV */
- for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
- inbuflen;
- inbuflen--, c->unused-- )
- *outbuf++ = (*ivp++ ^ *inbuf++);
- return 0;
- }
-
- if( c->unused )
- {
- inbuflen -= c->unused;
- for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
- *outbuf++ = (*ivp++ ^ *inbuf++);
- }
-
- /* Now we can process complete blocks. */
- while ( inbuflen >= blocksize )
- {
- int i;
- /* Encrypt the IV (and save the current one). */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- *outbuf++ = (*ivp++ ^ *inbuf++);
- inbuflen -= blocksize;
- }
- if ( inbuflen )
- { /* process the remaining bytes */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- c->unused = blocksize;
- c->unused -= inbuflen;
- for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
- *outbuf++ = (*ivp++ ^ *inbuf++);
- }
- return 0;
-}
-
-static gcry_err_code_t
-do_ofb_decrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned char *ivp;
- size_t blocksize = c->cipher->blocksize;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- if( inbuflen <= c->unused )
- {
- /* Short enough to be encoded by the remaining XOR mask. */
- for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--)
- *outbuf++ = *ivp++ ^ *inbuf++;
- return 0;
- }
-
- if ( c->unused )
- {
- inbuflen -= c->unused;
- for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
- *outbuf++ = *ivp++ ^ *inbuf++;
- }
-
- /* Now we can process complete blocks. */
- while ( inbuflen >= blocksize )
- {
- int i;
- /* Encrypt the IV (and save the current one). */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
- *outbuf++ = *ivp++ ^ *inbuf++;
- inbuflen -= blocksize;
- }
- if ( inbuflen )
- { /* Process the remaining bytes. */
- /* Encrypt the IV (and save the current one). */
- memcpy( c->lastiv, c->u_iv.iv, blocksize );
- c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
- c->unused = blocksize;
- c->unused -= inbuflen;
- for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
- *outbuf++ = *ivp++ ^ *inbuf++;
- }
- return 0;
-}
-
-
-static gcry_err_code_t
-do_ctr_encrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- unsigned int n;
- int i;
- unsigned int blocksize = c->cipher->blocksize;
- unsigned int nblocks;
-
- if (outbuflen < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
-
- /* First process a left over encrypted counter. */
- if (c->unused)
- {
- gcry_assert (c->unused < blocksize);
- i = blocksize - c->unused;
- for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++)
- {
- /* XOR input with encrypted counter and store in output. */
- outbuf[n] = inbuf[n] ^ c->lastiv[i];
- }
- inbuf += n;
- outbuf += n;
- inbuflen -= n;
- }
-
-
- /* Use a bulk method if available. */
- nblocks = inbuflen / blocksize;
- if (nblocks && c->bulk.ctr_enc)
- {
- c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
- inbuf += nblocks * blocksize;
- outbuf += nblocks * blocksize;
- inbuflen -= nblocks * blocksize;
- }
-
- /* If we don't have a bulk method use the standard method. We also
- use this method for the a remaining partial block. */
- if (inbuflen)
- {
- unsigned char tmp[MAX_BLOCKSIZE];
-
- for (n=0; n < inbuflen; n++)
- {
- if ((n % blocksize) == 0)
- {
- c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr);
-
- for (i = blocksize; i > 0; i--)
- {
- c->u_ctr.ctr[i-1]++;
- if (c->u_ctr.ctr[i-1] != 0)
- break;
- }
- }
-
- /* XOR input with encrypted counter and store in output. */
- outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
- }
-
- /* Save the unused bytes of the counter. */
- n %= blocksize;
- c->unused = (blocksize - n) % blocksize;
- if (c->unused)
- memcpy (c->lastiv+n, tmp+n, c->unused);
-
- wipememory (tmp, sizeof tmp);
- }
-
- return 0;
-}
-
-static gcry_err_code_t
-do_ctr_decrypt (gcry_cipher_hd_t c,
- unsigned char *outbuf, unsigned int outbuflen,
- const unsigned char *inbuf, unsigned int inbuflen)
-{
- return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
-}
-
-
-/* Perform the AES-Wrap algorithm as specified by RFC3394. We
- implement this as a mode usable with any cipher algorithm of
- blocksize 128. */
-static gcry_err_code_t
-do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
- const byte *inbuf, unsigned int inbuflen )
-{
- int j, x;
- unsigned int n, i;
- unsigned char *r, *a, *b;
- unsigned char t[8];
-
-#if MAX_BLOCKSIZE < 8
-#error Invalid block size
-#endif
- /* We require a cipher with a 128 bit block length. */
- if (c->cipher->blocksize != 16)
- return GPG_ERR_INV_LENGTH;
-
- /* The output buffer must be able to hold the input data plus one
- additional block. */
- if (outbuflen < inbuflen + 8)
- return GPG_ERR_BUFFER_TOO_SHORT;
- /* Input data must be multiple of 64 bits. */
- if (inbuflen % 8)
- return GPG_ERR_INV_ARG;
-
- n = inbuflen / 8;
-
- /* We need at least two 64 bit blocks. */
- if (n < 2)
- return GPG_ERR_INV_ARG;
-
- r = outbuf;
- a = outbuf; /* We store A directly in OUTBUF. */
- b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
-
- /* If an IV has been set we use that IV as the Alternative Initial
- Value; if it has not been set we use the standard value. */
- if (c->marks.iv)
- memcpy (a, c->u_iv.iv, 8);
- else
- memset (a, 0xa6, 8);
-
- /* Copy the inbuf to the outbuf. */
- memmove (r+8, inbuf, inbuflen);
-
- memset (t, 0, sizeof t); /* t := 0. */
-
- for (j = 0; j <= 5; j++)
- {
- for (i = 1; i <= n; i++)
- {
- /* B := AES_k( A | R[i] ) */
- memcpy (b, a, 8);
- memcpy (b+8, r+i*8, 8);
- c->cipher->encrypt (&c->context.c, b, b);
- /* t := t + 1 */
- for (x = 7; x >= 0; x--)
- {
- t[x]++;
- if (t[x])
- break;
- }
- /* A := MSB_64(B) ^ t */
- for (x=0; x < 8; x++)
- a[x] = b[x] ^ t[x];
- /* R[i] := LSB_64(B) */
- memcpy (r+i*8, b+8, 8);
- }
- }
-
- return 0;
-}
-
-/* Perform the AES-Unwrap algorithm as specified by RFC3394. We
- implement this as a mode usable with any cipher algorithm of
- blocksize 128. */
-static gcry_err_code_t
-do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
- const byte *inbuf, unsigned int inbuflen)
-{
- int j, x;
- unsigned int n, i;
- unsigned char *r, *a, *b;
- unsigned char t[8];
-
-#if MAX_BLOCKSIZE < 8
-#error Invalid block size
-#endif
- /* We require a cipher with a 128 bit block length. */
- if (c->cipher->blocksize != 16)
- return GPG_ERR_INV_LENGTH;
-
- /* The output buffer must be able to hold the input data minus one
- additional block. Fixme: The caller has more restrictive checks
- - we may want to fix them for this mode. */
- if (outbuflen + 8 < inbuflen)
- return GPG_ERR_BUFFER_TOO_SHORT;
- /* Input data must be multiple of 64 bits. */
- if (inbuflen % 8)
- return GPG_ERR_INV_ARG;
-
- n = inbuflen / 8;
-
- /* We need at least three 64 bit blocks. */
- if (n < 3)
- return GPG_ERR_INV_ARG;
-
- r = outbuf;
- a = c->lastiv; /* We use c->LASTIV as buffer for A. */
- b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
-
- /* Copy the inbuf to the outbuf and save A. */
- memcpy (a, inbuf, 8);
- memmove (r, inbuf+8, inbuflen-8);
- n--; /* Reduce to actual number of data blocks. */
-
- /* t := 6 * n */
- i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */
- for (x=0; x < 8 && x < sizeof (i); x++)
- t[7-x] = i >> (8*x);
- for (; x < 8; x++)
- t[7-x] = 0;
-
- for (j = 5; j >= 0; j--)
- {
- for (i = n; i >= 1; i--)
- {
- /* B := AES_k^1( (A ^ t)| R[i] ) */
- for (x = 0; x < 8; x++)
- b[x] = a[x] ^ t[x];
- memcpy (b+8, r+(i-1)*8, 8);
- c->cipher->decrypt (&c->context.c, b, b);
- /* t := t - 1 */
- for (x = 7; x >= 0; x--)
- {
- t[x]--;
- if (t[x] != 0xff)
- break;
- }
- /* A := MSB_64(B) */
- memcpy (a, b, 8);
- /* R[i] := LSB_64(B) */
- memcpy (r+(i-1)*8, b+8, 8);
- }
- }
-
- /* If an IV has been set we compare against this Alternative Initial
- Value; if it has not been set we compare against the standard IV. */
- if (c->marks.iv)
- j = memcmp (a, c->u_iv.iv, 8);
- else
- {
- for (j=0, x=0; x < 8; x++)
- if (a[x] != 0xa6)
- {
- j=1;
- break;
- }
- }
- return j? GPG_ERR_CHECKSUM : 0;
-}
-
-
/****************
* Encrypt INBUF to OUTBUF with the mode selected at open.
* inbuf and outbuf may overlap or be the same.
@@ -1703,23 +905,24 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
break;
case GCRY_CIPHER_MODE_CBC:
- rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_CFB:
- rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_OFB:
- rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_CTR:
- rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_AESWRAP:
- rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_aeswrap_encrypt (c, outbuf, outbuflen,
+ inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_STREAM:
@@ -1795,23 +998,24 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
break;
case GCRY_CIPHER_MODE_CBC:
- rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_CFB:
- rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_OFB:
- rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_CTR:
- rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_AESWRAP:
- rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ rc = _gcry_cipher_aeswrap_decrypt (c, outbuf, outbuflen,
+ inbuf, inbuflen);
break;
case GCRY_CIPHER_MODE_STREAM: