#include "des_int.h"
#include "f_tables.h"
int
mit_des_cbc_encrypt(in, out, length, schedule, ivec, enc)
const mit_des_cblock *in;
mit_des_cblock *out;
unsigned long length;
const mit_des_key_schedule schedule;
const mit_des_cblock ivec;
int enc;
{
register unsigned DES_INT32 left, right;
register unsigned DES_INT32 temp;
const unsigned DES_INT32 *kp;
const unsigned char *ip;
unsigned char *op;
kp = (const unsigned DES_INT32 *)schedule;
if (enc) {
ip = ivec;
GET_HALF_BLOCK(left, ip);
GET_HALF_BLOCK(right, ip);
ip = *in;
op = *out;
while (length > 0) {
if (length >= 8) {
left ^= ((*ip++) & FF_UINT32) << 24;
left ^= ((*ip++) & FF_UINT32) << 16;
left ^= ((*ip++) & FF_UINT32) << 8;
left ^= (*ip++) & FF_UINT32;
right ^= ((*ip++) & FF_UINT32) << 24;
right ^= ((*ip++) & FF_UINT32) << 16;
right ^= ((*ip++) & FF_UINT32) << 8;
right ^= (*ip++) & FF_UINT32;
length -= 8;
} else {
ip += (int) length;
switch(length) {
case 7:
right ^= (*(--ip) & FF_UINT32) << 8;
case 6:
right ^= (*(--ip) & FF_UINT32) << 16;
case 5:
right ^= (*(--ip) & FF_UINT32) << 24;
case 4:
left ^= *(--ip) & FF_UINT32;
case 3:
left ^= (*(--ip) & FF_UINT32) << 8;
case 2:
left ^= (*(--ip) & FF_UINT32) << 16;
case 1:
left ^= (*(--ip) & FF_UINT32) << 24;
break;
}
length = 0;
}
DES_DO_ENCRYPT(left, right, temp, kp);
PUT_HALF_BLOCK(left, op);
PUT_HALF_BLOCK(right, op);
}
} else {
unsigned DES_INT32 ocipherl, ocipherr;
unsigned DES_INT32 cipherl, cipherr;
if (length <= 0)
return 0;
ip = ivec;
GET_HALF_BLOCK(ocipherl, ip);
GET_HALF_BLOCK(ocipherr, ip);
ip = *in;
op = *out;
for (;;) {
GET_HALF_BLOCK(left, ip);
GET_HALF_BLOCK(right, ip);
cipherl = left;
cipherr = right;
DES_DO_DECRYPT(left, right, temp, kp);
left ^= ocipherl;
right ^= ocipherr;
if (length > 8) {
length -= 8;
PUT_HALF_BLOCK(left, op);
PUT_HALF_BLOCK(right, op);
ocipherl = cipherl;
ocipherr = cipherr;
} else {
op += (int) length;
switch(length) {
case 8:
*(--op) = (unsigned char) (right & 0xff);
case 7:
*(--op) = (unsigned char) ((right >> 8) & 0xff);
case 6:
*(--op) = (unsigned char) ((right >> 16) & 0xff);
case 5:
*(--op) = (unsigned char) ((right >> 24) & 0xff);
case 4:
*(--op) = (unsigned char) (left & 0xff);
case 3:
*(--op) = (unsigned char) ((left >> 8) & 0xff);
case 2:
*(--op) = (unsigned char) ((left >> 16) & 0xff);
case 1:
*(--op) = (unsigned char) ((left >> 24) & 0xff);
break;
}
break;
}
}
}
return 0;
}