xref: /freebsd/crypto/krb5/src/lib/gssapi/krb5/util_seqnum.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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