Standardize License information
[openafs.git] / src / rxkad / domestic / fcrypt.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /* NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
11  * scatter/gather vectors.
12  */
13
14 #define DEBUG 0
15
16 #ifdef KERNEL
17 #include "../afs/param.h"
18 #ifndef UKERNEL
19 #include "../afs/stds.h"
20 #include "../h/types.h"
21 #ifndef AFS_LINUX20_ENV
22 #include "../netinet/in.h"
23 #endif
24 #else /* UKERNEL */
25 #include "../afs/sysincludes.h"
26 #include "../afs/stds.h"
27 #endif /* UKERNEL */
28 #ifdef AFS_LINUX22_ENV
29 #include <asm/byteorder.h>
30 #endif
31
32 #include "../afs/longc_procs.h"
33
34 #else /* KERNEL */
35
36 #include <afs/param.h>
37 #include <afs/stds.h>
38 #include <sys/types.h>
39 #ifdef AFS_NT40_ENV
40 #include <winsock2.h>
41 #else
42 #include <netinet/in.h>
43 #endif
44 #include <rx/rx.h>
45 #endif /* KERNEL */
46
47 #include "sboxes.h"
48 #include "fcrypt.h"
49 #include "rxkad.h"
50
51
52 #ifdef TCRYPT
53 int ROUNDS = 16;
54 #else
55 #define ROUNDS 16
56 #endif
57
58 #define XPRT_FCRYPT
59 #ifdef KERNEL
60 #include "../afs/permit_xprt.h"
61 #else
62 #include "../permit_xprt.h"
63 #endif
64
65 int fc_keysched (key, schedule)
66   IN struct ktc_encryptionKey *key;
67   OUT fc_KeySchedule    schedule;
68 {   unsigned char *keychar = (unsigned char *)key;
69     afs_uint32  kword[2];
70
71     unsigned int   temp;
72     int            i;
73
74     /* first, flush the losing key parity bits. */
75     kword[0] = (*keychar++) >> 1;
76     kword[0] <<= 7;
77     kword[0] += (*keychar++) >> 1;
78     kword[0] <<= 7;
79     kword[0] += (*keychar++) >> 1;
80     kword[0] <<= 7;
81     kword[0] += (*keychar++) >> 1;
82     kword[1] = kword[0] >> 4;           /* get top 24 bits for hi word */
83     kword[0] &= 0xf;
84     kword[0] <<= 7;
85     kword[0] += (*keychar++) >> 1;
86     kword[0] <<= 7;
87     kword[0] += (*keychar++) >> 1;
88     kword[0] <<= 7;
89     kword[0] += (*keychar++) >> 1;
90     kword[0] <<= 7;
91     kword[0] += (*keychar) >> 1;
92
93     schedule[0] = kword[0];
94     for (i=1; i<ROUNDS; i++) {
95         /* rotate right 3 */
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];
100     }
101     LOCK_RXKAD_STATS
102     rxkad_stats.fc_key_scheds++;
103     UNLOCK_RXKAD_STATS
104     return 0;
105 }
106
107 AFS_HIDE
108 afs_int32 fc_ecb_encrypt(clear, cipher, schedule, encrypt)
109   IN afs_uint32  *clear;
110   OUT afs_uint32 *cipher;
111   IN fc_KeySchedule  schedule;
112   IN int             encrypt;   /* 0 ==> decrypt, else encrypt */
113 {   afs_uint32  L,R;
114     afs_uint32  S,P;
115     unsigned char *Pchar = (unsigned char *)&P;
116     unsigned char *Schar = (unsigned char *)&S;
117     int i;
118
119 #if defined(vax) || (defined(mips) && defined(MIPSEL)) || defined(AFSLITTLE_ENDIAN)
120 #define Byte0 3 
121 #define Byte1 2
122 #define Byte2 1
123 #define Byte3 0
124 #else
125 #define Byte0 0
126 #define Byte1 1
127 #define Byte2 2
128 #define Byte3 3
129 #endif
130
131 #if 0
132     bcopy (clear, &L, sizeof(afs_int32));
133     bcopy (clear+1, &R, sizeof(afs_int32));
134 #else
135     L = ntohl(*clear);
136     R = ntohl(*(clear+1));
137 #endif
138
139     if (encrypt) {
140         LOCK_RXKAD_STATS
141         rxkad_stats.fc_encrypts[ENCRYPT]++;
142         UNLOCK_RXKAD_STATS
143         for (i=0; i<(ROUNDS/2); i++) {
144             S = *schedule++ ^ R;        /* xor R with key bits from schedule */
145             Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. */
146             Pchar[Byte3] = sbox1[Schar[Byte1]]; /* and permute the result */
147             Pchar[Byte1] = sbox2[Schar[Byte2]];
148             Pchar[Byte0] = sbox3[Schar[Byte3]];
149             P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
150             L ^= P;                     /* we're done with L, so save there */
151             S = *schedule++ ^ L;        /* this time xor with L */
152             Pchar[Byte2] = sbox0[Schar[Byte0]];
153             Pchar[Byte3] = sbox1[Schar[Byte1]];
154             Pchar[Byte1] = sbox2[Schar[Byte2]];
155             Pchar[Byte0] = sbox3[Schar[Byte3]];
156             P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
157             R ^= P;
158         }
159     }
160     else {
161         LOCK_RXKAD_STATS
162         rxkad_stats.fc_encrypts[DECRYPT]++;
163         UNLOCK_RXKAD_STATS
164         schedule = &schedule[ROUNDS-1]; /* start at end of key schedule */
165         for (i=0; i<(ROUNDS/2); i++) {
166             S = *schedule-- ^ L;        /* xor R with key bits from schedule */
167             Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. and */
168             Pchar[Byte3] = sbox1[Schar[Byte1]]; /* permute the result */
169             Pchar[Byte1] = sbox2[Schar[Byte2]];
170             Pchar[Byte0] = sbox3[Schar[Byte3]];
171             P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
172             R ^= P;                     /* we're done with L, so save there */
173             S = *schedule-- ^ R;        /* this time xor with L */
174             Pchar[Byte2] = sbox0[Schar[Byte0]];
175             Pchar[Byte3] = sbox1[Schar[Byte1]];
176             Pchar[Byte1] = sbox2[Schar[Byte2]];
177             Pchar[Byte0] = sbox3[Schar[Byte3]];
178             P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
179             L ^= P;
180         }
181     }
182 #if 0
183     bcopy (&L, cipher, sizeof(afs_int32));
184     bcopy (&R, cipher+1, sizeof(afs_int32));
185 #else
186     *cipher = htonl(L);
187     *(cipher+1) = htonl(R);
188 #endif
189     return 0;
190 }
191
192 /* Crypting can be done in segments by recycling xor.  All but the final segment must
193  * be multiples of 8 bytes.
194  * NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
195  * scatter/gather vectors.
196  */
197 AFS_HIDE
198 afs_int32 fc_cbc_encrypt (input, output, length, key, xor, encrypt)
199   char          *input;
200   char          *output;
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 */
205 {   afs_uint32 i,j;
206     afs_uint32 t_input[2];
207     afs_uint32 t_output[2];
208     unsigned char *t_in_p = (unsigned char *) t_input;
209
210     if (encrypt) {
211         for (i = 0; length > 0; i++, length -= 8) {
212             /* get input */
213             bcopy (input, t_input, sizeof(t_input));
214             input += sizeof(t_input);
215
216             /* zero pad */
217             for (j = length; j <= 7; j++)
218                 *(t_in_p+j)= 0;
219
220             /* do the xor for cbc into the temp */
221             xor[0] ^= t_input[0] ;
222             xor[1] ^= t_input[1] ;
223             /* encrypt */
224             fc_ecb_encrypt (xor, t_output, key, encrypt);
225
226             /* copy temp output and save it for cbc */
227             bcopy (t_output, output, sizeof(t_output));
228             output += sizeof(t_output);
229
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];
233
234
235         }
236         t_output[0] = 0;
237         t_output[1] = 0;
238     }
239     else {
240         /* decrypt */
241         for (i = 0; length > 0; i++, length -= 8) {
242             /* get input */
243             bcopy (input, t_input, sizeof(t_input));
244             input += sizeof(t_input);
245
246             /* no padding for decrypt */
247             fc_ecb_encrypt(t_input, t_output, key, encrypt);
248
249             /* do the xor for cbc into the output */
250             t_output[0] ^= xor[0] ;
251             t_output[1] ^= xor[1] ;
252
253             /* copy temp output */
254             bcopy (t_output, output, sizeof(t_output));
255             output += sizeof(t_output);
256
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];
260         }
261     }
262     return 0;
263 }