Annotation of 43BSDReno/kerberosIV/des/pcbc_encrypt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/pcbc_encrypt.c,v $
                      3:  * $Author: jtkohl $
                      4:  *
                      5:  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
                      6:  * of Technology.
                      7:  *
                      8:  * For copying and distribution information, please see the file
                      9:  * <mit-copyright.h>.
                     10:  *
                     11:  * These routines perform encryption and decryption using the DES
                     12:  * private key algorithm, or else a subset of it-- fewer inner loops.
                     13:  * ( AUTH_DES_ITER defaults to 16, may be less)
                     14:  *
                     15:  * Under U.S. law, this software may not be exported outside the US
                     16:  * without license from the U.S. Commerce department.
                     17:  *
                     18:  * The key schedule is passed as an arg, as well as the cleartext or
                     19:  * ciphertext.  The cleartext and ciphertext should be in host order.
                     20:  *
                     21:  * These routines form the library interface to the des facilities.
                     22:  *
                     23:  * spm 8/85    MIT project athena
                     24:  */
                     25: 
                     26: #ifndef        lint
                     27: static char rcsid_pcbc_encrypt_c[] =
                     28: "$Id: pcbc_encrypt.c,v 4.11 90/01/02 13:46:30 jtkohl Exp $";
                     29: #endif lint
                     30: 
                     31: #include <mit-copyright.h>
                     32: #include <stdio.h>
                     33: #include <des.h>
                     34: #include "des_internal.h"
                     35: 
                     36: extern int des_debug;
                     37: extern int des_debug_print();
                     38: 
                     39: /*
                     40:  * pcbc_encrypt is an "error propagation chaining" encrypt operation
                     41:  * for DES, similar to CBC, but that, on encryption, "xor"s the
                     42:  * plaintext of block N with the ciphertext resulting from block N,
                     43:  * then "xor"s that result with the plaintext of block N+1 prior to
                     44:  * encrypting block N+1. (decryption the appropriate inverse.  This
                     45:  * "pcbc" mode propagates a single bit error anywhere in either the
                     46:  * cleartext or ciphertext chain all the way through to the end. In
                     47:  * contrast, CBC mode limits a single bit error in the ciphertext to
                     48:  * affect only the current (8byte) block and the subsequent block.
                     49:  *
                     50:  * performs pcbc error-propagation chaining operation by xor-ing block
                     51:  * N+1 with both the plaintext (block N) and the ciphertext from block
                     52:  * N.  Either encrypts from cleartext to ciphertext, if encrypt != 0
                     53:  * or decrypts from ciphertext to cleartext, if encrypt == 0
                     54:  *
                     55:  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
                     56:  * enough space was provided, your program will get trashed.
                     57:  *
                     58:  * For encryption, the cleartext string is null padded, at the end, to
                     59:  * an integral multiple of eight bytes.
                     60:  *
                     61:  * For decryption, the ciphertext will be used in integral multiples
                     62:  * of 8 bytes, but only the first "length" bytes returned into the
                     63:  * cleartext.
                     64:  *
                     65:  * This is NOT a standard mode of operation.
                     66:  *
                     67:  */
                     68: 
                     69: int
                     70: des_pcbc_encrypt(in,out,length,key,iv,encrypt)
                     71:     des_cblock *in;            /* >= length bytes of inputtext */
                     72:     des_cblock *out;           /* >= length bytes of outputtext */
                     73:     register long length;      /* in bytes */
                     74:     int encrypt;               /* 0 ==> decrypt, else encrypt */
                     75:     des_key_schedule key;              /* precomputed key schedule */
                     76:     des_cblock *iv;            /* 8 bytes of ivec */
                     77: {
                     78:     register unsigned long *input = (unsigned long *) in;
                     79:     register unsigned long *output = (unsigned long *) out;
                     80:     register unsigned long *ivec = (unsigned long *) iv;
                     81: 
                     82:     unsigned long i,j;
                     83:     static unsigned long t_input[2];
                     84:     static unsigned long t_output[2];
                     85:     static unsigned char *t_in_p;
                     86:     static unsigned long xor_0, xor_1;
                     87: 
                     88:     t_in_p = (unsigned char *) t_input;
                     89:     if (encrypt) {
                     90: #ifdef MUSTALIGN
                     91:        if ((long) ivec & 3) {
                     92:            bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
                     93:            bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
                     94:        }
                     95:        else
                     96: #endif
                     97:        {
                     98:            xor_0 = *ivec++;
                     99:            xor_1 = *ivec;
                    100:        }
                    101: 
                    102:        for (i = 0; length > 0; i++, length -= 8) {
                    103:            /* get input */
                    104: #ifdef MUSTALIGN
                    105:            if ((long) input & 3) {
                    106:                bcopy((char *)input,(char *)&t_input[0],sizeof(t_input[0]));
                    107:                bcopy((char *)(input+1),(char *)&t_input[1],sizeof(t_input[1]));
                    108:            }
                    109:            else
                    110: #endif
                    111:            {
                    112:                t_input[0] = *input;
                    113:                t_input[1] = *(input+1);
                    114:            }
                    115: 
                    116:            /* zero pad */
                    117:            if (length < 8) {
                    118:                for (j = length; j <= 7; j++)
                    119:                    *(t_in_p+j)= 0;
                    120:            }
                    121: 
                    122: #ifdef DEBUG
                    123:            if (des_debug)
                    124:                des_debug_print("clear",length,t_input[0],t_input[1]);
                    125: #endif
                    126:            /* do the xor for cbc into the temp */
                    127:            t_input[0] ^= xor_0 ;
                    128:            t_input[1] ^= xor_1 ;
                    129:            /* encrypt */
                    130:            (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
                    131: 
                    132:            /*
                    133:             * We want to XOR with both the plaintext and ciphertext
                    134:             * of the previous block, before we write the output, in
                    135:             * case both input and output are the same space.
                    136:             */
                    137: #ifdef MUSTALIGN
                    138:            if ((long) input & 3) {
                    139:                bcopy((char *)input++,(char *)&xor_0,sizeof(xor_0));
                    140:                xor_0 ^= t_output[0];
                    141:                bcopy((char *)input++,(char *)&xor_1,sizeof(xor_1));
                    142:                xor_1 ^= t_output[1];
                    143:            }
                    144:            else
                    145: #endif
                    146:            {
                    147:                xor_0 = *input++ ^ t_output[0];
                    148:                xor_1 = *input++ ^ t_output[1];
                    149:            }
                    150: 
                    151: 
                    152:            /* copy temp output and save it for cbc */
                    153: #ifdef MUSTALIGN
                    154:            if ((long) output & 3) {
                    155:                bcopy((char *)&t_output[0],(char *)output++,
                    156:                      sizeof(t_output[0]));
                    157:                bcopy((char *)&t_output[1],(char *)output++,
                    158:                      sizeof(t_output[1]));
                    159:            }
                    160:            else
                    161: #endif
                    162:            {
                    163:                *output++ = t_output[0];
                    164:                *output++ = t_output[1];
                    165:            }
                    166: 
                    167: #ifdef DEBUG
                    168:            if (des_debug) {
                    169:                des_debug_print("xor'ed",i,t_input[0],t_input[1]);
                    170:                des_debug_print("cipher",i,t_output[0],t_output[1]);
                    171:            }
                    172: #endif
                    173:        }
                    174:        t_output[0] = 0;
                    175:        t_output[1] = 0;
                    176:        xor_0 = 0;
                    177:        xor_1 = 0;
                    178:        return 0;
                    179:     }
                    180: 
                    181:     else {
                    182:        /* decrypt */
                    183: #ifdef MUSTALIGN
                    184:        if ((long) ivec & 3) {
                    185:            bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
                    186:            bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
                    187:        }
                    188:        else
                    189: #endif
                    190:        {
                    191:            xor_0 = *ivec++;
                    192:            xor_1 = *ivec;
                    193:        }
                    194: 
                    195:        for (i = 0; length > 0; i++, length -= 8) {
                    196:            /* get input */
                    197: #ifdef MUSTALIGN
                    198:            if ((long) input & 3) {
                    199:                bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
                    200:                bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
                    201:            }
                    202:            else
                    203: #endif
                    204:            {
                    205:                t_input[0] = *input++;
                    206:                t_input[1] = *input++;
                    207:            }
                    208: 
                    209:            /* no padding for decrypt */
                    210: #ifdef DEBUG
                    211:            if (des_debug)
                    212:                des_debug_print("cipher",i,t_input[0],t_input[1]);
                    213: #else
                    214: #ifdef lint
                    215:            i = i;
                    216: #endif
                    217: #endif
                    218:            /* encrypt */
                    219:            (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
                    220: #ifdef DEBUG
                    221:            if (des_debug)
                    222:                des_debug_print("out pre xor",i,t_output[0],t_output[1]);
                    223: #endif
                    224:            /* do the xor for cbc into the output */
                    225:            t_output[0] ^= xor_0 ;
                    226:            t_output[1] ^= xor_1 ;
                    227:            /* copy temp output */
                    228: #ifdef MUSTALIGN
                    229:            if ((long) output & 3) {
                    230:                bcopy((char *)&t_output[0],(char *)output++,
                    231:                      sizeof(t_output[0]));
                    232:                bcopy((char *)&t_output[1],(char *)output++,
                    233:                      sizeof(t_output[1]));
                    234:            }
                    235:            else
                    236: #endif
                    237:            {
                    238:                *output++ = t_output[0];
                    239:                *output++ = t_output[1];
                    240:            }
                    241: 
                    242:            /* save xor value for next round */
                    243:            xor_0 = t_output[0] ^ t_input[0];
                    244:            xor_1 = t_output[1] ^ t_input[1];
                    245: 
                    246: #ifdef DEBUG
                    247:            if (des_debug)
                    248:                des_debug_print("clear",i,t_output[0],t_output[1]);
                    249: #endif
                    250:        }
                    251:        return 0;
                    252:     }
                    253: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.