2 * linux/net/sunrpc/gss_krb5_crypto.c
4 * Copyright (c) 2000-2008 The Regents of the University of Michigan.
7 * Andy Adamson <andros@umich.edu>
8 * Bruce Fields <bfields@umich.edu>
12 * Copyright (C) 1998 by the FundsXpress, INC.
14 * All rights reserved.
16 * Export of this software from the United States of America may require
17 * a specific license from the United States Government. It is the
18 * responsibility of any person or organization contemplating export to
19 * obtain such a license before exporting.
21 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
22 * distribute this software and its documentation for any purpose and
23 * without fee is hereby granted, provided that the above copyright
24 * notice appear in all copies and that both that copyright notice and
25 * this permission notice appear in supporting documentation, and that
26 * the name of FundsXpress. not be used in advertising or publicity pertaining
27 * to distribution of the software without specific, written prior
28 * permission. FundsXpress makes no representations about the suitability of
29 * this software for any purpose. It is provided "as is" without express
30 * or implied warranty.
32 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
37 #include <linux/err.h>
38 #include <linux/types.h>
40 #include <linux/scatterlist.h>
41 #include <linux/crypto.h>
42 #include <linux/highmem.h>
43 #include <linux/pagemap.h>
44 #include <linux/random.h>
45 #include <linux/sunrpc/gss_krb5.h>
46 #include <linux/sunrpc/xdr.h>
49 # define RPCDBG_FACILITY RPCDBG_AUTH
54 struct crypto_blkcipher
*tfm
,
61 struct scatterlist sg
[1];
62 u8 local_iv
[GSS_KRB5_MAX_BLOCKSIZE
] = {0};
63 struct blkcipher_desc desc
= { .tfm
= tfm
, .info
= local_iv
};
65 if (length
% crypto_blkcipher_blocksize(tfm
) != 0)
68 if (crypto_blkcipher_ivsize(tfm
) > GSS_KRB5_MAX_BLOCKSIZE
) {
69 dprintk("RPC: gss_k5encrypt: tfm iv size too large %d\n",
70 crypto_blkcipher_ivsize(tfm
));
75 memcpy(local_iv
, iv
, crypto_blkcipher_ivsize(tfm
));
77 memcpy(out
, in
, length
);
78 sg_init_one(sg
, out
, length
);
80 ret
= crypto_blkcipher_encrypt_iv(&desc
, sg
, sg
, length
);
82 dprintk("RPC: krb5_encrypt returns %d\n", ret
);
88 struct crypto_blkcipher
*tfm
,
95 struct scatterlist sg
[1];
96 u8 local_iv
[GSS_KRB5_MAX_BLOCKSIZE
] = {0};
97 struct blkcipher_desc desc
= { .tfm
= tfm
, .info
= local_iv
};
99 if (length
% crypto_blkcipher_blocksize(tfm
) != 0)
102 if (crypto_blkcipher_ivsize(tfm
) > GSS_KRB5_MAX_BLOCKSIZE
) {
103 dprintk("RPC: gss_k5decrypt: tfm iv size too large %d\n",
104 crypto_blkcipher_ivsize(tfm
));
108 memcpy(local_iv
,iv
, crypto_blkcipher_ivsize(tfm
));
110 memcpy(out
, in
, length
);
111 sg_init_one(sg
, out
, length
);
113 ret
= crypto_blkcipher_decrypt_iv(&desc
, sg
, sg
, length
);
115 dprintk("RPC: gss_k5decrypt returns %d\n",ret
);
120 checksummer(struct scatterlist
*sg
, void *data
)
122 struct hash_desc
*desc
= data
;
124 return crypto_hash_update(desc
, sg
, sg
->length
);
128 arcfour_hmac_md5_usage_to_salt(unsigned int usage
, u8 salt
[4])
130 unsigned int ms_usage
;
142 salt
[0] = (ms_usage
>> 0) & 0xff;
143 salt
[1] = (ms_usage
>> 8) & 0xff;
144 salt
[2] = (ms_usage
>> 16) & 0xff;
145 salt
[3] = (ms_usage
>> 24) & 0xff;
151 make_checksum_hmac_md5(struct krb5_ctx
*kctx
, char *header
, int hdrlen
,
152 struct xdr_buf
*body
, int body_offset
, u8
*cksumkey
,
153 unsigned int usage
, struct xdr_netobj
*cksumout
)
155 struct hash_desc desc
;
156 struct scatterlist sg
[1];
158 u8 checksumdata
[GSS_KRB5_MAX_CKSUM_LEN
];
160 struct crypto_hash
*md5
;
161 struct crypto_hash
*hmac_md5
;
163 if (cksumkey
== NULL
)
164 return GSS_S_FAILURE
;
166 if (cksumout
->len
< kctx
->gk5e
->cksumlength
) {
167 dprintk("%s: checksum buffer length, %u, too small for %s\n",
168 __func__
, cksumout
->len
, kctx
->gk5e
->name
);
169 return GSS_S_FAILURE
;
172 if (arcfour_hmac_md5_usage_to_salt(usage
, rc4salt
)) {
173 dprintk("%s: invalid usage value %u\n", __func__
, usage
);
174 return GSS_S_FAILURE
;
177 md5
= crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC
);
179 return GSS_S_FAILURE
;
181 hmac_md5
= crypto_alloc_hash(kctx
->gk5e
->cksum_name
, 0,
183 if (IS_ERR(hmac_md5
)) {
184 crypto_free_hash(md5
);
185 return GSS_S_FAILURE
;
189 desc
.flags
= CRYPTO_TFM_REQ_MAY_SLEEP
;
191 err
= crypto_hash_init(&desc
);
194 sg_init_one(sg
, rc4salt
, 4);
195 err
= crypto_hash_update(&desc
, sg
, 4);
199 sg_init_one(sg
, header
, hdrlen
);
200 err
= crypto_hash_update(&desc
, sg
, hdrlen
);
203 err
= xdr_process_buf(body
, body_offset
, body
->len
- body_offset
,
207 err
= crypto_hash_final(&desc
, checksumdata
);
212 desc
.flags
= CRYPTO_TFM_REQ_MAY_SLEEP
;
214 err
= crypto_hash_init(&desc
);
217 err
= crypto_hash_setkey(hmac_md5
, cksumkey
, kctx
->gk5e
->keylength
);
221 sg_init_one(sg
, checksumdata
, crypto_hash_digestsize(md5
));
222 err
= crypto_hash_digest(&desc
, sg
, crypto_hash_digestsize(md5
),
227 memcpy(cksumout
->data
, checksumdata
, kctx
->gk5e
->cksumlength
);
228 cksumout
->len
= kctx
->gk5e
->cksumlength
;
230 crypto_free_hash(md5
);
231 crypto_free_hash(hmac_md5
);
232 return err
? GSS_S_FAILURE
: 0;
236 * checksum the plaintext data and hdrlen bytes of the token header
237 * The checksum is performed over the first 8 bytes of the
238 * gss token header and then over the data body
241 make_checksum(struct krb5_ctx
*kctx
, char *header
, int hdrlen
,
242 struct xdr_buf
*body
, int body_offset
, u8
*cksumkey
,
243 unsigned int usage
, struct xdr_netobj
*cksumout
)
245 struct hash_desc desc
;
246 struct scatterlist sg
[1];
248 u8 checksumdata
[GSS_KRB5_MAX_CKSUM_LEN
];
249 unsigned int checksumlen
;
251 if (kctx
->gk5e
->ctype
== CKSUMTYPE_HMAC_MD5_ARCFOUR
)
252 return make_checksum_hmac_md5(kctx
, header
, hdrlen
,
254 cksumkey
, usage
, cksumout
);
256 if (cksumout
->len
< kctx
->gk5e
->cksumlength
) {
257 dprintk("%s: checksum buffer length, %u, too small for %s\n",
258 __func__
, cksumout
->len
, kctx
->gk5e
->name
);
259 return GSS_S_FAILURE
;
262 desc
.tfm
= crypto_alloc_hash(kctx
->gk5e
->cksum_name
, 0, CRYPTO_ALG_ASYNC
);
263 if (IS_ERR(desc
.tfm
))
264 return GSS_S_FAILURE
;
265 desc
.flags
= CRYPTO_TFM_REQ_MAY_SLEEP
;
267 checksumlen
= crypto_hash_digestsize(desc
.tfm
);
269 if (cksumkey
!= NULL
) {
270 err
= crypto_hash_setkey(desc
.tfm
, cksumkey
,
271 kctx
->gk5e
->keylength
);
276 err
= crypto_hash_init(&desc
);
279 sg_init_one(sg
, header
, hdrlen
);
280 err
= crypto_hash_update(&desc
, sg
, hdrlen
);
283 err
= xdr_process_buf(body
, body_offset
, body
->len
- body_offset
,
287 err
= crypto_hash_final(&desc
, checksumdata
);
291 switch (kctx
->gk5e
->ctype
) {
292 case CKSUMTYPE_RSA_MD5
:
293 err
= kctx
->gk5e
->encrypt(kctx
->seq
, NULL
, checksumdata
,
294 checksumdata
, checksumlen
);
297 memcpy(cksumout
->data
,
298 checksumdata
+ checksumlen
- kctx
->gk5e
->cksumlength
,
299 kctx
->gk5e
->cksumlength
);
301 case CKSUMTYPE_HMAC_SHA1_DES3
:
302 memcpy(cksumout
->data
, checksumdata
, kctx
->gk5e
->cksumlength
);
308 cksumout
->len
= kctx
->gk5e
->cksumlength
;
310 crypto_free_hash(desc
.tfm
);
311 return err
? GSS_S_FAILURE
: 0;
315 * checksum the plaintext data and hdrlen bytes of the token header
316 * Per rfc4121, sec. 4.2.4, the checksum is performed over the data
317 * body then over the first 16 octets of the MIC token
318 * Inclusion of the header data in the calculation of the
319 * checksum is optional.
322 make_checksum_v2(struct krb5_ctx
*kctx
, char *header
, int hdrlen
,
323 struct xdr_buf
*body
, int body_offset
, u8
*cksumkey
,
324 unsigned int usage
, struct xdr_netobj
*cksumout
)
326 struct hash_desc desc
;
327 struct scatterlist sg
[1];
329 u8 checksumdata
[GSS_KRB5_MAX_CKSUM_LEN
];
330 unsigned int checksumlen
;
332 if (kctx
->gk5e
->keyed_cksum
== 0) {
333 dprintk("%s: expected keyed hash for %s\n",
334 __func__
, kctx
->gk5e
->name
);
335 return GSS_S_FAILURE
;
337 if (cksumkey
== NULL
) {
338 dprintk("%s: no key supplied for %s\n",
339 __func__
, kctx
->gk5e
->name
);
340 return GSS_S_FAILURE
;
343 desc
.tfm
= crypto_alloc_hash(kctx
->gk5e
->cksum_name
, 0,
345 if (IS_ERR(desc
.tfm
))
346 return GSS_S_FAILURE
;
347 checksumlen
= crypto_hash_digestsize(desc
.tfm
);
348 desc
.flags
= CRYPTO_TFM_REQ_MAY_SLEEP
;
350 err
= crypto_hash_setkey(desc
.tfm
, cksumkey
, kctx
->gk5e
->keylength
);
354 err
= crypto_hash_init(&desc
);
357 err
= xdr_process_buf(body
, body_offset
, body
->len
- body_offset
,
361 if (header
!= NULL
) {
362 sg_init_one(sg
, header
, hdrlen
);
363 err
= crypto_hash_update(&desc
, sg
, hdrlen
);
367 err
= crypto_hash_final(&desc
, checksumdata
);
371 cksumout
->len
= kctx
->gk5e
->cksumlength
;
373 switch (kctx
->gk5e
->ctype
) {
374 case CKSUMTYPE_HMAC_SHA1_96_AES128
:
375 case CKSUMTYPE_HMAC_SHA1_96_AES256
:
376 /* note that this truncates the hash */
377 memcpy(cksumout
->data
, checksumdata
, kctx
->gk5e
->cksumlength
);
384 crypto_free_hash(desc
.tfm
);
385 return err
? GSS_S_FAILURE
: 0;
388 struct encryptor_desc
{
389 u8 iv
[GSS_KRB5_MAX_BLOCKSIZE
];
390 struct blkcipher_desc desc
;
392 struct xdr_buf
*outbuf
;
394 struct scatterlist infrags
[4];
395 struct scatterlist outfrags
[4];
401 encryptor(struct scatterlist
*sg
, void *data
)
403 struct encryptor_desc
*desc
= data
;
404 struct xdr_buf
*outbuf
= desc
->outbuf
;
405 struct page
*in_page
;
406 int thislen
= desc
->fraglen
+ sg
->length
;
410 /* Worst case is 4 fragments: head, end of page 1, start
411 * of page 2, tail. Anything more is a bug. */
412 BUG_ON(desc
->fragno
> 3);
414 page_pos
= desc
->pos
- outbuf
->head
[0].iov_len
;
415 if (page_pos
>= 0 && page_pos
< outbuf
->page_len
) {
416 /* pages are not in place: */
417 int i
= (page_pos
+ outbuf
->page_base
) >> PAGE_CACHE_SHIFT
;
418 in_page
= desc
->pages
[i
];
420 in_page
= sg_page(sg
);
422 sg_set_page(&desc
->infrags
[desc
->fragno
], in_page
, sg
->length
,
424 sg_set_page(&desc
->outfrags
[desc
->fragno
], sg_page(sg
), sg
->length
,
427 desc
->fraglen
+= sg
->length
;
428 desc
->pos
+= sg
->length
;
430 fraglen
= thislen
& (crypto_blkcipher_blocksize(desc
->desc
.tfm
) - 1);
436 sg_mark_end(&desc
->infrags
[desc
->fragno
- 1]);
437 sg_mark_end(&desc
->outfrags
[desc
->fragno
- 1]);
439 ret
= crypto_blkcipher_encrypt_iv(&desc
->desc
, desc
->outfrags
,
440 desc
->infrags
, thislen
);
444 sg_init_table(desc
->infrags
, 4);
445 sg_init_table(desc
->outfrags
, 4);
448 sg_set_page(&desc
->outfrags
[0], sg_page(sg
), fraglen
,
449 sg
->offset
+ sg
->length
- fraglen
);
450 desc
->infrags
[0] = desc
->outfrags
[0];
451 sg_assign_page(&desc
->infrags
[0], in_page
);
453 desc
->fraglen
= fraglen
;
462 gss_encrypt_xdr_buf(struct crypto_blkcipher
*tfm
, struct xdr_buf
*buf
,
463 int offset
, struct page
**pages
)
466 struct encryptor_desc desc
;
468 BUG_ON((buf
->len
- offset
) % crypto_blkcipher_blocksize(tfm
) != 0);
470 memset(desc
.iv
, 0, sizeof(desc
.iv
));
472 desc
.desc
.info
= desc
.iv
;
480 sg_init_table(desc
.infrags
, 4);
481 sg_init_table(desc
.outfrags
, 4);
483 ret
= xdr_process_buf(buf
, offset
, buf
->len
- offset
, encryptor
, &desc
);
487 struct decryptor_desc
{
488 u8 iv
[GSS_KRB5_MAX_BLOCKSIZE
];
489 struct blkcipher_desc desc
;
490 struct scatterlist frags
[4];
496 decryptor(struct scatterlist
*sg
, void *data
)
498 struct decryptor_desc
*desc
= data
;
499 int thislen
= desc
->fraglen
+ sg
->length
;
502 /* Worst case is 4 fragments: head, end of page 1, start
503 * of page 2, tail. Anything more is a bug. */
504 BUG_ON(desc
->fragno
> 3);
505 sg_set_page(&desc
->frags
[desc
->fragno
], sg_page(sg
), sg
->length
,
508 desc
->fraglen
+= sg
->length
;
510 fraglen
= thislen
& (crypto_blkcipher_blocksize(desc
->desc
.tfm
) - 1);
516 sg_mark_end(&desc
->frags
[desc
->fragno
- 1]);
518 ret
= crypto_blkcipher_decrypt_iv(&desc
->desc
, desc
->frags
,
519 desc
->frags
, thislen
);
523 sg_init_table(desc
->frags
, 4);
526 sg_set_page(&desc
->frags
[0], sg_page(sg
), fraglen
,
527 sg
->offset
+ sg
->length
- fraglen
);
529 desc
->fraglen
= fraglen
;
538 gss_decrypt_xdr_buf(struct crypto_blkcipher
*tfm
, struct xdr_buf
*buf
,
541 struct decryptor_desc desc
;
544 BUG_ON((buf
->len
- offset
) % crypto_blkcipher_blocksize(tfm
) != 0);
546 memset(desc
.iv
, 0, sizeof(desc
.iv
));
548 desc
.desc
.info
= desc
.iv
;
553 sg_init_table(desc
.frags
, 4);
555 return xdr_process_buf(buf
, offset
, buf
->len
- offset
, decryptor
, &desc
);
559 * This function makes the assumption that it was ultimately called
562 * The client auth_gss code moves any existing tail data into a
563 * separate page before calling gss_wrap.
564 * The server svcauth_gss code ensures that both the head and the
565 * tail have slack space of RPC_MAX_AUTH_SIZE before calling gss_wrap.
567 * Even with that guarantee, this function may be called more than
568 * once in the processing of gss_wrap(). The best we can do is
569 * verify at compile-time (see GSS_KRB5_SLACK_CHECK) that the
570 * largest expected shift will fit within RPC_MAX_AUTH_SIZE.
571 * At run-time we can verify that a single invocation of this
572 * function doesn't attempt to use more the RPC_MAX_AUTH_SIZE.
576 xdr_extend_head(struct xdr_buf
*buf
, unsigned int base
, unsigned int shiftlen
)
583 BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED
> RPC_MAX_AUTH_SIZE
);
584 BUG_ON(shiftlen
> RPC_MAX_AUTH_SIZE
);
586 p
= buf
->head
[0].iov_base
+ base
;
588 memmove(p
+ shiftlen
, p
, buf
->head
[0].iov_len
- base
);
590 buf
->head
[0].iov_len
+= shiftlen
;
591 buf
->len
+= shiftlen
;
597 gss_krb5_cts_crypt(struct crypto_blkcipher
*cipher
, struct xdr_buf
*buf
,
598 u32 offset
, u8
*iv
, struct page
**pages
, int encrypt
)
601 struct scatterlist sg
[1];
602 struct blkcipher_desc desc
= { .tfm
= cipher
, .info
= iv
};
603 u8 data
[GSS_KRB5_MAX_BLOCKSIZE
* 2];
604 struct page
**save_pages
;
605 u32 len
= buf
->len
- offset
;
607 if (len
> ARRAY_SIZE(data
)) {
613 * For encryption, we want to read from the cleartext
614 * page cache pages, and write the encrypted data to
615 * the supplied xdr_buf pages.
617 save_pages
= buf
->pages
;
621 ret
= read_bytes_from_xdr_buf(buf
, offset
, data
, len
);
622 buf
->pages
= save_pages
;
626 sg_init_one(sg
, data
, len
);
629 ret
= crypto_blkcipher_encrypt_iv(&desc
, sg
, sg
, len
);
631 ret
= crypto_blkcipher_decrypt_iv(&desc
, sg
, sg
, len
);
636 ret
= write_bytes_to_xdr_buf(buf
, offset
, data
, len
);
643 gss_krb5_aes_encrypt(struct krb5_ctx
*kctx
, u32 offset
,
644 struct xdr_buf
*buf
, int ec
, struct page
**pages
)
647 struct xdr_netobj hmac
;
650 struct crypto_blkcipher
*cipher
, *aux_cipher
;
652 struct page
**save_pages
;
654 struct encryptor_desc desc
;
658 if (kctx
->initiate
) {
659 cipher
= kctx
->initiator_enc
;
660 aux_cipher
= kctx
->initiator_enc_aux
;
661 cksumkey
= kctx
->initiator_integ
;
662 usage
= KG_USAGE_INITIATOR_SEAL
;
664 cipher
= kctx
->acceptor_enc
;
665 aux_cipher
= kctx
->acceptor_enc_aux
;
666 cksumkey
= kctx
->acceptor_integ
;
667 usage
= KG_USAGE_ACCEPTOR_SEAL
;
669 blocksize
= crypto_blkcipher_blocksize(cipher
);
671 /* hide the gss token header and insert the confounder */
672 offset
+= GSS_KRB5_TOK_HDR_LEN
;
673 if (xdr_extend_head(buf
, offset
, kctx
->gk5e
->conflen
))
674 return GSS_S_FAILURE
;
675 gss_krb5_make_confounder(buf
->head
[0].iov_base
+ offset
, kctx
->gk5e
->conflen
);
676 offset
-= GSS_KRB5_TOK_HDR_LEN
;
678 if (buf
->tail
[0].iov_base
!= NULL
) {
679 ecptr
= buf
->tail
[0].iov_base
+ buf
->tail
[0].iov_len
;
681 buf
->tail
[0].iov_base
= buf
->head
[0].iov_base
682 + buf
->head
[0].iov_len
;
683 buf
->tail
[0].iov_len
= 0;
684 ecptr
= buf
->tail
[0].iov_base
;
687 memset(ecptr
, 'X', ec
);
688 buf
->tail
[0].iov_len
+= ec
;
691 /* copy plaintext gss token header after filler (if any) */
692 memcpy(ecptr
+ ec
, buf
->head
[0].iov_base
+ offset
,
693 GSS_KRB5_TOK_HDR_LEN
);
694 buf
->tail
[0].iov_len
+= GSS_KRB5_TOK_HDR_LEN
;
695 buf
->len
+= GSS_KRB5_TOK_HDR_LEN
;
698 hmac
.len
= GSS_KRB5_MAX_CKSUM_LEN
;
699 hmac
.data
= buf
->tail
[0].iov_base
+ buf
->tail
[0].iov_len
;
702 * When we are called, pages points to the real page cache
703 * data -- which we can't go and encrypt! buf->pages points
704 * to scratch pages which we are going to send off to the
705 * client/server. Swap in the plaintext pages to calculate
708 save_pages
= buf
->pages
;
711 err
= make_checksum_v2(kctx
, NULL
, 0, buf
,
712 offset
+ GSS_KRB5_TOK_HDR_LEN
,
713 cksumkey
, usage
, &hmac
);
714 buf
->pages
= save_pages
;
716 return GSS_S_FAILURE
;
718 nbytes
= buf
->len
- offset
- GSS_KRB5_TOK_HDR_LEN
;
719 nblocks
= (nbytes
+ blocksize
- 1) / blocksize
;
722 cbcbytes
= (nblocks
- 2) * blocksize
;
724 memset(desc
.iv
, 0, sizeof(desc
.iv
));
727 desc
.pos
= offset
+ GSS_KRB5_TOK_HDR_LEN
;
732 desc
.desc
.info
= desc
.iv
;
734 desc
.desc
.tfm
= aux_cipher
;
736 sg_init_table(desc
.infrags
, 4);
737 sg_init_table(desc
.outfrags
, 4);
739 err
= xdr_process_buf(buf
, offset
+ GSS_KRB5_TOK_HDR_LEN
,
740 cbcbytes
, encryptor
, &desc
);
745 /* Make sure IV carries forward from any CBC results. */
746 err
= gss_krb5_cts_crypt(cipher
, buf
,
747 offset
+ GSS_KRB5_TOK_HDR_LEN
+ cbcbytes
,
754 /* Now update buf to account for HMAC */
755 buf
->tail
[0].iov_len
+= kctx
->gk5e
->cksumlength
;
756 buf
->len
+= kctx
->gk5e
->cksumlength
;
765 gss_krb5_aes_decrypt(struct krb5_ctx
*kctx
, u32 offset
, struct xdr_buf
*buf
,
766 u32
*headskip
, u32
*tailskip
)
768 struct xdr_buf subbuf
;
771 struct crypto_blkcipher
*cipher
, *aux_cipher
;
772 struct xdr_netobj our_hmac_obj
;
773 u8 our_hmac
[GSS_KRB5_MAX_CKSUM_LEN
];
774 u8 pkt_hmac
[GSS_KRB5_MAX_CKSUM_LEN
];
775 int nblocks
, blocksize
, cbcbytes
;
776 struct decryptor_desc desc
;
779 if (kctx
->initiate
) {
780 cipher
= kctx
->acceptor_enc
;
781 aux_cipher
= kctx
->acceptor_enc_aux
;
782 cksum_key
= kctx
->acceptor_integ
;
783 usage
= KG_USAGE_ACCEPTOR_SEAL
;
785 cipher
= kctx
->initiator_enc
;
786 aux_cipher
= kctx
->initiator_enc_aux
;
787 cksum_key
= kctx
->initiator_integ
;
788 usage
= KG_USAGE_INITIATOR_SEAL
;
790 blocksize
= crypto_blkcipher_blocksize(cipher
);
793 /* create a segment skipping the header and leaving out the checksum */
794 xdr_buf_subsegment(buf
, &subbuf
, offset
+ GSS_KRB5_TOK_HDR_LEN
,
795 (buf
->len
- offset
- GSS_KRB5_TOK_HDR_LEN
-
796 kctx
->gk5e
->cksumlength
));
798 nblocks
= (subbuf
.len
+ blocksize
- 1) / blocksize
;
802 cbcbytes
= (nblocks
- 2) * blocksize
;
804 memset(desc
.iv
, 0, sizeof(desc
.iv
));
809 desc
.desc
.info
= desc
.iv
;
811 desc
.desc
.tfm
= aux_cipher
;
813 sg_init_table(desc
.frags
, 4);
815 ret
= xdr_process_buf(&subbuf
, 0, cbcbytes
, decryptor
, &desc
);
820 /* Make sure IV carries forward from any CBC results. */
821 ret
= gss_krb5_cts_crypt(cipher
, &subbuf
, cbcbytes
, desc
.iv
, NULL
, 0);
826 /* Calculate our hmac over the plaintext data */
827 our_hmac_obj
.len
= sizeof(our_hmac
);
828 our_hmac_obj
.data
= our_hmac
;
830 ret
= make_checksum_v2(kctx
, NULL
, 0, &subbuf
, 0,
831 cksum_key
, usage
, &our_hmac_obj
);
835 /* Get the packet's hmac value */
836 ret
= read_bytes_from_xdr_buf(buf
, buf
->len
- kctx
->gk5e
->cksumlength
,
837 pkt_hmac
, kctx
->gk5e
->cksumlength
);
841 if (memcmp(pkt_hmac
, our_hmac
, kctx
->gk5e
->cksumlength
) != 0) {
845 *headskip
= kctx
->gk5e
->conflen
;
846 *tailskip
= kctx
->gk5e
->cksumlength
;
848 if (ret
&& ret
!= GSS_S_BAD_SIG
)
854 * Compute Kseq given the initial session key and the checksum.
855 * Set the key of the given cipher.
858 krb5_rc4_setup_seq_key(struct krb5_ctx
*kctx
, struct crypto_blkcipher
*cipher
,
859 unsigned char *cksum
)
861 struct crypto_hash
*hmac
;
862 struct hash_desc desc
;
863 struct scatterlist sg
[1];
864 u8 Kseq
[GSS_KRB5_MAX_KEYLEN
];
865 u32 zeroconstant
= 0;
868 dprintk("%s: entered\n", __func__
);
870 hmac
= crypto_alloc_hash(kctx
->gk5e
->cksum_name
, 0, CRYPTO_ALG_ASYNC
);
872 dprintk("%s: error %ld, allocating hash '%s'\n",
873 __func__
, PTR_ERR(hmac
), kctx
->gk5e
->cksum_name
);
874 return PTR_ERR(hmac
);
880 err
= crypto_hash_init(&desc
);
884 /* Compute intermediate Kseq from session key */
885 err
= crypto_hash_setkey(hmac
, kctx
->Ksess
, kctx
->gk5e
->keylength
);
889 sg_init_table(sg
, 1);
890 sg_set_buf(sg
, &zeroconstant
, 4);
892 err
= crypto_hash_digest(&desc
, sg
, 4, Kseq
);
896 /* Compute final Kseq from the checksum and intermediate Kseq */
897 err
= crypto_hash_setkey(hmac
, Kseq
, kctx
->gk5e
->keylength
);
901 sg_set_buf(sg
, cksum
, 8);
903 err
= crypto_hash_digest(&desc
, sg
, 8, Kseq
);
907 err
= crypto_blkcipher_setkey(cipher
, Kseq
, kctx
->gk5e
->keylength
);
914 crypto_free_hash(hmac
);
915 dprintk("%s: returning %d\n", __func__
, err
);
920 * Compute Kcrypt given the initial session key and the plaintext seqnum.
921 * Set the key of cipher kctx->enc.
924 krb5_rc4_setup_enc_key(struct krb5_ctx
*kctx
, struct crypto_blkcipher
*cipher
,
927 struct crypto_hash
*hmac
;
928 struct hash_desc desc
;
929 struct scatterlist sg
[1];
930 u8 Kcrypt
[GSS_KRB5_MAX_KEYLEN
];
931 u8 zeroconstant
[4] = {0};
935 dprintk("%s: entered, seqnum %u\n", __func__
, seqnum
);
937 hmac
= crypto_alloc_hash(kctx
->gk5e
->cksum_name
, 0, CRYPTO_ALG_ASYNC
);
939 dprintk("%s: error %ld, allocating hash '%s'\n",
940 __func__
, PTR_ERR(hmac
), kctx
->gk5e
->cksum_name
);
941 return PTR_ERR(hmac
);
947 err
= crypto_hash_init(&desc
);
951 /* Compute intermediate Kcrypt from session key */
952 for (i
= 0; i
< kctx
->gk5e
->keylength
; i
++)
953 Kcrypt
[i
] = kctx
->Ksess
[i
] ^ 0xf0;
955 err
= crypto_hash_setkey(hmac
, Kcrypt
, kctx
->gk5e
->keylength
);
959 sg_init_table(sg
, 1);
960 sg_set_buf(sg
, zeroconstant
, 4);
962 err
= crypto_hash_digest(&desc
, sg
, 4, Kcrypt
);
966 /* Compute final Kcrypt from the seqnum and intermediate Kcrypt */
967 err
= crypto_hash_setkey(hmac
, Kcrypt
, kctx
->gk5e
->keylength
);
971 seqnumarray
[0] = (unsigned char) ((seqnum
>> 24) & 0xff);
972 seqnumarray
[1] = (unsigned char) ((seqnum
>> 16) & 0xff);
973 seqnumarray
[2] = (unsigned char) ((seqnum
>> 8) & 0xff);
974 seqnumarray
[3] = (unsigned char) ((seqnum
>> 0) & 0xff);
976 sg_set_buf(sg
, seqnumarray
, 4);
978 err
= crypto_hash_digest(&desc
, sg
, 4, Kcrypt
);
982 err
= crypto_blkcipher_setkey(cipher
, Kcrypt
, kctx
->gk5e
->keylength
);
989 crypto_free_hash(hmac
);
990 dprintk("%s: returning %d\n", __func__
, err
);