2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
11 * scatter/gather vectors.
17 #include "../afs/param.h"
19 #include "../afs/stds.h"
20 #include "../h/types.h"
21 #ifndef AFS_LINUX20_ENV
22 #include "../netinet/in.h"
25 #include "../afs/sysincludes.h"
26 #include "../afs/stds.h"
28 #ifdef AFS_LINUX22_ENV
29 #include <asm/byteorder.h>
32 #include "../afs/longc_procs.h"
36 #include <afs/param.h>
38 #include <sys/types.h>
42 #include <netinet/in.h>
60 #include "../afs/permit_xprt.h"
62 #include "../permit_xprt.h"
65 int fc_keysched (key, schedule)
66 IN struct ktc_encryptionKey *key;
67 OUT fc_KeySchedule schedule;
68 { unsigned char *keychar = (unsigned char *)key;
74 /* first, flush the losing key parity bits. */
75 kword[0] = (*keychar++) >> 1;
77 kword[0] += (*keychar++) >> 1;
79 kword[0] += (*keychar++) >> 1;
81 kword[0] += (*keychar++) >> 1;
82 kword[1] = kword[0] >> 4; /* get top 24 bits for hi word */
85 kword[0] += (*keychar++) >> 1;
87 kword[0] += (*keychar++) >> 1;
89 kword[0] += (*keychar++) >> 1;
91 kword[0] += (*keychar) >> 1;
93 schedule[0] = kword[0];
94 for (i=1; i<ROUNDS; i++) {
96 temp = kword[0] & ((1<<11)-1); /* get 11 lsb */
97 kword[0] = (kword[0] >> 11) | ((kword[1] & ((1<<11)-1)) << (32-11));
98 kword[1] = (kword[1] >> 11) | (temp << (56-32-11));
99 schedule[i] = kword[0];
102 rxkad_stats.fc_key_scheds++;
107 afs_int32 fc_ecb_encrypt(clear, cipher, schedule, encrypt)
108 IN afs_uint32 *clear;
109 OUT afs_uint32 *cipher;
110 IN fc_KeySchedule schedule;
111 IN int encrypt; /* 0 ==> decrypt, else encrypt */
114 unsigned char *Pchar = (unsigned char *)&P;
115 unsigned char *Schar = (unsigned char *)&S;
118 #if defined(vax) || (defined(mips) && defined(MIPSEL)) || defined(AFSLITTLE_ENDIAN)
131 bcopy (clear, &L, sizeof(afs_int32));
132 bcopy (clear+1, &R, sizeof(afs_int32));
135 R = ntohl(*(clear+1));
140 rxkad_stats.fc_encrypts[ENCRYPT]++;
142 for (i=0; i<(ROUNDS/2); i++) {
143 S = *schedule++ ^ R; /* xor R with key bits from schedule */
144 Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. */
145 Pchar[Byte3] = sbox1[Schar[Byte1]]; /* and permute the result */
146 Pchar[Byte1] = sbox2[Schar[Byte2]];
147 Pchar[Byte0] = sbox3[Schar[Byte3]];
148 P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
149 L ^= P; /* we're done with L, so save there */
150 S = *schedule++ ^ L; /* this time xor with L */
151 Pchar[Byte2] = sbox0[Schar[Byte0]];
152 Pchar[Byte3] = sbox1[Schar[Byte1]];
153 Pchar[Byte1] = sbox2[Schar[Byte2]];
154 Pchar[Byte0] = sbox3[Schar[Byte3]];
155 P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
161 rxkad_stats.fc_encrypts[DECRYPT]++;
163 schedule = &schedule[ROUNDS-1]; /* start at end of key schedule */
164 for (i=0; i<(ROUNDS/2); i++) {
165 S = *schedule-- ^ L; /* xor R with key bits from schedule */
166 Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. and */
167 Pchar[Byte3] = sbox1[Schar[Byte1]]; /* permute the result */
168 Pchar[Byte1] = sbox2[Schar[Byte2]];
169 Pchar[Byte0] = sbox3[Schar[Byte3]];
170 P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
171 R ^= P; /* we're done with L, so save there */
172 S = *schedule-- ^ R; /* this time xor with L */
173 Pchar[Byte2] = sbox0[Schar[Byte0]];
174 Pchar[Byte3] = sbox1[Schar[Byte1]];
175 Pchar[Byte1] = sbox2[Schar[Byte2]];
176 Pchar[Byte0] = sbox3[Schar[Byte3]];
177 P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
182 bcopy (&L, cipher, sizeof(afs_int32));
183 bcopy (&R, cipher+1, sizeof(afs_int32));
186 *(cipher+1) = htonl(R);
191 /* Crypting can be done in segments by recycling xor. All but the final segment must
192 * be multiples of 8 bytes.
193 * NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
194 * scatter/gather vectors.
196 afs_int32 fc_cbc_encrypt (input, output, length, key, xor, encrypt)
199 afs_int32 length; /* in bytes */
200 int encrypt; /* 0 ==> decrypt, else encrypt */
201 fc_KeySchedule key; /* precomputed key schedule */
202 afs_uint32 *xor; /* 8 bytes of initialization vector */
204 afs_uint32 t_input[2];
205 afs_uint32 t_output[2];
206 unsigned char *t_in_p = (unsigned char *) t_input;
209 for (i = 0; length > 0; i++, length -= 8) {
211 bcopy (input, t_input, sizeof(t_input));
212 input += sizeof(t_input);
215 for (j = length; j <= 7; j++)
218 /* do the xor for cbc into the temp */
219 xor[0] ^= t_input[0] ;
220 xor[1] ^= t_input[1] ;
222 fc_ecb_encrypt (xor, t_output, key, encrypt);
224 /* copy temp output and save it for cbc */
225 bcopy (t_output, output, sizeof(t_output));
226 output += sizeof(t_output);
228 /* calculate xor value for next round from plain & cipher text */
229 xor[0] = t_input[0] ^ t_output[0];
230 xor[1] = t_input[1] ^ t_output[1];
239 for (i = 0; length > 0; i++, length -= 8) {
241 bcopy (input, t_input, sizeof(t_input));
242 input += sizeof(t_input);
244 /* no padding for decrypt */
245 fc_ecb_encrypt(t_input, t_output, key, encrypt);
247 /* do the xor for cbc into the output */
248 t_output[0] ^= xor[0] ;
249 t_output[1] ^= xor[1] ;
251 /* copy temp output */
252 bcopy (t_output, output, sizeof(t_output));
253 output += sizeof(t_output);
255 /* calculate xor value for next round from plain & cipher text */
256 xor[0] = t_input[0] ^ t_output[0];
257 xor[1] = t_input[1] ^ t_output[1];