re-factor modes to use internal ECB implementation

This commit is contained in:
Steffen Jaeckel 2019-11-15 16:29:40 +01:00
parent 23803626b6
commit 661109f660
45 changed files with 241 additions and 284 deletions

View file

@ -274,18 +274,14 @@ typedef struct {
#ifdef LTC_CFB_MODE
/** A block cipher CFB structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
/** The pad used to encrypt/decrypt */
pad[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The width of the mode: 1, 8, 64, or 128 */
width,
int width,
/** The padding offset */
padlen;
} symmetric_CFB;
@ -294,30 +290,23 @@ typedef struct {
#ifdef LTC_OFB_MODE
/** A block cipher OFB structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
int padlen;
} symmetric_OFB;
#endif
#ifdef LTC_CBC_MODE
/** A block cipher CBC structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen;
} symmetric_CBC;
#endif
@ -325,19 +314,15 @@ typedef struct {
#ifdef LTC_CTR_MODE
/** A block cipher CTR structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The counter */
unsigned char ctr[MAXBLOCKSIZE];
/** The pad used to encrypt/decrypt */
unsigned char pad[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen,
int padlen,
/** The mode (endianess) of the CTR, 0==little, 1==big */
mode,
/** counter width */
@ -349,18 +334,14 @@ typedef struct {
#ifdef LTC_LRW_MODE
/** A LRW structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The current IV */
unsigned char IV[16],
/** the tweak key */
tweak[16],
/** The current pad, it's the product of the first 15 bytes against the tweak key */
pad[16];
/** The scheduled symmetric key */
symmetric_key key;
#ifdef LTC_LRW_TABLES
/** The pre-computed multiplication table */
unsigned char PC[16][256][16];
@ -374,17 +355,13 @@ typedef struct {
#ifdef LTC_F8_MODE
/** A block cipher F8 structure */
typedef struct {
/** The ECB context of the cipher */
symmetric_ECB ecb;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
MIV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
int padlen;
/** Current block count */
ulong32 blockcnt;
} symmetric_F8;
@ -451,7 +428,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, const symmetric_key *skey);
/** Accelerated ECB decryption
@param pt Plaintext
@ -460,7 +437,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, const symmetric_key *skey);
/** Accelerated CBC encryption
@param pt Plaintext
@ -470,7 +447,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const symmetric_key *skey);
/** Accelerated CBC decryption
@param pt Plaintext
@ -480,7 +457,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const symmetric_key *skey);
/** Accelerated CTR encryption
@param pt Plaintext
@ -491,7 +468,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, const symmetric_key *skey);
/** Accelerated LRW
@param pt Plaintext
@ -502,7 +479,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, const symmetric_key *skey);
/** Accelerated LRW
@param ct Ciphertext
@ -513,7 +490,7 @@ extern struct ltc_cipher_descriptor {
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, const symmetric_key *skey);
/** Accelerated CCM packet (one-shot)
@param key The secret key to use
@ -533,7 +510,7 @@ extern struct ltc_cipher_descriptor {
*/
int (*accel_ccm_memory)(
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
@ -923,8 +900,8 @@ extern const struct ltc_cipher_descriptor tea_desc;
#ifdef LTC_ECB_MODE
int ecb_start(int cipher, const unsigned char *key,
int keylen, int num_rounds, symmetric_ECB *ecb);
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb);
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb);
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, const symmetric_ECB *ecb);
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, const symmetric_ECB *ecb);
int ecb_done(symmetric_ECB *ecb);
#endif
@ -1016,7 +993,7 @@ int f8_test_mode(void);
#ifdef LTC_XTS_MODE
typedef struct {
symmetric_key key1, key2;
symmetric_ECB key1, key2;
int cipher;
} symmetric_xts;

View file

@ -710,6 +710,14 @@
#error LTC_NO_MATH defined, but also a math descriptor
#endif
#if !defined(LTC_ECB_MODE)
#if defined(LTC_CFB_MODE) || defined(LTC_OFB_MODE) || defined(LTC_CBC_MODE) || defined(LTC_CTR_MODE) || \
defined(LTC_F8_MODE) || defined(LTC_LRW_MODE) || defined(LTC_XTS_MODE) )
#error LTC_ECB_MODE not defined, but all other modes depend on it
#endif
#endif
/* THREAD management */
#ifdef LTC_PTHREAD

View file

@ -122,6 +122,10 @@ typedef struct {
/* tomcrypt_cipher.h */
int ecb_encrypt_block(const unsigned char *pt, unsigned char *ct, const symmetric_ECB *ecb);
int ecb_decrypt_block(const unsigned char *ct, unsigned char *pt, const symmetric_ECB *ecb);
void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
int blowfish_expand(const unsigned char *key, int keylen,
const unsigned char *data, int datalen,

View file

@ -197,7 +197,7 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen,
goto error_out;
}
if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.blocklen)) != CRYPT_OK) {
if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.ecb.blocklen)) != CRYPT_OK) {
goto error_out;
}
#else

View file

@ -32,51 +32,51 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(cbc->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) {
if (cbc->ecb.blocklen < 1 || cbc->ecb.blocklen > (int)sizeof(cbc->IV) || cbc->ecb.blocklen > (int)sizeof(tmp)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
if (len % cbc->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
if (cbc->ecb.blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
if (cipher_descriptor[cbc->ecb.cipher].accel_cbc_decrypt != NULL) {
return cipher_descriptor[cbc->ecb.cipher].accel_cbc_decrypt(ct, pt, len / cbc->ecb.blocklen, cbc->IV, &cbc->ecb.key);
}
while (len) {
/* decrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
if ((err = ecb_decrypt_block(ct, tmp, &cbc->ecb)) != CRYPT_OK) {
return err;
}
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy;
}
#else
for (x = 0; x < cbc->blocklen; x++) {
for (x = 0; x < cbc->ecb.blocklen; x++) {
tmpy = tmp[x] ^ cbc->IV[x];
cbc->IV[x] = ct[x];
pt[x] = tmpy;
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
ct += cbc->ecb.blocklen;
pt += cbc->ecb.blocklen;
len -= cbc->ecb.blocklen;
}
return CRYPT_OK;
}

View file

@ -15,14 +15,9 @@
*/
int cbc_done(symmetric_CBC *cbc)
{
int err;
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[cbc->cipher].done(&cbc->key);
return CRYPT_OK;
return ecb_done(&cbc->ecb);
}

View file

@ -26,58 +26,58 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(cbc->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
if (cbc->ecb.blocklen < 1 || cbc->ecb.blocklen > (int)sizeof(cbc->IV)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
if (len % cbc->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
if (cbc->ecb.blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
if (cipher_descriptor[cbc->ecb.cipher].accel_cbc_encrypt != NULL) {
return cipher_descriptor[cbc->ecb.cipher].accel_cbc_encrypt(pt, ct, len / cbc->ecb.blocklen, cbc->IV, &cbc->ecb.key);
}
while (len) {
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
for (x = 0; x < cbc->ecb.blocklen; x++) {
cbc->IV[x] ^= pt[x];
}
#endif
/* encrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(cbc->IV, ct, &cbc->ecb)) != CRYPT_OK) {
return err;
}
/* store IV [ciphertext] for a future block */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
for (x = 0; x < cbc->ecb.blocklen; x++) {
cbc->IV[x] = ct[x];
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
ct += cbc->ecb.blocklen;
pt += cbc->ecb.blocklen;
len -= cbc->ecb.blocklen;
}
return CRYPT_OK;
}

View file

@ -21,12 +21,12 @@ int cbc_getiv(unsigned char *IV, unsigned long *len, const symmetric_CBC *cbc)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(cbc != NULL);
if ((unsigned long)cbc->blocklen > *len) {
*len = cbc->blocklen;
if ((unsigned long)cbc->ecb.blocklen > *len) {
*len = cbc->ecb.blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, cbc->IV, cbc->blocklen);
*len = cbc->blocklen;
XMEMCPY(IV, cbc->IV, cbc->ecb.blocklen);
*len = cbc->ecb.blocklen;
return CRYPT_OK;
}

View file

@ -21,7 +21,7 @@ int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(cbc != NULL);
if (len != (unsigned long)cbc->blocklen) {
if (len != (unsigned long)cbc->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
XMEMCPY(cbc->IV, IV, len);

View file

@ -28,20 +28,13 @@ int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(cbc != NULL);
/* bad param? */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* setup cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key, keylen, num_rounds, &cbc->ecb)) != CRYPT_OK) {
return err;
}
/* copy IV */
cbc->blocklen = cipher_descriptor[cipher].block_length;
cbc->cipher = cipher;
for (x = 0; x < cbc->blocklen; x++) {
for (x = 0; x < cbc->ecb.blocklen; x++) {
cbc->IV[x] = IV[x];
}
return CRYPT_OK;

View file

@ -57,12 +57,12 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
return CRYPT_OVERFLOW;
}
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
if (cfb->ecb.blocklen < 0 || cfb->ecb.blocklen > (int)sizeof(cfb->IV) ||
cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
return CRYPT_INVALID_ARG;
}
@ -70,8 +70,8 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
bits_per_round = cfb->width == 1 ? 1 : 8;
while (bitlen > 0) {
if (cfb->padlen == cfb->blocklen) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
if (cfb->padlen == cfb->ecb.blocklen) {
if ((err = ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
@ -85,22 +85,22 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
ct_ <<= 1;
pt_ <<= 1;
}
if (cfb->blocklen == 16)
if (cfb->ecb.blocklen == 16)
s_shift1left_128(cfb->pad, ct_ >> 7);
else
s_shift1left_64(cfb->pad, ct_ >> 7);
pt_ |= ((ct_ ^ cfb->IV[0]) >> 7) & 0x01u;
cfb->padlen = cfb->blocklen;
cfb->padlen = cfb->ecb.blocklen;
if (cur_bit % 8 == 0) {
*pt++ = pt_;
cur_bit = 0;
}
break;
case 8:
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1);
cfb->pad[cfb->blocklen - 1] = *ct;
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->ecb.blocklen - 1);
cfb->pad[cfb->ecb.blocklen - 1] = *ct;
*pt++ = *ct++ ^ cfb->IV[0];
cfb->padlen = cfb->blocklen;
cfb->padlen = cfb->ecb.blocklen;
break;
case 64:
case 128:

View file

@ -15,14 +15,9 @@
*/
int cfb_done(symmetric_CFB *cfb)
{
int err;
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[cfb->cipher].done(&cfb->key);
return CRYPT_OK;
return ecb_done(&cfb->ecb);
}

View file

@ -57,12 +57,12 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
return CRYPT_OVERFLOW;
}
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
if (cfb->ecb.blocklen < 0 || cfb->ecb.blocklen > (int)sizeof(cfb->IV) ||
cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
return CRYPT_INVALID_ARG;
}
@ -70,8 +70,8 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
bits_per_round = cfb->width == 1 ? 1 : 8;
while (bitlen > 0) {
if (cfb->padlen == cfb->blocklen) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
if (cfb->padlen == cfb->ecb.blocklen) {
if ((err = ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
@ -86,22 +86,22 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
ct_ <<= 1;
}
ct_ |= ((pt_ ^ cfb->IV[0]) >> 7) & 0x01u;
if (cfb->blocklen == 16)
if (cfb->ecb.blocklen == 16)
s_shift1left_128(cfb->pad, ct_);
else
s_shift1left_64(cfb->pad, ct_);
cfb->padlen = cfb->blocklen;
cfb->padlen = cfb->ecb.blocklen;
if (cur_bit % 8 == 0) {
*ct++ = ct_;
cur_bit = 0;
}
break;
case 8:
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1);
cfb->pad[cfb->blocklen - 1] = (*ct = *pt ^ cfb->IV[0]);
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->ecb.blocklen - 1);
cfb->pad[cfb->ecb.blocklen - 1] = (*ct = *pt ^ cfb->IV[0]);
++pt;
++ct;
cfb->padlen = cfb->blocklen;
cfb->padlen = cfb->ecb.blocklen;
break;
case 64:
case 128:

View file

@ -21,12 +21,12 @@ int cfb_getiv(unsigned char *IV, unsigned long *len, const symmetric_CFB *cfb)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(cfb != NULL);
if ((unsigned long)cfb->blocklen > *len) {
*len = cfb->blocklen;
if ((unsigned long)cfb->ecb.blocklen > *len) {
*len = cfb->ecb.blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, cfb->pad, cfb->blocklen);
*len = cfb->blocklen;
XMEMCPY(IV, cfb->pad, cfb->ecb.blocklen);
*len = cfb->ecb.blocklen;
return CRYPT_OK;
}

View file

@ -23,18 +23,18 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)cfb->blocklen) {
if (len != (unsigned long)cfb->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
cfb->padlen = 0;
XMEMCPY(cfb->pad, IV, len);
return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
return ecb_encrypt_block(IV, cfb->IV, &cfb->ecb);
}
#endif

View file

@ -52,23 +52,19 @@ int cfb_start_ex(int cipher, const unsigned char *IV, const unsigned char *key,
return CRYPT_INVALID_ARG;
}
/* copy data */
cfb->cipher = cipher;
cfb->width = width;
cfb->blocklen = cipher_descriptor[cipher].block_length;
for (x = 0; x < cfb->blocklen; x++) {
cfb->pad[x] = IV[x];
}
/* init the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key, keylen, num_rounds, &cfb->ecb)) != CRYPT_OK) {
return err;
}
/* copy data */
for (x = 0; x < cfb->ecb.blocklen; x++) {
cfb->pad[x] = IV[x];
}
/* encrypt the IV */
cfb->padlen = 0;
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
return ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb);
}
/**

View file

@ -15,14 +15,9 @@
*/
int ctr_done(symmetric_CTR *ctr)
{
int err;
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ctr->cipher].done(&ctr->key);
return CRYPT_OK;
return ecb_done(&ctr->ecb);
}

View file

@ -24,7 +24,7 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo
while (len) {
/* is the pad empty? */
if (ctr->padlen == ctr->blocklen) {
if (ctr->padlen == ctr->ecb.blocklen) {
/* increment counter */
if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
/* little-endian */
@ -36,7 +36,7 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo
}
} else {
/* big-endian */
for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
for (x = ctr->ecb.blocklen-1; x >= ctr->ctrlen; x--) {
ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
if (ctr->ctr[x] != (unsigned char)0) {
break;
@ -45,21 +45,21 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo
}
/* encrypt it */
if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(ctr->ctr, ctr->pad, &ctr->ecb)) != CRYPT_OK) {
return err;
}
ctr->padlen = 0;
}
#ifdef LTC_FAST
if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->ecb.blocklen)) {
for (x = 0; x < ctr->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
}
pt += ctr->blocklen;
ct += ctr->blocklen;
len -= ctr->blocklen;
ctr->padlen = ctr->blocklen;
pt += ctr->ecb.blocklen;
ct += ctr->ecb.blocklen;
len -= ctr->ecb.blocklen;
ctr->padlen = ctr->ecb.blocklen;
continue;
}
#endif
@ -85,26 +85,26 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(ctr->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
if ((ctr->ecb.blocklen < 1) || (ctr->ecb.blocklen > (int)sizeof(ctr->ctr)) ||
(ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
if (ctr->ecb.blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
if (ctr->padlen < ctr->blocklen) {
fr = ctr->blocklen - ctr->padlen;
if ((cipher_descriptor[ctr->ecb.cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->ecb.blocklen)) {
if (ctr->padlen < ctr->ecb.blocklen) {
fr = ctr->ecb.blocklen - ctr->padlen;
if ((err = s_ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
return err;
}
@ -113,13 +113,13 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
len -= fr;
}
if (len >= (unsigned long)ctr->blocklen) {
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
if (len >= (unsigned long)ctr->ecb.blocklen) {
if ((err = cipher_descriptor[ctr->ecb.cipher].accel_ctr_encrypt(pt, ct, len/ctr->ecb.blocklen, ctr->ctr, ctr->mode, &ctr->ecb.key)) != CRYPT_OK) {
return err;
}
pt += (len / ctr->blocklen) * ctr->blocklen;
ct += (len / ctr->blocklen) * ctr->blocklen;
len %= ctr->blocklen;
pt += (len / ctr->ecb.blocklen) * ctr->ecb.blocklen;
ct += (len / ctr->ecb.blocklen) * ctr->ecb.blocklen;
len %= ctr->ecb.blocklen;
}
}

View file

@ -21,12 +21,12 @@ int ctr_getiv(unsigned char *IV, unsigned long *len, const symmetric_CTR *ctr)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(ctr != NULL);
if ((unsigned long)ctr->blocklen > *len) {
*len = ctr->blocklen;
if ((unsigned long)ctr->ecb.blocklen > *len) {
*len = ctr->ecb.blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, ctr->ctr, ctr->blocklen);
*len = ctr->blocklen;
XMEMCPY(IV, ctr->ctr, ctr->ecb.blocklen);
*len = ctr->ecb.blocklen;
return CRYPT_OK;
}

View file

@ -24,11 +24,11 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
LTC_ARGCHK(ctr != NULL);
/* bad param? */
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(ctr->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ctr->blocklen) {
if (len != (unsigned long)ctr->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
@ -37,7 +37,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
/* force next block */
ctr->padlen = 0;
return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
return ecb_encrypt_block(IV, ctr->pad, &ctr->ecb);
}
#endif

View file

@ -49,16 +49,14 @@ int ctr_start( int cipher,
}
/* setup cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key, keylen, num_rounds, &ctr->ecb)) != CRYPT_OK) {
return err;
}
/* copy ctr */
ctr->blocklen = cipher_descriptor[cipher].block_length;
ctr->cipher = cipher;
ctr->padlen = 0;
ctr->mode = ctr_mode & 0x1000;
for (x = 0; x < ctr->blocklen; x++) {
for (x = 0; x < ctr->ecb.blocklen; x++) {
ctr->ctr[x] = IV[x];
}
@ -74,7 +72,7 @@ int ctr_start( int cipher,
}
} else {
/* big-endian */
for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
for (x = ctr->ecb.blocklen-1; x >= ctr->ctrlen; x--) {
ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
if (ctr->ctr[x] != (unsigned char)0) {
break;
@ -83,7 +81,7 @@ int ctr_start( int cipher,
}
}
return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
return ecb_encrypt_block(ctr->ctr, ctr->pad, &ctr->ecb);
}
#endif

View file

@ -8,6 +8,14 @@
*/
#ifdef LTC_ECB_MODE
int ecb_decrypt_block(const unsigned char *ct, unsigned char *pt, const symmetric_ECB *ecb)
{
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, 1, &ecb->key);
}
return cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
}
/**
ECB decrypt
@ -17,7 +25,7 @@
@param ecb ECB state
@return CRYPT_OK if successful
*/
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb)
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, const symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(pt != NULL);

View file

@ -8,6 +8,14 @@
*/
#ifdef LTC_ECB_MODE
int ecb_encrypt_block(const unsigned char *pt, unsigned char *ct, const symmetric_ECB *ecb)
{
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, 1, &ecb->key);
}
return cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
}
/**
ECB encrypt
@ -17,7 +25,7 @@
@param ecb ECB state
@return CRYPT_OK if successful
*/
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb)
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, const symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(pt != NULL);

View file

@ -15,14 +15,9 @@
*/
int f8_done(symmetric_F8 *f8)
{
int err;
LTC_ARGCHK(f8 != NULL);
if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[f8->cipher].done(&f8->key);
return CRYPT_OK;
return ecb_done(&f8->ecb);
}

View file

@ -24,12 +24,12 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(f8 != NULL);
if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(f8->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) ||
if (f8->ecb.blocklen < 0 || f8->ecb.blocklen > (int)sizeof(f8->IV) ||
f8->padlen < 0 || f8->padlen > (int)sizeof(f8->IV)) {
return CRYPT_INVALID_ARG;
}
@ -37,14 +37,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy
zeromem(buf, sizeof(buf));
/* make sure the pad is empty */
if (f8->padlen == f8->blocklen) {
if (f8->padlen == f8->ecb.blocklen) {
/* xor of IV, MIV and blockcnt == what goes into cipher */
STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4)));
++(f8->blockcnt);
for (x = 0; x < f8->blocklen; x++) {
for (x = 0; x < f8->ecb.blocklen; x++) {
f8->IV[x] ^= f8->MIV[x] ^ buf[x];
}
if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) {
return err;
}
f8->padlen = 0;
@ -52,14 +52,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy
#ifdef LTC_FAST
if (f8->padlen == 0) {
while (len >= (unsigned long)f8->blocklen) {
STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
while (len >= (unsigned long)f8->ecb.blocklen) {
STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4)));
++(f8->blockcnt);
for (x = 0; x < f8->blocklen; x += sizeof(LTC_FAST_TYPE)) {
for (x = 0; x < f8->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&ct[x])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x]));
*(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&f8->MIV[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&buf[x]));
}
if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) {
return err;
}
len -= x;
@ -70,14 +70,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy
#endif
while (len > 0) {
if (f8->padlen == f8->blocklen) {
if (f8->padlen == f8->ecb.blocklen) {
/* xor of IV, MIV and blockcnt == what goes into cipher */
STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4)));
++(f8->blockcnt);
for (x = 0; x < f8->blocklen; x++) {
for (x = 0; x < f8->ecb.blocklen; x++) {
f8->IV[x] ^= f8->MIV[x] ^ buf[x];
}
if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) {
return err;
}
f8->padlen = 0;

View file

@ -21,12 +21,12 @@ int f8_getiv(unsigned char *IV, unsigned long *len, const symmetric_F8 *f8)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(f8 != NULL);
if ((unsigned long)f8->blocklen > *len) {
*len = f8->blocklen;
if ((unsigned long)f8->ecb.blocklen > *len) {
*len = f8->ecb.blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, f8->IV, f8->blocklen);
*len = f8->blocklen;
XMEMCPY(IV, f8->IV, f8->ecb.blocklen);
*len = f8->ecb.blocklen;
return CRYPT_OK;
}

View file

@ -23,17 +23,17 @@ int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(f8 != NULL);
if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(f8->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)f8->blocklen) {
if (len != (unsigned long)f8->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
f8->padlen = 0;
return cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->IV, &f8->key);
return ecb_encrypt_block(IV, f8->IV, &f8->ecb);
}
#endif

View file

@ -47,9 +47,7 @@ int f8_start( int cipher, const unsigned char *IV,
/* copy details */
f8->blockcnt = 0;
f8->cipher = cipher;
f8->blocklen = cipher_descriptor[cipher].block_length;
f8->padlen = f8->blocklen;
f8->padlen = cipher_descriptor[cipher].block_length;
/* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */
zeromem(tkey, sizeof(tkey));
@ -64,23 +62,22 @@ int f8_start( int cipher, const unsigned char *IV,
}
/* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */
if ((err = cipher_descriptor[cipher].setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) {
if ((err = ecb_start(cipher, tkey, keylen, num_rounds, &f8->ecb)) != CRYPT_OK) {
return err;
}
/* encrypt IV */
if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) {
cipher_descriptor[f8->cipher].done(&f8->key);
return err;
if ((err = ecb_encrypt_block(IV, f8->MIV, &f8->ecb)) != CRYPT_OK) {
return ecb_done(&f8->ecb);
}
zeromem(tkey, sizeof(tkey));
zeromem(f8->IV, sizeof(f8->IV));
/* terminate this cipher */
cipher_descriptor[f8->cipher].done(&f8->key);
ecb_done(&f8->ecb);
/* init the cipher */
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &f8->key);
return ecb_start(cipher, key, keylen, num_rounds, &f8->ecb);
}
#endif

View file

@ -24,12 +24,12 @@ int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(lrw != NULL);
if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) {
return cipher_descriptor[lrw->cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->key);
if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt != NULL) {
return cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->ecb.key);
}
return lrw_process(ct, pt, len, LRW_DECRYPT, lrw);

View file

@ -16,16 +16,9 @@
*/
int lrw_done(symmetric_LRW *lrw)
{
int err;
LTC_ARGCHK(lrw != NULL);
if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[lrw->cipher].done(&lrw->key);
return CRYPT_OK;
return ecb_done(&lrw->ecb);
}
#endif

View file

@ -24,12 +24,12 @@ int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(lrw != NULL);
if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL) {
return cipher_descriptor[lrw->cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->key);
if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt != NULL) {
return cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->ecb.key);
}
return lrw_process(pt, ct, len, LRW_ENCRYPT, lrw);

View file

@ -77,11 +77,11 @@ int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, i
/* send through cipher */
if (mode == LRW_ENCRYPT) {
if ((err = cipher_descriptor[lrw->cipher].ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(ct, ct, &lrw->ecb)) != CRYPT_OK) {
return err;
}
} else {
if ((err = cipher_descriptor[lrw->cipher].ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
if ((err = ecb_decrypt_block(ct, ct, &lrw->ecb)) != CRYPT_OK) {
return err;
}
}

View file

@ -30,7 +30,7 @@ int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw)
return CRYPT_INVALID_ARG;
}
if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) {
return err;
}
@ -38,7 +38,7 @@ int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw)
XMEMCPY(lrw->IV, IV, 16);
/* check if we have to actually do work */
if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) {
if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt != NULL) {
/* we have accelerators, let's bail since they don't use lrw->pad anyways */
return CRYPT_OK;
}

View file

@ -53,10 +53,10 @@ int lrw_start( int cipher,
}
/* schedule key */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &lrw->key)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key, keylen, num_rounds, &lrw->ecb)) != CRYPT_OK) {
return err;
}
lrw->cipher = cipher;
lrw->ecb.cipher = cipher;
/* copy the IV and tweak */
XMEMCPY(lrw->tweak, tweak, 16);

View file

@ -15,14 +15,9 @@
*/
int ofb_done(symmetric_OFB *ofb)
{
int err;
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ofb->cipher].done(&ofb->key);
return CRYPT_OK;
return ecb_done(&ofb->ecb);
}

View file

@ -23,19 +23,19 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(ofb->ecb.cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) ||
if (ofb->ecb.blocklen < 0 || ofb->ecb.blocklen > (int)sizeof(ofb->IV) ||
ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) {
return CRYPT_INVALID_ARG;
}
while (len-- > 0) {
if (ofb->padlen == ofb->blocklen) {
if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
if (ofb->padlen == ofb->ecb.blocklen) {
if ((err = ecb_encrypt_block(ofb->IV, ofb->IV, &ofb->ecb)) != CRYPT_OK) {
return err;
}
ofb->padlen = 0;

View file

@ -21,12 +21,12 @@ int ofb_getiv(unsigned char *IV, unsigned long *len, const symmetric_OFB *ofb)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(ofb != NULL);
if ((unsigned long)ofb->blocklen > *len) {
*len = ofb->blocklen;
if ((unsigned long)ofb->ecb.blocklen > *len) {
*len = ofb->ecb.blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, ofb->IV, ofb->blocklen);
*len = ofb->blocklen;
XMEMCPY(IV, ofb->IV, ofb->ecb.blocklen);
*len = ofb->ecb.blocklen;
return CRYPT_OK;
}

View file

@ -23,17 +23,17 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
if ((err = cipher_is_valid(ofb->ecb.cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ofb->blocklen) {
if (len != (unsigned long)ofb->ecb.blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
ofb->padlen = 0;
return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
return ecb_encrypt_block(IV, ofb->IV, &ofb->ecb);
}
#endif

View file

@ -33,16 +33,18 @@ int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
return err;
}
/* init the cipher */
if ((err = ecb_start(cipher, key, keylen, num_rounds, &ofb->ecb)) != CRYPT_OK) {
return err;
}
ofb->padlen = cipher_descriptor[cipher].block_length;
/* copy details */
ofb->cipher = cipher;
ofb->blocklen = cipher_descriptor[cipher].block_length;
for (x = 0; x < ofb->blocklen; x++) {
for (x = 0; x < ofb->ecb.blocklen; x++) {
ofb->IV[x] = IV[x];
}
/* init the cipher */
ofb->padlen = ofb->blocklen;
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key);
return CRYPT_OK;
}
#endif

View file

@ -24,7 +24,7 @@ static int s_tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned ch
}
#endif
err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1);
err = ecb_decrypt_block(P, P, &xts->key1);
#ifdef LTC_FAST
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
@ -86,7 +86,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt,
if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) {
/* use accelerated decryption for whole blocks */
if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2)) !=
if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1.key, &xts->key2.key)) !=
CRYPT_OK) {
return err;
}
@ -97,7 +97,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt,
XMEMCPY(T, tweak, sizeof(T));
} else {
/* encrypt the tweak */
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(tweak, T, &xts->key2)) != CRYPT_OK) {
return err;
}
@ -136,7 +136,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt,
}
/* Decrypt the tweak back */
if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
if ((err = ecb_decrypt_block(T, tweak, &xts->key2)) != CRYPT_OK) {
return err;
}

View file

@ -14,8 +14,8 @@
void xts_done(symmetric_xts *xts)
{
LTC_ARGCHKVD(xts != NULL);
cipher_descriptor[xts->cipher].done(&xts->key1);
cipher_descriptor[xts->cipher].done(&xts->key2);
ecb_done(&xts->key1);
ecb_done(&xts->key2);
}
#endif

View file

@ -24,7 +24,7 @@ static int s_tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char
}
#endif
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(C, C, &xts->key1)) != CRYPT_OK) {
return err;
}
@ -88,7 +88,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct,
if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) {
/* use accelerated encryption for whole blocks */
if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1, &xts->key2)) !=
if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1.key, &xts->key2.key)) !=
CRYPT_OK) {
return err;
}
@ -100,7 +100,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct,
} else {
/* encrypt the tweak */
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {
if ((err = ecb_encrypt_block(tweak, T, &xts->key2)) != CRYPT_OK) {
return err;
}
@ -137,7 +137,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct,
}
/* Decrypt the tweak back */
if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
if ((err = ecb_decrypt_block(T, tweak, &xts->key2)) != CRYPT_OK) {
return err;
}

View file

@ -37,10 +37,10 @@ int xts_start(int cipher, const unsigned char *key1, const unsigned char *key2,
}
/* schedule the two ciphers */
if ((err = cipher_descriptor[cipher].setup(key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) {
return err;
}
if ((err = cipher_descriptor[cipher].setup(key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) {
if ((err = ecb_start(cipher, key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) {
return err;
}
xts->cipher = cipher;

View file

@ -23,8 +23,10 @@ static int s_xts_test_accel_xts_encrypt(const unsigned char *pt, unsigned char *
orig = cipher_descriptor[xts.cipher].accel_xts_encrypt;
cipher_descriptor[xts.cipher].accel_xts_encrypt = NULL;
XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key));
XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key));
XMEMCPY(&xts.key1.key, skey1, sizeof(xts.key1));
XMEMCPY(&xts.key2.key, skey2, sizeof(xts.key2));
xts.key1.cipher = xts.key2.cipher = xts.cipher;
xts.key1.blocklen = xts.key2.blocklen = cipher_descriptor[xts.cipher].block_length;
ret = xts_encrypt(pt, blocks << 4, ct, tweak, &xts);
cipher_descriptor[xts.cipher].accel_xts_encrypt = orig;
@ -50,8 +52,10 @@ static int s_xts_test_accel_xts_decrypt(const unsigned char *ct, unsigned char *
orig = cipher_descriptor[xts.cipher].accel_xts_decrypt;
cipher_descriptor[xts.cipher].accel_xts_decrypt = NULL;
XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key));
XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key));
XMEMCPY(&xts.key1.key, skey1, sizeof(xts.key1));
XMEMCPY(&xts.key2.key, skey2, sizeof(xts.key2));
xts.key1.cipher = xts.key2.cipher = xts.cipher;
xts.key1.blocklen = xts.key2.blocklen = cipher_descriptor[xts.cipher].block_length;
ret = xts_decrypt(ct, blocks << 4, pt, tweak, &xts);
cipher_descriptor[xts.cipher].accel_xts_decrypt = orig;

View file

@ -131,21 +131,15 @@ int modes_test(void)
/* encode the block */
DO(ret = ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
l = sizeof(iv2);
DO(ret = ofb_getiv(iv2, &l, &ofb));
if (l != 16 || memcmp(iv2, iv, 16)) {
fprintf(stderr, "ofb_getiv failed");
return 1;
}
DO(ofb_getiv(iv2, &l, &ofb));
DO(do_compare_testvector(iv2, l, iv, 16, "ofb_getiv", 0));
DO(ret = ofb_encrypt(pt, ct, 64, &ofb));
/* decode the block */
DO(ret = ofb_setiv(iv2, l, &ofb));
zeromem(tmp, sizeof(tmp));
DO(ret = ofb_decrypt(ct, tmp, 64, &ofb));
if (memcmp(tmp, pt, 64) != 0) {
fprintf(stderr, "OFB failed");
return 1;
}
DO(do_compare_testvector(tmp, 64, pt, 64, "OFB", 0));
#endif
#if defined(LTC_CTR_MODE) && defined(LTC_RIJNDAEL)