|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.