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