#include "des_int.h"
#include "des.h"
#include <f_tables.h>
int KRB5_CALLCONV
des_pcbc_encrypt(in, out, length, schedule, ivec, enc)
des_cblock *in;
des_cblock *out;
long length;
const des_key_schedule schedule;
des_cblock *ivec;
int enc;
{
register unsigned DES_INT32 left, right;
const unsigned DES_INT32 *kp;
const unsigned char *ip;
unsigned char *op;
kp = (const unsigned DES_INT32 *)schedule;
if (enc) {
register unsigned DES_INT32 plainl = 42;
register unsigned DES_INT32 plainr = 17;
ip = *ivec;
GET_HALF_BLOCK(left, ip);
GET_HALF_BLOCK(right, ip);
ip = *in;
op = *out;
while (length > 0) {
if (length > 8) {
GET_HALF_BLOCK(plainl, ip);
GET_HALF_BLOCK(plainr, ip);
left ^= plainl;
right ^= plainr;
length -= 8;
} else {
ip += (int) length;
switch(length) {
case 8:
right ^= *(--ip) & 0xff;
case 7:
right ^= (*(--ip) & 0xff) << 8;
case 6:
right ^= (*(--ip) & 0xff) << 16;
case 5:
right ^= (*(--ip) & 0xff) << 24;
case 4:
left ^= *(--ip) & 0xff;
case 3:
left ^= (*(--ip) & 0xff) << 8;
case 2:
left ^= (*(--ip) & 0xff) << 16;
case 1:
left ^= (*(--ip) & 0xff) << 24;
break;
}
length = 0;
}
DES_DO_ENCRYPT(left, right, kp);
PUT_HALF_BLOCK(left, op);
PUT_HALF_BLOCK(right, op);
left ^= plainl;
right ^= plainr;
}
} 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, kp);
left ^= ocipherl;
right ^= ocipherr;
if (length > 8) {
length -= 8;
PUT_HALF_BLOCK(left, op);
PUT_HALF_BLOCK(right, op);
ocipherl = cipherl ^ left;
ocipherr = cipherr ^ right;
} 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;
}