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>
16 #include <afs/param.h>
22 #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
26 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_OBSD_ENV)
27 #include "netinet/in.h"
30 #include "afs/sysincludes.h"
32 #ifdef AFS_LINUX22_ENV
33 #include <asm/byteorder.h>
46 #include <rx/rxkad_stats.h>
57 fc_keysched(struct ktc_encryptionKey
*key
, fc_KeySchedule schedule
)
59 unsigned char *keychar
= (unsigned char *)key
;
65 /* first, flush the losing key parity bits. */
66 kword
[0] = (*keychar
++) >> 1;
68 kword
[0] += (*keychar
++) >> 1;
70 kword
[0] += (*keychar
++) >> 1;
72 kword
[0] += (*keychar
++) >> 1;
73 kword
[1] = kword
[0] >> 4; /* get top 24 bits for hi word */
76 kword
[0] += (*keychar
++) >> 1;
78 kword
[0] += (*keychar
++) >> 1;
80 kword
[0] += (*keychar
++) >> 1;
82 kword
[0] += (*keychar
) >> 1;
84 schedule
[0] = kword
[0];
85 for (i
= 1; i
< ROUNDS
; i
++) {
87 temp
= kword
[0] & ((1 << 11) - 1); /* get 11 lsb */
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];
93 INC_RXKAD_STATS(fc_key_scheds
);
97 /* IN int encrypt; * 0 ==> decrypt, else encrypt */
99 fc_ecb_encrypt(void * clear
, void * cipher
,
100 const fc_KeySchedule schedule
, int encrypt
)
103 volatile afs_uint32 S
, P
;
104 volatile unsigned char *Pchar
= (unsigned char *)&P
;
105 volatile unsigned char *Schar
= (unsigned char *)&S
;
108 #ifndef WORDS_BIGENDIAN
121 memcpy(&L
, clear
, sizeof(afs_int32
));
122 memcpy(&R
, clear
+ 1, sizeof(afs_int32
));
124 L
= ntohl(*((afs_uint32
*)clear
));
125 R
= ntohl(*((afs_uint32
*)clear
+ 1));
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 */
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 */
167 memcpy(cipher
, &L
, sizeof(afs_int32
));
168 memcpy(cipher
+ 1, &R
, sizeof(afs_int32
));
170 *((afs_int32
*)cipher
) = htonl(L
);
171 *((afs_int32
*)cipher
+ 1) = htonl(R
);
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.
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 *
188 fc_cbc_encrypt(void *input
, void *output
, afs_int32 length
,
189 const fc_KeySchedule key
, afs_uint32
* xor, int encrypt
)
192 afs_uint32 t_input
[2];
193 afs_uint32 t_output
[2];
194 unsigned char *t_in_p
= (unsigned char *)t_input
;
197 for (i
= 0; length
> 0; i
++, length
-= 8) {
199 memcpy(t_input
, input
, sizeof(t_input
));
200 input
=((char *)input
) + sizeof(t_input
);
203 for (j
= length
; j
<= 7; j
++)
206 /* do the xor for cbc into the temp */
207 xor[0] ^= t_input
[0];
208 xor[1] ^= t_input
[1];
210 fc_ecb_encrypt(xor, t_output
, key
, encrypt
);
212 /* copy temp output and save it for cbc */
213 memcpy(output
, t_output
, sizeof(t_output
));
214 output
=(char *)output
+ sizeof(t_output
);
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];
226 for (i
= 0; length
> 0; i
++, length
-= 8) {
228 memcpy(t_input
, input
, sizeof(t_input
));
229 input
=((char *)input
) + sizeof(t_input
);
231 /* no padding for decrypt */
232 fc_ecb_encrypt(t_input
, t_output
, key
, encrypt
);
234 /* do the xor for cbc into the output */
235 t_output
[0] ^= xor[0];
236 t_output
[1] ^= xor[1];
238 /* copy temp output */
239 memcpy(output
, t_output
, sizeof(t_output
));
240 output
=((char *)output
) + sizeof(t_output
);
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];