libgcrypt: Import libgcrypt 1.11

We currently use an old version of libgcrypt which results in us having
fewer ciphers and missing on many other improvements.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Vladimir Serbinenko authored and Daniel Kiper committed 2025-07-11 23:12:50 +02:00
1 parent a0d4c94ef6
commit 3312af6e07
468 files changed
+210508 -33178

No files matched your search

+669 -104
View File
@@ -4,7 +4,7 @@
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
@@ -14,8 +14,8 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
* License along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
/* Test vectors:
@@ -42,22 +42,49 @@
#include "g10lib.h"
#include "types.h"
#include "cipher.h"
#include "bithelp.h"
#include "bufhelp.h"
#include "cipher-internal.h"
/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
#undef USE_AMD64_ASM
#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
# define USE_AMD64_ASM 1
#endif
/* USE_ARM_ASM indicates whether to use ARM assembly code. */
#undef USE_ARM_ASM
#if defined(__ARMEL__)
# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
# define USE_ARM_ASM 1
# endif
#endif
#define CAST5_BLOCKSIZE 8
typedef struct {
u32 Km[16];
byte Kr[16];
#ifdef USE_ARM_ASM
u32 Kr_arm_enc[16 / sizeof(u32)];
u32 Kr_arm_dec[16 / sizeof(u32)];
#endif
} CAST5_context;
static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen,
cipher_bulk_ops_t *bulk_ops);
static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf);
static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf);
#define s1 _gcry_cast5_s1to4[0]
#define s2 _gcry_cast5_s1to4[1]
#define s3 _gcry_cast5_s1to4[2]
#define s4 _gcry_cast5_s1to4[3]
static const u32 s1[256] = {
const u32 _gcry_cast5_s1to4[4][256] = { {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
@@ -90,8 +117,7 @@ static const u32 s1[256] = {
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
static const u32 s2[256] = {
}, {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
@@ -124,8 +150,7 @@ static const u32 s2[256] = {
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
};
static const u32 s3[256] = {
}, {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
@@ -158,8 +183,7 @@ static const u32 s3[256] = {
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
};
static const u32 s4[256] = {
}, {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
@@ -192,7 +216,7 @@ static const u32 s4[256] = {
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
} };
static const u32 s5[256] = {
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
@@ -331,24 +355,125 @@ static const u32 s8[256] = {
};
#if defined(__GNUC__) && defined(__i386__)
static inline u32
rol(int n, u32 x)
{
__asm__("roll %%cl,%0"
:"=r" (x)
:"0" (x),"c" (n));
return x;
}
#else
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
#endif
#ifdef USE_AMD64_ASM
#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \
/* Assembly implementations of CAST5. */
extern void _gcry_cast5_amd64_encrypt_block(CAST5_context *c, byte *outbuf,
const byte *inbuf);
extern void _gcry_cast5_amd64_decrypt_block(CAST5_context *c, byte *outbuf,
const byte *inbuf);
/* These assembly implementations process four blocks in parallel. */
extern void _gcry_cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out,
const byte *in, byte *ctr);
extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out,
const byte *in, byte *iv);
extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out,
const byte *in, byte *iv);
static void
do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
_gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf);
}
static void
do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
_gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf);
}
static void
cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr)
{
_gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr);
}
static void
cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
{
_gcry_cast5_amd64_cbc_dec (ctx, out, in, iv);
}
static void
cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
{
_gcry_cast5_amd64_cfb_dec (ctx, out, in, iv);
}
static unsigned int
encrypt_block (void *context , byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_encrypt_block (c, outbuf, inbuf);
return /*burn_stack*/ (2*8);
}
static unsigned int
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_decrypt_block (c, outbuf, inbuf);
return /*burn_stack*/ (2*8);
}
#elif defined(USE_ARM_ASM)
/* ARM assembly implementations of CAST5. */
extern void _gcry_cast5_arm_encrypt_block(CAST5_context *c, byte *outbuf,
const byte *inbuf);
extern void _gcry_cast5_arm_decrypt_block(CAST5_context *c, byte *outbuf,
const byte *inbuf);
/* These assembly implementations process two blocks in parallel. */
extern void _gcry_cast5_arm_ctr_enc(CAST5_context *ctx, byte *out,
const byte *in, byte *ctr);
extern void _gcry_cast5_arm_cbc_dec(CAST5_context *ctx, byte *out,
const byte *in, byte *iv);
extern void _gcry_cast5_arm_cfb_dec(CAST5_context *ctx, byte *out,
const byte *in, byte *iv);
static void
do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
_gcry_cast5_arm_encrypt_block (context, outbuf, inbuf);
}
static void
do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
_gcry_cast5_arm_decrypt_block (context, outbuf, inbuf);
}
static unsigned int
encrypt_block (void *context , byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_encrypt_block (c, outbuf, inbuf);
return /*burn_stack*/ (10*4);
}
static unsigned int
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_decrypt_block (c, outbuf, inbuf);
return /*burn_stack*/ (10*4);
}
#else /*USE_ARM_ASM*/
#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol(I,(r))), \
(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol(I,(r))), \
(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol(I,(r))), \
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static void
@@ -357,16 +482,16 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
u32 l, r, t;
u32 I; /* used by the Fx macros */
u32 *Km;
byte *Kr;
u32 Kr;
Km = c->Km;
Kr = c->Kr;
Kr = buf_get_le32(c->Kr + 0);
/* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
* right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
*/
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
l = buf_get_be32(inbuf + 0);
r = buf_get_be32(inbuf + 4);
/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
* Li = Ri-1;
@@ -376,41 +501,126 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
* Rounds 3, 6, 9, 12, and 15 use f function Type 3.
*/
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr & 31); Kr = buf_get_le32(c->Kr + 4);
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr & 31); Kr = buf_get_le32(c->Kr + 8);
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[10], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[11], Kr & 31); Kr = buf_get_le32(c->Kr + 12);
t = l; l = r; r = t ^ F1(r, Km[12], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[13], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[14], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[15], Kr & 31);
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
* concatenate to form the ciphertext.) */
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
buf_put_be32(outbuf + 0, r);
buf_put_be32(outbuf + 4, l);
}
static void
static unsigned int
encrypt_block (void *context , byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_encrypt_block (c, outbuf, inbuf);
_gcry_burn_stack (20+4*sizeof(void*));
return /*burn_stack*/ (20+4*sizeof(void*));
}
static void
do_encrypt_block_3( CAST5_context *c, byte *outbuf, const byte *inbuf )
{
u32 l0, r0, t0, l1, r1, t1, l2, r2, t2;
u32 I; /* used by the Fx macros */
u32 *Km;
u32 Kr;
Km = c->Km;
Kr = buf_get_le32(c->Kr + 0);
l0 = buf_get_be32(inbuf + 0);
r0 = buf_get_be32(inbuf + 4);
l1 = buf_get_be32(inbuf + 8);
r1 = buf_get_be32(inbuf + 12);
l2 = buf_get_be32(inbuf + 16);
r2 = buf_get_be32(inbuf + 20);
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 0], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 0], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 0], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 1], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 1], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 1], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 2], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 2], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 2], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 3], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 3], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 3], Kr & 31);
Kr = buf_get_le32(c->Kr + 4);
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 4], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 4], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 4], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 5], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 5], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 5], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 6], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 6], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 6], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 7], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 7], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 7], Kr & 31);
Kr = buf_get_le32(c->Kr + 8);
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 8], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 8], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 8], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 9], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 9], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 9], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[10], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[10], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[10], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[11], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[11], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[11], Kr & 31);
Kr = buf_get_le32(c->Kr + 12);
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[12], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[12], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[12], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[13], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[13], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[13], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[14], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[14], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[14], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[15], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[15], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[15], Kr & 31);
buf_put_be32(outbuf + 0, r0);
buf_put_be32(outbuf + 4, l0);
buf_put_be32(outbuf + 8, r1);
buf_put_be32(outbuf + 12, l1);
buf_put_be32(outbuf + 16, r2);
buf_put_be32(outbuf + 20, l2);
}
@@ -420,47 +630,363 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
u32 l, r, t;
u32 I;
u32 *Km;
byte *Kr;
u32 Kr;
Km = c->Km;
Kr = c->Kr;
Kr = buf_get_be32(c->Kr + 12);
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
l = buf_get_be32(inbuf + 0);
r = buf_get_be32(inbuf + 4);
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
t = l; l = r; r = t ^ F1(r, Km[15], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[14], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[13], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[12], Kr & 31); Kr = buf_get_be32(c->Kr + 8);
t = l; l = r; r = t ^ F3(r, Km[11], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[10], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr & 31); Kr = buf_get_be32(c->Kr + 4);
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr & 31); Kr = buf_get_be32(c->Kr + 0);
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr & 31); Kr >>= 8;
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr & 31);
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
buf_put_be32(outbuf + 0, r);
buf_put_be32(outbuf + 4, l);
}
static void
static unsigned int
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
{
CAST5_context *c = (CAST5_context *) context;
do_decrypt_block (c, outbuf, inbuf);
_gcry_burn_stack (20+4*sizeof(void*));
return /*burn_stack*/ (20+4*sizeof(void*));
}
static void
do_decrypt_block_3 (CAST5_context *c, byte *outbuf, const byte *inbuf )
{
u32 l0, r0, t0, l1, r1, t1, l2, r2, t2;
u32 I;
u32 *Km;
u32 Kr;
Km = c->Km;
Kr = buf_get_be32(c->Kr + 12);
l0 = buf_get_be32(inbuf + 0);
r0 = buf_get_be32(inbuf + 4);
l1 = buf_get_be32(inbuf + 8);
r1 = buf_get_be32(inbuf + 12);
l2 = buf_get_be32(inbuf + 16);
r2 = buf_get_be32(inbuf + 20);
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[15], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[15], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[15], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[14], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[14], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[14], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[13], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[13], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[13], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[12], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[12], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[12], Kr & 31);
Kr = buf_get_be32(c->Kr + 8);
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[11], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[11], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[11], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[10], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[10], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[10], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 9], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 9], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 9], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 8], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 8], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 8], Kr & 31);
Kr = buf_get_be32(c->Kr + 4);
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 7], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 7], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 7], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 6], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 6], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 6], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 5], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 5], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 5], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 4], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 4], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 4], Kr & 31);
Kr = buf_get_be32(c->Kr + 0);
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 3], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 3], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 3], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 2], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 2], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 2], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 1], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 1], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 1], Kr & 31);
Kr >>= 8;
t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 0], Kr & 31);
t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 0], Kr & 31);
t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 0], Kr & 31);
buf_put_be32(outbuf + 0, r0);
buf_put_be32(outbuf + 4, l0);
buf_put_be32(outbuf + 8, r1);
buf_put_be32(outbuf + 12, l1);
buf_put_be32(outbuf + 16, r2);
buf_put_be32(outbuf + 20, l2);
}
#endif /*!USE_ARM_ASM*/
/* Bulk encryption of complete blocks in CTR mode. This function is only
intended for the bulk encryption feature of cipher.c. CTR is expected to be
of size CAST5_BLOCKSIZE. */
static void
_gcry_cast5_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks)
{
CAST5_context *ctx = context;
unsigned char *outbuf = outbuf_arg;
const unsigned char *inbuf = inbuf_arg;
unsigned char tmpbuf[CAST5_BLOCKSIZE * 3];
int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE;
#ifdef USE_AMD64_ASM
{
if (nblocks >= 4)
burn_stack_depth += 8 * sizeof(void*);
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
nblocks -= 4;
outbuf += 4 * CAST5_BLOCKSIZE;
inbuf += 4 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#elif defined(USE_ARM_ASM)
{
/* Process data in 2 block chunks. */
while (nblocks >= 2)
{
_gcry_cast5_arm_ctr_enc(ctx, outbuf, inbuf, ctr);
nblocks -= 2;
outbuf += 2 * CAST5_BLOCKSIZE;
inbuf += 2 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#endif
#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM)
for ( ;nblocks >= 3; nblocks -= 3)
{
/* Prepare the counter blocks. */
cipher_block_cpy (tmpbuf + 0, ctr, CAST5_BLOCKSIZE);
cipher_block_cpy (tmpbuf + 8, ctr, CAST5_BLOCKSIZE);
cipher_block_cpy (tmpbuf + 16, ctr, CAST5_BLOCKSIZE);
cipher_block_add (tmpbuf + 8, 1, CAST5_BLOCKSIZE);
cipher_block_add (tmpbuf + 16, 2, CAST5_BLOCKSIZE);
cipher_block_add (ctr, 3, CAST5_BLOCKSIZE);
/* Encrypt the counter. */
do_encrypt_block_3(ctx, tmpbuf, tmpbuf);
/* XOR the input with the encrypted counter and store in output. */
buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE * 3);
outbuf += CAST5_BLOCKSIZE * 3;
inbuf += CAST5_BLOCKSIZE * 3;
}
#endif
for ( ;nblocks; nblocks-- )
{
/* Encrypt the counter. */
do_encrypt_block(ctx, tmpbuf, ctr);
/* XOR the input with the encrypted counter and store in output. */
cipher_block_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE);
outbuf += CAST5_BLOCKSIZE;
inbuf += CAST5_BLOCKSIZE;
/* Increment the counter. */
cipher_block_add (ctr, 1, CAST5_BLOCKSIZE);
}
wipememory(tmpbuf, sizeof(tmpbuf));
_gcry_burn_stack(burn_stack_depth);
}
/* Bulk decryption of complete blocks in CBC mode. This function is only
intended for the bulk encryption feature of cipher.c. */
static void
_gcry_cast5_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks)
{
CAST5_context *ctx = context;
unsigned char *outbuf = outbuf_arg;
const unsigned char *inbuf = inbuf_arg;
unsigned char savebuf[CAST5_BLOCKSIZE * 3];
int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE;
#ifdef USE_AMD64_ASM
{
if (nblocks >= 4)
burn_stack_depth += 8 * sizeof(void*);
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
nblocks -= 4;
outbuf += 4 * CAST5_BLOCKSIZE;
inbuf += 4 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#elif defined(USE_ARM_ASM)
{
/* Process data in 2 block chunks. */
while (nblocks >= 2)
{
_gcry_cast5_arm_cbc_dec(ctx, outbuf, inbuf, iv);
nblocks -= 2;
outbuf += 2 * CAST5_BLOCKSIZE;
inbuf += 2 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#endif
#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM)
for ( ;nblocks >= 3; nblocks -= 3)
{
/* INBUF is needed later and it may be identical to OUTBUF, so store
the intermediate result to SAVEBUF. */
do_decrypt_block_3 (ctx, savebuf, inbuf);
cipher_block_xor_1 (savebuf + 0, iv, CAST5_BLOCKSIZE);
cipher_block_xor_1 (savebuf + 8, inbuf, CAST5_BLOCKSIZE * 2);
cipher_block_cpy (iv, inbuf + 16, CAST5_BLOCKSIZE);
buf_cpy (outbuf, savebuf, CAST5_BLOCKSIZE * 3);
inbuf += CAST5_BLOCKSIZE * 3;
outbuf += CAST5_BLOCKSIZE * 3;
}
#endif
for ( ;nblocks; nblocks-- )
{
/* INBUF is needed later and it may be identical to OUTBUF, so store
the intermediate result to SAVEBUF. */
do_decrypt_block (ctx, savebuf, inbuf);
cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE);
inbuf += CAST5_BLOCKSIZE;
outbuf += CAST5_BLOCKSIZE;
}
wipememory(savebuf, sizeof(savebuf));
_gcry_burn_stack(burn_stack_depth);
}
/* Bulk decryption of complete blocks in CFB mode. This function is only
intended for the bulk encryption feature of cipher.c. */
static void
_gcry_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
const void *inbuf_arg, size_t nblocks)
{
CAST5_context *ctx = context;
unsigned char *outbuf = outbuf_arg;
const unsigned char *inbuf = inbuf_arg;
unsigned char tmpbuf[CAST5_BLOCKSIZE * 3];
int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE;
#ifdef USE_AMD64_ASM
{
if (nblocks >= 4)
burn_stack_depth += 8 * sizeof(void*);
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
nblocks -= 4;
outbuf += 4 * CAST5_BLOCKSIZE;
inbuf += 4 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#elif defined(USE_ARM_ASM)
{
/* Process data in 2 block chunks. */
while (nblocks >= 2)
{
_gcry_cast5_arm_cfb_dec(ctx, outbuf, inbuf, iv);
nblocks -= 2;
outbuf += 2 * CAST5_BLOCKSIZE;
inbuf += 2 * CAST5_BLOCKSIZE;
}
/* Use generic code to handle smaller chunks... */
}
#endif
#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM)
for ( ;nblocks >= 3; nblocks -= 3 )
{
cipher_block_cpy (tmpbuf + 0, iv, CAST5_BLOCKSIZE);
cipher_block_cpy (tmpbuf + 8, inbuf + 0, CAST5_BLOCKSIZE * 2);
cipher_block_cpy (iv, inbuf + 16, CAST5_BLOCKSIZE);
do_encrypt_block_3 (ctx, tmpbuf, tmpbuf);
buf_xor (outbuf, inbuf, tmpbuf, CAST5_BLOCKSIZE * 3);
outbuf += CAST5_BLOCKSIZE * 3;
inbuf += CAST5_BLOCKSIZE * 3;
}
#endif
for ( ;nblocks; nblocks-- )
{
do_encrypt_block(ctx, iv, iv);
cipher_block_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE);
outbuf += CAST5_BLOCKSIZE;
inbuf += CAST5_BLOCKSIZE;
}
wipememory(tmpbuf, sizeof(tmpbuf));
_gcry_burn_stack(burn_stack_depth);
}
@@ -468,13 +994,17 @@ static const char*
selftest(void)
{
CAST5_context c;
byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
cipher_bulk_ops_t bulk_ops;
static const byte key[16] =
{ 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
static const byte plain[8] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
static const byte cipher[8] =
{ 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
byte buffer[8];
cast_setkey( &c, key, 16 );
cast_setkey( &c, key, 16, &bulk_ops );
encrypt_block( &c, buffer, plain );
if( memcmp( buffer, cipher, 8 ) )
return "1";
@@ -495,10 +1025,10 @@ selftest(void)
0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
for(i=0; i < 1000000; i++ ) {
cast_setkey( &c, b0, 16 );
cast_setkey( &c, b0, 16, &bulk_ops );
encrypt_block( &c, a0, a0 );
encrypt_block( &c, a0+8, a0+8 );
cast_setkey( &c, a0, 16 );
cast_setkey( &c, a0, 16, &bulk_ops );
encrypt_block( &c, b0, b0 );
encrypt_block( &c, b0+8, b0+8 );
}
@@ -507,6 +1037,7 @@ selftest(void)
}
#endif
return NULL;
}
@@ -582,10 +1113,10 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
if( keylen != 16 )
return GPG_ERR_INV_KEYLEN;
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11];
x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
x[0] = buf_get_be32(key + 0);
x[1] = buf_get_be32(key + 4);
x[2] = buf_get_be32(key + 8);
x[3] = buf_get_be32(key + 12);
key_schedule( x, z, k );
for(i=0; i < 16; i++ )
@@ -594,9 +1125,35 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
for(i=0; i < 16; i++ )
c->Kr[i] = k[i] & 0x1f;
memset(&x,0, sizeof x);
memset(&z,0, sizeof z);
memset(&k,0, sizeof k);
#ifdef USE_ARM_ASM
for (i = 0; i < 4; i++)
{
byte Kr_arm[4];
/* Convert rotate left to rotate right and add shift left
* by 2. */
Kr_arm[0] = ((32 - c->Kr[4 * i + 0]) - 2) & 0x1f;
Kr_arm[1] = ((32 - c->Kr[4 * i + 1]) - 2) & 0x1f;
Kr_arm[2] = ((32 - c->Kr[4 * i + 2]) - 2) & 0x1f;
Kr_arm[3] = ((32 - c->Kr[4 * i + 3]) - 2) & 0x1f;
/* Endian friendly store. */
c->Kr_arm_enc[i] = Kr_arm[0] |
(Kr_arm[1] << 8) |
(Kr_arm[2] << 16) |
(Kr_arm[3] << 24);
c->Kr_arm_dec[i] = Kr_arm[3] |
(Kr_arm[2] << 8) |
(Kr_arm[1] << 16) |
(Kr_arm[0] << 24);
wipememory(Kr_arm, sizeof(Kr_arm));
}
#endif
wipememory(x, sizeof x);
wipememory(z, sizeof z);
wipememory(k, sizeof k);
#undef xi
#undef zi
@@ -604,17 +1161,25 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
}
static gcry_err_code_t
cast_setkey (void *context, const byte *key, unsigned keylen )
cast_setkey (void *context, const byte *key, unsigned keylen,
cipher_bulk_ops_t *bulk_ops)
{
CAST5_context *c = (CAST5_context *) context;
gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
_gcry_burn_stack (96+7*sizeof(void*));
/* Setup bulk encryption routines. */
memset (bulk_ops, 0, sizeof(*bulk_ops));
bulk_ops->cfb_dec = _gcry_cast5_cfb_dec;
bulk_ops->cbc_dec = _gcry_cast5_cbc_dec;
bulk_ops->ctr_enc = _gcry_cast5_ctr_enc;
return rc;
}
gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
{
GCRY_CIPHER_CAST5, {0, 0},
"CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
cast_setkey, encrypt_block, decrypt_block
};