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.
15
#include <afsconfig.h>
17
#include "../afs/param.h"
19
#include <afs/param.h>
22
RCSID("$Header: /afs/sipb.mit.edu/project/openafs/debian/cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.1.1.6 2001/09/11 14:34:46 hartmans Exp $");
27
#include "../afs/stds.h"
28
#include "../h/types.h"
29
#ifndef AFS_LINUX20_ENV
30
#include "../netinet/in.h"
33
#include "../afs/sysincludes.h"
34
#include "../afs/stds.h"
36
#ifdef AFS_LINUX22_ENV
37
#include <asm/byteorder.h>
40
#include "../afs/longc_procs.h"
45
#include <sys/types.h>
49
#include <netinet/in.h>
67
int fc_keysched (key, schedule)
68
IN struct ktc_encryptionKey *key;
69
OUT fc_KeySchedule schedule;
70
{ unsigned char *keychar = (unsigned char *)key;
76
/* first, flush the losing key parity bits. */
77
kword[0] = (*keychar++) >> 1;
79
kword[0] += (*keychar++) >> 1;
81
kword[0] += (*keychar++) >> 1;
83
kword[0] += (*keychar++) >> 1;
84
kword[1] = kword[0] >> 4; /* get top 24 bits for hi word */
87
kword[0] += (*keychar++) >> 1;
89
kword[0] += (*keychar++) >> 1;
91
kword[0] += (*keychar++) >> 1;
93
kword[0] += (*keychar) >> 1;
95
schedule[0] = kword[0];
96
for (i=1; i<ROUNDS; i++) {
98
temp = kword[0] & ((1<<11)-1); /* get 11 lsb */
99
kword[0] = (kword[0] >> 11) | ((kword[1] & ((1<<11)-1)) << (32-11));
100
kword[1] = (kword[1] >> 11) | (temp << (56-32-11));
101
schedule[i] = kword[0];
104
rxkad_stats.fc_key_scheds++;
109
afs_int32 fc_ecb_encrypt(clear, cipher, schedule, encrypt)
110
IN afs_uint32 *clear;
111
OUT afs_uint32 *cipher;
112
IN fc_KeySchedule schedule;
113
IN int encrypt; /* 0 ==> decrypt, else encrypt */
116
unsigned char *Pchar = (unsigned char *)&P;
117
unsigned char *Schar = (unsigned char *)&S;
120
#if defined(vax) || (defined(mips) && defined(MIPSEL)) || defined(AFSLITTLE_ENDIAN)
133
memcpy(&L, clear, sizeof(afs_int32));
134
memcpy(&R, clear+1, sizeof(afs_int32));
137
R = ntohl(*(clear+1));
142
rxkad_stats.fc_encrypts[ENCRYPT]++;
144
for (i=0; i<(ROUNDS/2); i++) {
145
S = *schedule++ ^ R; /* xor R with key bits from schedule */
146
Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. */
147
Pchar[Byte3] = sbox1[Schar[Byte1]]; /* and permute the result */
148
Pchar[Byte1] = sbox2[Schar[Byte2]];
149
Pchar[Byte0] = sbox3[Schar[Byte3]];
150
P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
151
L ^= P; /* we're done with L, so save there */
152
S = *schedule++ ^ L; /* this time xor with L */
153
Pchar[Byte2] = sbox0[Schar[Byte0]];
154
Pchar[Byte3] = sbox1[Schar[Byte1]];
155
Pchar[Byte1] = sbox2[Schar[Byte2]];
156
Pchar[Byte0] = sbox3[Schar[Byte3]];
157
P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
163
rxkad_stats.fc_encrypts[DECRYPT]++;
165
schedule = &schedule[ROUNDS-1]; /* start at end of key schedule */
166
for (i=0; i<(ROUNDS/2); i++) {
167
S = *schedule-- ^ L; /* xor R with key bits from schedule */
168
Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. and */
169
Pchar[Byte3] = sbox1[Schar[Byte1]]; /* permute the result */
170
Pchar[Byte1] = sbox2[Schar[Byte2]];
171
Pchar[Byte0] = sbox3[Schar[Byte3]];
172
P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
173
R ^= P; /* we're done with L, so save there */
174
S = *schedule-- ^ R; /* this time xor with L */
175
Pchar[Byte2] = sbox0[Schar[Byte0]];
176
Pchar[Byte3] = sbox1[Schar[Byte1]];
177
Pchar[Byte1] = sbox2[Schar[Byte2]];
178
Pchar[Byte0] = sbox3[Schar[Byte3]];
179
P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
184
memcpy(cipher, &L, sizeof(afs_int32));
185
memcpy(cipher+1, &R, sizeof(afs_int32));
188
*(cipher+1) = htonl(R);
193
/* Crypting can be done in segments by recycling xor. All but the final segment must
194
* be multiples of 8 bytes.
195
* NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
196
* scatter/gather vectors.
198
afs_int32 fc_cbc_encrypt (input, output, length, key, xor, encrypt)
201
afs_int32 length; /* in bytes */
202
int encrypt; /* 0 ==> decrypt, else encrypt */
203
fc_KeySchedule key; /* precomputed key schedule */
204
afs_uint32 *xor; /* 8 bytes of initialization vector */
206
afs_uint32 t_input[2];
207
afs_uint32 t_output[2];
208
unsigned char *t_in_p = (unsigned char *) t_input;
211
for (i = 0; length > 0; i++, length -= 8) {
213
memcpy(t_input, input, sizeof(t_input));
214
input += sizeof(t_input);
217
for (j = length; j <= 7; j++)
220
/* do the xor for cbc into the temp */
221
xor[0] ^= t_input[0] ;
222
xor[1] ^= t_input[1] ;
224
fc_ecb_encrypt (xor, t_output, key, encrypt);
226
/* copy temp output and save it for cbc */
227
memcpy(output, t_output, sizeof(t_output));
228
output += sizeof(t_output);
230
/* calculate xor value for next round from plain & cipher text */
231
xor[0] = t_input[0] ^ t_output[0];
232
xor[1] = t_input[1] ^ t_output[1];
241
for (i = 0; length > 0; i++, length -= 8) {
243
memcpy(t_input, input, sizeof(t_input));
244
input += sizeof(t_input);
246
/* no padding for decrypt */
247
fc_ecb_encrypt(t_input, t_output, key, encrypt);
249
/* do the xor for cbc into the output */
250
t_output[0] ^= xor[0] ;
251
t_output[1] ^= xor[1] ;
253
/* copy temp output */
254
memcpy(output, t_output, sizeof(t_output));
255
output += sizeof(t_output);
257
/* calculate xor value for next round from plain & cipher text */
258
xor[0] = t_input[0] ^ t_output[0];
259
xor[1] = t_input[1] ^ t_output[1];