1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright 2001, 2009 by the Massachusetts Institute of Technology.
4 * Copyright 1993 by OpenVision Technologies, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appears in all copies and
9 * that both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of OpenVision not be used
11 * in advertising or publicity pertaining to distribution of the software
12 * without specific, written prior permission. OpenVision makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
15 *
16 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 #include "gssapiP_krb5.h"
26 #include "k5-int.h"
27
28 /*
29 * $Id$
30 */
31
32 krb5_error_code
kg_make_seq_num(krb5_context context,krb5_key key,int direction,krb5_ui_4 seqnum,unsigned char * cksum,unsigned char * buf)33 kg_make_seq_num(krb5_context context, krb5_key key, int direction,
34 krb5_ui_4 seqnum, unsigned char *cksum, unsigned char *buf)
35 {
36 unsigned char plain[8];
37
38 plain[4] = direction;
39 plain[5] = direction;
40 plain[6] = direction;
41 plain[7] = direction;
42 if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
43 key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
44 /* Yes, Microsoft used big-endian sequence number.*/
45 store_32_be(seqnum, plain);
46 return kg_arcfour_docrypt (&key->keyblock, 0,
47 cksum, 8,
48 &plain[0], 8,
49 buf);
50
51 }
52
53 store_32_le(seqnum, plain);
54 return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
55 }
56
57 krb5_error_code
kg_get_seq_num(krb5_context context,krb5_key key,const uint8_t * cksum,const uint8_t * buf,int * direction,krb5_ui_4 * seqnum)58 kg_get_seq_num(krb5_context context, krb5_key key, const uint8_t *cksum,
59 const uint8_t *buf, int *direction, krb5_ui_4 *seqnum)
60 {
61 krb5_error_code code;
62 unsigned char plain[8];
63
64 if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
65 key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
66 code = kg_arcfour_docrypt (&key->keyblock, 0,
67 cksum, 8,
68 buf, 8,
69 plain);
70 } else {
71 code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8);
72 }
73 if (code)
74 return(code);
75
76 if ((plain[4] != plain[5]) ||
77 (plain[4] != plain[6]) ||
78 (plain[4] != plain[7]))
79 return((krb5_error_code) KG_BAD_SEQ);
80
81 *direction = plain[4];
82 if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
83 key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
84 *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24));
85 } else {
86 *seqnum = ((plain[0]) |
87 (plain[1]<<8) |
88 (plain[2]<<16) |
89 (plain[3]<<24));
90 }
91
92 return(0);
93 }
94