Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/sunrpc/auth_gss/gss_krb5_unseal.c
15112 views
1
/*
2
* linux/net/sunrpc/gss_krb5_unseal.c
3
*
4
* Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c
5
*
6
* Copyright (c) 2000-2008 The Regents of the University of Michigan.
7
* All rights reserved.
8
*
9
* Andy Adamson <[email protected]>
10
*/
11
12
/*
13
* Copyright 1993 by OpenVision Technologies, Inc.
14
*
15
* Permission to use, copy, modify, distribute, and sell this software
16
* and its documentation for any purpose is hereby granted without fee,
17
* provided that the above copyright notice appears in all copies and
18
* that both that copyright notice and this permission notice appear in
19
* supporting documentation, and that the name of OpenVision not be used
20
* in advertising or publicity pertaining to distribution of the software
21
* without specific, written prior permission. OpenVision makes no
22
* representations about the suitability of this software for any
23
* purpose. It is provided "as is" without express or implied warranty.
24
*
25
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
27
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
28
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
29
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
30
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
31
* PERFORMANCE OF THIS SOFTWARE.
32
*/
33
34
/*
35
* Copyright (C) 1998 by the FundsXpress, INC.
36
*
37
* All rights reserved.
38
*
39
* Export of this software from the United States of America may require
40
* a specific license from the United States Government. It is the
41
* responsibility of any person or organization contemplating export to
42
* obtain such a license before exporting.
43
*
44
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
45
* distribute this software and its documentation for any purpose and
46
* without fee is hereby granted, provided that the above copyright
47
* notice appear in all copies and that both that copyright notice and
48
* this permission notice appear in supporting documentation, and that
49
* the name of FundsXpress. not be used in advertising or publicity pertaining
50
* to distribution of the software without specific, written prior
51
* permission. FundsXpress makes no representations about the suitability of
52
* this software for any purpose. It is provided "as is" without express
53
* or implied warranty.
54
*
55
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
56
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
58
*/
59
60
#include <linux/types.h>
61
#include <linux/jiffies.h>
62
#include <linux/sunrpc/gss_krb5.h>
63
#include <linux/crypto.h>
64
65
#ifdef RPC_DEBUG
66
# define RPCDBG_FACILITY RPCDBG_AUTH
67
#endif
68
69
70
/* read_token is a mic token, and message_buffer is the data that the mic was
71
* supposedly taken over. */
72
73
static u32
74
gss_verify_mic_v1(struct krb5_ctx *ctx,
75
struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
76
{
77
int signalg;
78
int sealalg;
79
char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
80
struct xdr_netobj md5cksum = {.len = sizeof(cksumdata),
81
.data = cksumdata};
82
s32 now;
83
int direction;
84
u32 seqnum;
85
unsigned char *ptr = (unsigned char *)read_token->data;
86
int bodysize;
87
u8 *cksumkey;
88
89
dprintk("RPC: krb5_read_token\n");
90
91
if (g_verify_token_header(&ctx->mech_used, &bodysize, &ptr,
92
read_token->len))
93
return GSS_S_DEFECTIVE_TOKEN;
94
95
if ((ptr[0] != ((KG_TOK_MIC_MSG >> 8) & 0xff)) ||
96
(ptr[1] != (KG_TOK_MIC_MSG & 0xff)))
97
return GSS_S_DEFECTIVE_TOKEN;
98
99
/* XXX sanity-check bodysize?? */
100
101
signalg = ptr[2] + (ptr[3] << 8);
102
if (signalg != ctx->gk5e->signalg)
103
return GSS_S_DEFECTIVE_TOKEN;
104
105
sealalg = ptr[4] + (ptr[5] << 8);
106
if (sealalg != SEAL_ALG_NONE)
107
return GSS_S_DEFECTIVE_TOKEN;
108
109
if ((ptr[6] != 0xff) || (ptr[7] != 0xff))
110
return GSS_S_DEFECTIVE_TOKEN;
111
112
if (ctx->gk5e->keyed_cksum)
113
cksumkey = ctx->cksum;
114
else
115
cksumkey = NULL;
116
117
if (make_checksum(ctx, ptr, 8, message_buffer, 0,
118
cksumkey, KG_USAGE_SIGN, &md5cksum))
119
return GSS_S_FAILURE;
120
121
if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
122
ctx->gk5e->cksumlength))
123
return GSS_S_BAD_SIG;
124
125
/* it got through unscathed. Make sure the context is unexpired */
126
127
now = get_seconds();
128
129
if (now > ctx->endtime)
130
return GSS_S_CONTEXT_EXPIRED;
131
132
/* do sequencing checks */
133
134
if (krb5_get_seq_num(ctx, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8,
135
&direction, &seqnum))
136
return GSS_S_FAILURE;
137
138
if ((ctx->initiate && direction != 0xff) ||
139
(!ctx->initiate && direction != 0))
140
return GSS_S_BAD_SIG;
141
142
return GSS_S_COMPLETE;
143
}
144
145
static u32
146
gss_verify_mic_v2(struct krb5_ctx *ctx,
147
struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
148
{
149
char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
150
struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
151
.data = cksumdata};
152
s32 now;
153
u64 seqnum;
154
u8 *ptr = read_token->data;
155
u8 *cksumkey;
156
u8 flags;
157
int i;
158
unsigned int cksum_usage;
159
160
dprintk("RPC: %s\n", __func__);
161
162
if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_MIC)
163
return GSS_S_DEFECTIVE_TOKEN;
164
165
flags = ptr[2];
166
if ((!ctx->initiate && (flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)) ||
167
(ctx->initiate && !(flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)))
168
return GSS_S_BAD_SIG;
169
170
if (flags & KG2_TOKEN_FLAG_SEALED) {
171
dprintk("%s: token has unexpected sealed flag\n", __func__);
172
return GSS_S_FAILURE;
173
}
174
175
for (i = 3; i < 8; i++)
176
if (ptr[i] != 0xff)
177
return GSS_S_DEFECTIVE_TOKEN;
178
179
if (ctx->initiate) {
180
cksumkey = ctx->acceptor_sign;
181
cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
182
} else {
183
cksumkey = ctx->initiator_sign;
184
cksum_usage = KG_USAGE_INITIATOR_SIGN;
185
}
186
187
if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0,
188
cksumkey, cksum_usage, &cksumobj))
189
return GSS_S_FAILURE;
190
191
if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN,
192
ctx->gk5e->cksumlength))
193
return GSS_S_BAD_SIG;
194
195
/* it got through unscathed. Make sure the context is unexpired */
196
now = get_seconds();
197
if (now > ctx->endtime)
198
return GSS_S_CONTEXT_EXPIRED;
199
200
/* do sequencing checks */
201
202
seqnum = be64_to_cpup((__be64 *)ptr + 8);
203
204
return GSS_S_COMPLETE;
205
}
206
207
u32
208
gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
209
struct xdr_buf *message_buffer,
210
struct xdr_netobj *read_token)
211
{
212
struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
213
214
switch (ctx->enctype) {
215
default:
216
BUG();
217
case ENCTYPE_DES_CBC_RAW:
218
case ENCTYPE_DES3_CBC_RAW:
219
case ENCTYPE_ARCFOUR_HMAC:
220
return gss_verify_mic_v1(ctx, message_buffer, read_token);
221
case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
222
case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
223
return gss_verify_mic_v2(ctx, message_buffer, read_token);
224
}
225
}
226
227
228