ColdFire SEC, fix cache control in aes, des3 driver

This commit is contained in:
Takashi Kojo 2014-04-23 16:56:37 +09:00
parent 1ba30b1eb6
commit 41199a480d
3 changed files with 263 additions and 193 deletions

View File

@ -148,14 +148,14 @@
(cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
/* set iv for the next call */
if(dir == PIC32_ENCRYPTION) {
XMEMCPY((void *)aes->iv_ce,
XMEMCPY((void *)aes->iv_ce,
(void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE),
AES_BLOCK_SIZE) ;
} else {
} else {
ByteReverseWords((word32*)aes->iv_ce,
(word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE),
AES_BLOCK_SIZE);
}
}
}
XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ;
ByteReverseWords((word32*)out, (word32 *)out, sz);
@ -603,124 +603,152 @@
#endif /* CYASSL_AES_COUNTER */
#elif defined(HAVE_COLDFIRE_SEC)
#elif defined(HAVE_COLDFIRE_SEC)
#include <cyassl/internal.h>
#include "sec.h"
#include "mcf548x_sec.h"
#include "mcf548x_siu.h"
#include "mcf5475_sec.h"
#include "mcf5475_siu.h"
#if defined (HAVE_THREADX)
#include "memory_pools.h"
extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */
#define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 8)
static unsigned char *AESBuffer = NULL ;
#endif
#define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
static unsigned char *AESBuffIn = NULL ;
static unsigned char *AESBuffOut = NULL ;
static byte *secReg ;
static byte *secKey ;
static volatile SECdescriptorType *secDesc ;
static CyaSSL_Mutex Mutex_AesSEC ;
#define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
#define SEC_DESC_AES_CBC_DECRYPT 0x60200010
#define AES_BLOCK_LENGTH 16
extern volatile unsigned char __MBAR[];
static int TimeCount = 0 ;
static int AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
{
int i ; int stat1, stat2 ;
int ret ; int size ;
volatile int v ;
if((pi == NULL) || (po == NULL))
return BAD_FUNC_ARG;/*wrong pointer*/
LockMutex(&Mutex_AesSEC) ;
/* Set descriptor for SEC */
secDesc->length1 = 0x0;
secDesc->pointer1 = NULL;
secDesc->length2 = AES_BLOCK_SIZE;
secDesc->pointer2 = (byte *)secReg ; /* Initial Vector */
switch(aes->rounds) {
case 10: secDesc->length3 = 16 ; break ;
case 12: secDesc->length3 = 24 ; break ;
case 14: secDesc->length3 = 32 ; break ;
}
XMEMCPY(secKey, aes->key, secDesc->length3) ;
secDesc->pointer3 = (byte *)secKey;
secDesc->pointer4 = AESBuffIn ;
secDesc->pointer5 = AESBuffOut ;
secDesc->length6 = 0x0;
secDesc->pointer6 = NULL;
secDesc->length7 = 0x0;
secDesc->pointer7 = NULL;
secDesc->nextDescriptorPtr = NULL;
while(sz) {
secDesc->header = descHeader ;
XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE) ;
if((sz%AES_BUFFER_SIZE) == sz) {
size = sz ;
sz = 0 ;
} else {
size = AES_BUFFER_SIZE ;
sz -= AES_BUFFER_SIZE ;
}
secDesc->length4 = size;
secDesc->length5 = size;
XMEMCPY(AESBuffIn, pi, size) ;
if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]), AES_BLOCK_SIZE) ;
}
/* Point SEC to the location of the descriptor */
MCF_SEC_FR0 = (uint32)secDesc;
/* Initialize SEC and wait for encryption to complete */
MCF_SEC_CCCR0 = 0x0000001a;
/* poll SISR to determine when channel is complete */
v=0 ;
while((secDesc->header>> 24) != 0xff)v++ ;
ret = MCF_SEC_SISRH;
stat1 = MCF_SEC_AESSR ;
stat2 = MCF_SEC_AESISR ;
if(ret & 0xe0000000)
{
db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, AESISR=%08x\n", i, ret, stat1, stat2) ;
}
XMEMCPY(po, AESBuffOut, size) ;
if(descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]), AES_BLOCK_SIZE) ;
} else {
XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE) ;
}
pi += size ;
po += size ;
}
UnLockMutex(&Mutex_AesSEC) ;
return 0 ; /* for descriptier header 0xff000000 mode */
}
int AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
{
return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT)) ;
return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT)) ;
}
int AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
{
return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)) ;
}
static int AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
{
int i ; int stat1, stat2 ;
int ret ; int size ;
static SECdescriptorType descriptor;
volatile int v ;
if((pi == NULL) || (po == NULL))
return BAD_FUNC_ARG;/*wrong pointer*/
while(sz) {
if((sz%AES_BUFFER_SIZE) == sz) {
size = sz ;
sz = 0 ;
} else {
size = AES_BUFFER_SIZE ;
sz -= AES_BUFFER_SIZE ;
}
/* Set descriptor for SEC */
descriptor.header = descHeader ;
/*
descriptor.length1 = 0x0;
descriptor.pointer1 = NULL;
*/
descriptor.length2 = AES_BLOCK_SIZE;
descriptor.pointer2 = (byte *)aes->reg ; /* Initial Vector */
switch(aes->rounds) {
case 10: descriptor.length3 = 16 ; break ;
case 12: descriptor.length3 = 24 ; break ;
case 14: descriptor.length3 = 32 ; break ;
}
descriptor.pointer3 = (byte *)aes->key;
descriptor.length4 = size;
descriptor.pointer4 = (byte *)pi ;
descriptor.length5 = size;
descriptor.pointer5 = AESBuffer ;
/*
descriptor.length6 = 0x0;
descriptor.pointer6 = NULL;
descriptor.length7 = 0x0;
descriptor.pointer7 = NULL;
descriptor.nextDescriptorPtr = NULL;
*/
/* Initialize SEC and wait for encryption to complete */
MCF_SEC_CCCR0 = 0x00000000;
/* Point SEC to the location of the descriptor */
MCF_SEC_FR0 = (uint32)&descriptor;
/* poll SISR to determine when channel is complete */
i=0 ;
while (!(MCF_SEC_SISRL) && !(MCF_SEC_SISRH))i++ ;
for(v=0; v<100; v++) ;
ret = MCF_SEC_SISRH;
stat1 = MCF_SEC_AESSR ;
stat2 = MCF_SEC_AESISR ;
if(ret & 0xe0000000)
{
db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, AESISR=%08x\n", i, ret, stat1, stat2) ;
}
XMEMCPY(po, AESBuffer, size) ;
if(descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]), AES_BLOCK_SIZE) ;
} else {
XMEMCPY((void*)aes->reg, (void*)&(pi[size-AES_BLOCK_SIZE]), AES_BLOCK_SIZE) ;
}
pi += size ;
po += size ;
}
return 0 ; /* for descriptier header 0xff000000 mode */
return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)) ;
}
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
int status ;
if(AESBuffer == NULL) {
status = tx_byte_allocate(&mp_ncached,(void *)&AESBuffer, AES_BUFFER_SIZE,TX_NO_WAIT);
}
int s1, s2, s3, s4, s5 ;
if(AESBuffIn == NULL) {
#if defined (HAVE_THREADX)
s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, sizeof(SECdescriptorType), TX_NO_WAIT);
s1 = tx_byte_allocate(&mp_ncached,(void *)&AESBuffIn, AES_BUFFER_SIZE, TX_NO_WAIT);
s2 = tx_byte_allocate(&mp_ncached,(void *)&AESBuffOut, AES_BUFFER_SIZE, TX_NO_WAIT);
s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey, AES_BLOCK_SIZE*2,TX_NO_WAIT);
s4 = tx_byte_allocate(&mp_ncached,(void *)&secReg, AES_BLOCK_SIZE, TX_NO_WAIT);
TimeCount = 0 ;
if(s1 || s2 || s3 || s4 || s5)
return BAD_FUNC_ARG;
#else
#error "Allocate non-Cache buffers"
#endif
InitMutex(&Mutex_AesSEC) ;
}
if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
return BAD_FUNC_ARG;
@ -732,6 +760,7 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
XMEMCPY(aes->key, userKey, keylen);
if (iv)
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
return 0;
}
@ -2724,7 +2753,7 @@ static void GMULT(word64* X, word64* Y)
{
word64 Z[2] = {0,0};
word64 V[2] ;
int i, j;
int i, j;
V[0] = X[0] ; V[1] = X[1] ;
for (i = 0; i < 2; i++)
@ -2825,7 +2854,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz,
/* Hash in the lengths in bits of A and C */
{
word64 len[2] ;
len[0] = aSz ; len[1] = cSz;
len[0] = aSz ; len[1] = cSz;
/* Lengths are in bytes. Convert to bits. */
len[0] *= 8;
@ -2851,7 +2880,7 @@ static void GMULT(word32* X, word32* Y)
int i, j;
V[0] = X[0]; V[1] = X[1]; V[2] = X[2]; V[3] = X[3];
for (i = 0; i < 4; i++)
{
word32 y = Y[i];

View File

@ -273,32 +273,72 @@
return 0;
}
#elif defined(HAVE_COLDFIRE_SEC)
#elif defined(HAVE_COLDFIRE_SEC)
#include <cyassl/internal.h>
#include "sec.h"
#include "mcf548x_sec.h"
#include "mcf5475_sec.h"
#include "mcf5475_siu.h"
#if defined (HAVE_THREADX)
#include "memory_pools.h"
extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */
#define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 16)
static unsigned char *DesBuffer = NULL ;
#endif
#define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)
static unsigned char *desBuffIn = NULL ;
static unsigned char *desBuffOut = NULL ;
static byte *secIV ;
static byte *secKey ;
static volatile SECdescriptorType *secDesc ;
static CyaSSL_Mutex Mutex_DesSEC ;
#define SEC_DESC_DES_CBC_ENCRYPT 0x20500010
#define SEC_DESC_DES_CBC_DECRYPT 0x20400010
#define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010
#define SEC_DESC_DES3_CBC_DECRYPT 0x20600010
#define DES_IVLEN 8
#define DES_KEYLEN 8
#define DES3_IVLEN 8
#define DES3_KEYLEN 24
extern volatile unsigned char __MBAR[];
static void Des_Cbc(Des* des, byte* out, const byte* in, word32 sz, word32 desc)
static int TimeCount = 0 ;
static void Des_Cbc(byte* out, const byte* in, word32 sz,
byte *key, byte *iv, word32 desc)
{
static volatile SECdescriptorType descriptor = { NULL } ;
int ret ; int stat1,stat2 ;
int i ; int size ;
volatile int v ;
LockMutex(&Mutex_DesSEC) ;
secDesc->length1 = 0x0;
secDesc->pointer1 = NULL;
if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){
secDesc->length2 = DES_IVLEN ;
secDesc->length3 = DES_KEYLEN ;
} else {
secDesc->length2 = DES3_IVLEN ;
secDesc->length3 = DES3_KEYLEN ;
}
secDesc->pointer2 = secIV ;
secDesc->pointer3 = secKey;
secDesc->pointer4 = desBuffIn ;
secDesc->pointer5 = desBuffOut ;
secDesc->length6 = 0;
secDesc->pointer6 = NULL;
secDesc->length7 = 0x0;
secDesc->pointer7 = NULL;
secDesc->nextDescriptorPtr = NULL ;
while(sz) {
XMEMCPY(secIV, iv, secDesc->length2) ;
if((sz%DES_BUFFER_SIZE) == sz) {
size = sz ;
sz = 0 ;
@ -307,38 +347,21 @@ static void Des_Cbc(Des* des, byte* out, const byte* in, word32 sz, word32 desc)
sz -= DES_BUFFER_SIZE ;
}
descriptor.header = desc ;
/*
escriptor.length1 = 0x0;
descriptor.pointer1 = NULL;
*/
descriptor.length2 = des->ivlen ;
descriptor.pointer2 = (byte *)des->iv ;
descriptor.length3 = des->keylen ;
descriptor.pointer3 = (byte *)des->key;
descriptor.length4 = size;
descriptor.pointer4 = (byte *)in ;
descriptor.length5 = size;
descriptor.pointer5 = DesBuffer ;
/*
descriptor.length6 = 0;
descriptor.pointer6 = NULL;
descriptor.length7 = 0x0;
descriptor.pointer7 = NULL;
descriptor.nextDescriptorPtr = NULL ;
*/
XMEMCPY(desBuffIn, in, size) ;
XMEMCPY(secKey, key, secDesc->length3) ;
/* Initialize SEC and wait for encryption to complete */
MCF_SEC_CCCR0 = 0x0000001A; //enable channel done notification
secDesc->header = desc ;
secDesc->length4 = size;
secDesc->length5 = size;
/* Point SEC to the location of the descriptor */
MCF_SEC_FR0 = (uint32)&descriptor;
MCF_SEC_FR0 = (uint32)secDesc;
/* Initialize SEC and wait for encryption to complete */
MCF_SEC_CCCR0 = 0x0000001a;
/* poll SISR to determine when channel is complete */
while (!(MCF_SEC_SISRL) && !(MCF_SEC_SISRH))
;
for(v=0; v<500; v++) ;
v=0 ;
while((secDesc->header>> 24) != 0xff) {
if(v++ > 1000)break ;
}
ret = MCF_SEC_SISRH;
stat1 = MCF_SEC_DSR ;
@ -346,86 +369,120 @@ static void Des_Cbc(Des* des, byte* out, const byte* in, word32 sz, word32 desc)
if(ret & 0xe0000000)
db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2) ;
XMEMCPY(out, DesBuffer, size) ;
XMEMCPY(out, desBuffOut, size) ;
if((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {
XMEMCPY((void*)des->iv, (void*)&(out[size-DES_IVLEN]), DES_IVLEN) ;
XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2) ;
} else {
XMEMCPY((void*)des->iv, (void*)&(in[size-DES_IVLEN]), DES_IVLEN) ;
XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2) ;
}
in += size ;
out += size ;
}
UnLockMutex(&Mutex_DesSEC) ;
if((TimeCount++ % 6)==0)
tx_thread_sleep(1) ; /* DELAY */
}
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
{
Des_Cbc(des, out, in, sz, SEC_DESC_DES_CBC_ENCRYPT) ;
Des_Cbc(out, in, sz, des->key, des->reg, SEC_DESC_DES_CBC_ENCRYPT) ;
}
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
{
Des_Cbc(des, out, in, sz, SEC_DESC_DES_CBC_DECRYPT) ;
Des_Cbc(out, in, sz, des->key, des->reg, SEC_DESC_DES_CBC_DECRYPT) ;
}
int Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
void Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
{
Des_Cbc((Des *)des3, out, in, sz, SEC_DESC_DES3_CBC_ENCRYPT) ;
return 0;
}
int Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
{
Des_Cbc((Des *)des3, out, in, sz, SEC_DESC_DES3_CBC_DECRYPT) ;
return 0;
Des_Cbc(out, in, sz, des3->key, des3->reg, SEC_DESC_DES3_CBC_ENCRYPT) ;
}
int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
void Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
{
int i ; int status ;
if(DesBuffer == NULL) {
status = tx_byte_allocate(&mp_ncached,(void *)&DesBuffer,DES_BUFFER_SIZE,TX_NO_WAIT);
Des_Cbc(out, in, sz, des3->key, des3->reg, SEC_DESC_DES3_CBC_DECRYPT) ;
}
static void setParity(byte *buf, int len)
{
int i, j ;
byte v ;
int bits ;
for(i=0; i<len; i++)
{
v = buf[i] >> 1 ;
buf[i] = v << 1 ;
bits = 0 ;
for(j=0; j<7; j++)
{
bits += (v&0x1) ;
v = v >> 1 ;
}
buf[i] |= (1 - (bits&0x1)) ;
}
XMEMCPY(des->key, key, DES_KEYLEN);
des->keylen = DES_KEYLEN ;
des->ivlen = 0 ;
}
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
{
int i ; int s1, s2, s3, s4, s5 ;
if(desBuffIn == NULL) {
#if defined (HAVE_THREADX)
s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
sizeof(SECdescriptorType), TX_NO_WAIT);
s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn, DES_BUFFER_SIZE, TX_NO_WAIT);
s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
/* Don't know des or des3 to be used. Allocate larger buffers */
s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey, DES3_KEYLEN,TX_NO_WAIT);
s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT);
#else
#error "Allocate non-Cache buffers"
#endif
InitMutex(&Mutex_DesSEC) ;
}
XMEMCPY(des->key, key, DES_KEYLEN);
if (iv) {
XMEMCPY(des->iv, iv, DES_IVLEN);
des->ivlen = DES_IVLEN ;
XMEMCPY(des->reg, iv, DES_IVLEN);
} else {
for(i=0; i<DES_IVLEN; i++)
des->iv[i] = 0x0 ;
XMEMSET(des->reg, 0x0, DES_IVLEN) ;
}
return 0;
}
int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
void Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
{
int i ; int status ;
int i ; int s1, s2, s3, s4, s5 ;
if(DesBuffer == NULL) {
status = tx_byte_allocate(&mp_ncached,(void *)&DesBuffer,DES_BUFFER_SIZE,TX_NO_WAIT);
if(desBuffIn == NULL) {
s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
sizeof(SECdescriptorType), TX_NO_WAIT);
s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn, DES_BUFFER_SIZE, TX_NO_WAIT);
s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey, DES3_KEYLEN,TX_NO_WAIT);
s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT);
InitMutex(&Mutex_DesSEC) ;
}
XMEMCPY(des3->key, key, DES3_KEYLEN);
des3->keylen = DES3_KEYLEN ;
des3->ivlen = 0 ;
XMEMCPY(des3->key[0], key, DES3_KEYLEN);
setParity((byte *)des3->key[0], DES3_KEYLEN) ;
if (iv) {
XMEMCPY(des3->iv, iv, DES3_IVLEN);
des3->ivlen = DES3_IVLEN ;
XMEMCPY(des3->reg, iv, DES3_IVLEN);
} else {
for(i=0; i<DES_IVLEN; i++)
des3->iv[i] = 0x0 ;
XMEMSET(des3->reg, 0x0, DES3_IVLEN) ;
}
return 0;
}
#elif defined FREESCALE_MMCAU

View File

@ -40,17 +40,11 @@ enum {
DES3_ENC_TYPE = 3, /* cipher unique type */
DES_BLOCK_SIZE = 8,
DES_KS_SIZE = 32,
DES_KEYLEN = 8 ,
DES_ENCRYPTION = 0,
DES_DECRYPTION = 1
};
#define DES_IVLEN 8
#define DES_KEYLEN 8
#define DES3_IVLEN 8
#define DES3_KEYLEN 24
#ifdef STM32F2_CRYPTO
enum {
DES_CBC = 0,
@ -63,22 +57,12 @@ enum {
typedef struct Des {
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
#ifdef HAVE_COLDFIRE_SEC
byte keylen ; /* for Coldfire SEC */
byte ivlen ; /* for Coldfire SEC */
byte iv[DES3_IVLEN]; /* for Coldfire SEC */
#endif
word32 key[DES_KS_SIZE];
} Des;
/* DES3 encryption and decryption */
typedef struct Des3 {
#ifdef HAVE_COLDFIRE_SEC
byte keylen ; /* for Coldfire SEC */
byte ivlen ; /* for Coldfire SEC */
byte iv[DES3_IVLEN]; /* for Coldfire SEC */
#endif
word32 key[3][DES_KS_SIZE];
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */