xref: /freebsd/crypto/krb5/src/lib/gssapi/krb5/util_seqnum.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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
33 kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
34     krb5_context context;
35     krb5_key key;
36     int direction;
37     krb5_ui_4 seqnum;
38     unsigned char *cksum;
39     unsigned char *buf;
40 {
41     unsigned char plain[8];
42 
43     plain[4] = direction;
44     plain[5] = direction;
45     plain[6] = direction;
46     plain[7] = direction;
47     if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
48         key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
49         /* Yes, Microsoft used big-endian sequence number.*/
50         store_32_be(seqnum, plain);
51         return kg_arcfour_docrypt (&key->keyblock, 0,
52                                    cksum, 8,
53                                    &plain[0], 8,
54                                    buf);
55 
56     }
57 
58     store_32_le(seqnum, plain);
59     return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
60 }
61 
62 krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
63     krb5_context context;
64     krb5_key key;
65     unsigned char *cksum;
66     unsigned char *buf;
67     int *direction;
68     krb5_ui_4 *seqnum;
69 {
70     krb5_error_code code;
71     unsigned char plain[8];
72 
73     if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
74         key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
75         code = kg_arcfour_docrypt (&key->keyblock, 0,
76                                    cksum, 8,
77                                    buf, 8,
78                                    plain);
79     } else {
80         code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8);
81     }
82     if (code)
83         return(code);
84 
85     if ((plain[4] != plain[5]) ||
86         (plain[4] != plain[6]) ||
87         (plain[4] != plain[7]))
88         return((krb5_error_code) KG_BAD_SEQ);
89 
90     *direction = plain[4];
91     if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC ||
92         key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
93         *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24));
94     } else {
95         *seqnum = ((plain[0]) |
96                    (plain[1]<<8) |
97                    (plain[2]<<16) |
98                    (plain[3]<<24));
99     }
100 
101     return(0);
102 }
103