diff options
Diffstat (limited to 'net/sunrpc/auth_gss/gss_krb5_keys.c')
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_keys.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 253b4149584a..d54668790f0c 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c | |||
@@ -250,3 +250,56 @@ err_free_cipher: | |||
250 | err_return: | 250 | err_return: |
251 | return ret; | 251 | return ret; |
252 | } | 252 | } |
253 | |||
254 | #define smask(step) ((1<<step)-1) | ||
255 | #define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step))) | ||
256 | #define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1) | ||
257 | |||
258 | static void mit_des_fixup_key_parity(u8 key[8]) | ||
259 | { | ||
260 | int i; | ||
261 | for (i = 0; i < 8; i++) { | ||
262 | key[i] &= 0xfe; | ||
263 | key[i] |= 1^parity_char(key[i]); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * This is the des3 key derivation postprocess function | ||
269 | */ | ||
270 | u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e, | ||
271 | struct xdr_netobj *randombits, | ||
272 | struct xdr_netobj *key) | ||
273 | { | ||
274 | int i; | ||
275 | u32 ret = EINVAL; | ||
276 | |||
277 | if (key->len != 24) { | ||
278 | dprintk("%s: key->len is %d\n", __func__, key->len); | ||
279 | goto err_out; | ||
280 | } | ||
281 | if (randombits->len != 21) { | ||
282 | dprintk("%s: randombits->len is %d\n", | ||
283 | __func__, randombits->len); | ||
284 | goto err_out; | ||
285 | } | ||
286 | |||
287 | /* take the seven bytes, move them around into the top 7 bits of the | ||
288 | 8 key bytes, then compute the parity bits. Do this three times. */ | ||
289 | |||
290 | for (i = 0; i < 3; i++) { | ||
291 | memcpy(key->data + i*8, randombits->data + i*7, 7); | ||
292 | key->data[i*8+7] = (((key->data[i*8]&1)<<1) | | ||
293 | ((key->data[i*8+1]&1)<<2) | | ||
294 | ((key->data[i*8+2]&1)<<3) | | ||
295 | ((key->data[i*8+3]&1)<<4) | | ||
296 | ((key->data[i*8+4]&1)<<5) | | ||
297 | ((key->data[i*8+5]&1)<<6) | | ||
298 | ((key->data[i*8+6]&1)<<7)); | ||
299 | |||
300 | mit_des_fixup_key_parity(key->data + i*8); | ||
301 | } | ||
302 | ret = 0; | ||
303 | err_out: | ||
304 | return ret; | ||
305 | } | ||