2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "gssapi_locl.h"
40 OM_uint32 req_output_size
,
41 OM_uint32
* max_input_size
,
46 size_t len
, total_len
, padlength
;
47 padlength
= blocksize
- (req_output_size
% blocksize
);
48 len
= req_output_size
+ 8 + padlength
+ extrasize
;
49 gssapi_krb5_encap_length(len
, &len
, &total_len
);
50 *max_input_size
= (OM_uint32
)total_len
;
51 return GSS_S_COMPLETE
;
56 OM_uint32
* minor_status
,
57 const gss_ctx_id_t context_handle
,
60 OM_uint32 req_output_size
,
61 OM_uint32
* max_input_size
68 ret
= gss_krb5_getsomekey(context_handle
, &key
);
73 krb5_enctype_to_keytype (gssapi_krb5_context
, key
->keytype
, &keytype
);
77 ret
= sub_wrap_size(req_output_size
, max_input_size
, 8, 22);
80 ret
= sub_wrap_size(req_output_size
, max_input_size
, 8, 34);
83 *minor_status
= KRB5_PROG_ETYPE_NOSUPP
;
87 krb5_free_keyblock (gssapi_krb5_context
, key
);
93 (OM_uint32
* minor_status
,
94 const gss_ctx_id_t context_handle
,
97 const gss_buffer_t input_message_buffer
,
99 gss_buffer_t output_message_buffer
,
106 des_key_schedule schedule
;
111 size_t len
, total_len
, padlength
, datalen
;
113 padlength
= 8 - (input_message_buffer
->length
% 8);
114 datalen
= input_message_buffer
->length
+ padlength
+ 8;
116 gssapi_krb5_encap_length (len
, &len
, &total_len
);
118 output_message_buffer
->length
= total_len
;
119 output_message_buffer
->value
= malloc (total_len
);
120 if (output_message_buffer
->value
== NULL
)
121 return GSS_S_FAILURE
;
123 p
= gssapi_krb5_make_header(output_message_buffer
->value
,
125 "\x02\x01"); /* TOK_ID */
128 memcpy (p
, "\x00\x00", 2);
132 memcpy (p
, "\x00\x00", 2);
134 memcpy (p
, "\xff\xff", 2);
137 memcpy (p
, "\xff\xff", 2);
144 /* confounder + data + pad */
145 des_new_random_key((des_cblock
*)p
);
146 memcpy (p
+ 8, input_message_buffer
->value
,
147 input_message_buffer
->length
);
148 memset (p
+ 8 + input_message_buffer
->length
, padlength
, padlength
);
152 MD5_Update (&md5
, p
- 24, 8);
153 MD5_Update (&md5
, p
, datalen
);
154 MD5_Final (hash
, &md5
);
156 memset (&zero
, 0, sizeof(zero
));
157 memcpy (&deskey
, key
->keyvalue
.data
, sizeof(deskey
));
158 des_set_key (&deskey
, schedule
);
159 des_cbc_cksum ((void *)hash
, (void *)hash
, sizeof(hash
),
161 memcpy (p
- 8, hash
, 8);
163 /* sequence number */
164 krb5_auth_getlocalseqnumber (gssapi_krb5_context
,
165 context_handle
->auth_context
,
169 p
[0] = (seq_number
>> 0) & 0xFF;
170 p
[1] = (seq_number
>> 8) & 0xFF;
171 p
[2] = (seq_number
>> 16) & 0xFF;
172 p
[3] = (seq_number
>> 24) & 0xFF;
174 (context_handle
->more_flags
& LOCAL
) ? 0 : 0xFF,
177 des_set_key (&deskey
, schedule
);
178 des_cbc_encrypt ((void *)p
, (void *)p
, 8,
179 schedule
, (des_cblock
*)(p
+ 8), DES_ENCRYPT
);
181 krb5_auth_setlocalseqnumber (gssapi_krb5_context
,
182 context_handle
->auth_context
,
185 /* encrypt the data */
189 memcpy (&deskey
, key
->keyvalue
.data
, sizeof(deskey
));
191 for (i
= 0; i
< sizeof(deskey
); ++i
)
193 des_set_key (&deskey
, schedule
);
194 memset (&zero
, 0, sizeof(zero
));
195 des_cbc_encrypt ((void *)p
,
202 memset (deskey
, 0, sizeof(deskey
));
203 memset (schedule
, 0, sizeof(schedule
));
205 if(conf_state
!= NULL
)
206 *conf_state
= conf_req_flag
;
207 return GSS_S_COMPLETE
;
212 (OM_uint32
* minor_status
,
213 const gss_ctx_id_t context_handle
,
216 const gss_buffer_t input_message_buffer
,
218 gss_buffer_t output_message_buffer
,
225 size_t len
, total_len
, padlength
, datalen
;
231 padlength
= 8 - (input_message_buffer
->length
% 8);
232 datalen
= input_message_buffer
->length
+ padlength
+ 8;
234 gssapi_krb5_encap_length (len
, &len
, &total_len
);
236 output_message_buffer
->length
= total_len
;
237 output_message_buffer
->value
= malloc (total_len
);
238 if (output_message_buffer
->value
== NULL
)
239 return GSS_S_FAILURE
;
241 p
= gssapi_krb5_make_header(output_message_buffer
->value
,
243 "\x02\x01"); /* TOK_ID */
246 memcpy (p
, "\x04\x00", 2); /* HMAC SHA1 DES3-KD */
250 memcpy (p
, "\x02\x00", 2); /* DES3-KD */
252 memcpy (p
, "\xff\xff", 2);
255 memcpy (p
, "\xff\xff", 2);
258 /* calculate checksum (the above + confounder + data + pad) */
260 memcpy (p
+ 20, p
- 8, 8);
261 des_new_random_key((des_cblock
*)(p
+ 28));
262 memcpy (p
+ 28 + 8, input_message_buffer
->value
,
263 input_message_buffer
->length
);
264 memset (p
+ 28 + 8 + input_message_buffer
->length
, padlength
, padlength
);
266 ret
= krb5_crypto_init(gssapi_krb5_context
, key
, 0, &crypto
);
268 free (output_message_buffer
->value
);
270 return GSS_S_FAILURE
;
273 ret
= krb5_create_checksum (gssapi_krb5_context
,
279 krb5_crypto_destroy (gssapi_krb5_context
, crypto
);
281 free (output_message_buffer
->value
);
283 return GSS_S_FAILURE
;
286 /* zero out SND_SEQ + SGN_CKSUM in case */
289 memcpy (p
+ 8, cksum
.checksum
.data
, cksum
.checksum
.length
);
290 free_Checksum (&cksum
);
292 /* sequence number */
293 krb5_auth_getlocalseqnumber (gssapi_krb5_context
,
294 context_handle
->auth_context
,
297 seq
[0] = (seq_number
>> 0) & 0xFF;
298 seq
[1] = (seq_number
>> 8) & 0xFF;
299 seq
[2] = (seq_number
>> 16) & 0xFF;
300 seq
[3] = (seq_number
>> 24) & 0xFF;
302 (context_handle
->more_flags
& LOCAL
) ? 0 : 0xFF,
306 ret
= krb5_crypto_init(gssapi_krb5_context
, key
, ETYPE_DES3_CBC_NONE_IVEC
,
309 free (output_message_buffer
->value
);
311 return GSS_S_FAILURE
;
317 memcpy (&ivec
, p
+ 8, 8);
318 ret
= krb5_encrypt_ivec (gssapi_krb5_context
,
324 krb5_crypto_destroy (gssapi_krb5_context
, crypto
);
326 free (output_message_buffer
->value
);
328 return GSS_S_FAILURE
;
331 assert (encdata
.length
== 8);
333 memcpy (p
, encdata
.data
, encdata
.length
);
334 krb5_data_free (&encdata
);
336 krb5_auth_setlocalseqnumber (gssapi_krb5_context
,
337 context_handle
->auth_context
,
340 /* encrypt the data */
346 ret
= krb5_crypto_init(gssapi_krb5_context
, key
,
347 ETYPE_DES3_CBC_NONE
, &crypto
);
349 free (output_message_buffer
->value
);
351 return GSS_S_FAILURE
;
353 ret
= krb5_encrypt(gssapi_krb5_context
, crypto
, KRB5_KU_USAGE_SEAL
,
355 krb5_crypto_destroy(gssapi_krb5_context
, crypto
);
357 free (output_message_buffer
->value
);
359 return GSS_S_FAILURE
;
361 assert (tmp
.length
== datalen
);
363 memcpy (p
, tmp
.data
, datalen
);
364 krb5_data_free(&tmp
);
366 if(conf_state
!= NULL
)
367 *conf_state
= conf_req_flag
;
368 return GSS_S_COMPLETE
;
372 (OM_uint32
* minor_status
,
373 const gss_ctx_id_t context_handle
,
376 const gss_buffer_t input_message_buffer
,
378 gss_buffer_t output_message_buffer
383 krb5_keytype keytype
;
385 ret
= gss_krb5_getsomekey(context_handle
, &key
);
388 return GSS_S_FAILURE
;
390 krb5_enctype_to_keytype (gssapi_krb5_context
, key
->keytype
, &keytype
);
394 ret
= wrap_des (minor_status
, context_handle
, conf_req_flag
,
395 qop_req
, input_message_buffer
, conf_state
,
396 output_message_buffer
, key
);
399 ret
= wrap_des3 (minor_status
, context_handle
, conf_req_flag
,
400 qop_req
, input_message_buffer
, conf_state
,
401 output_message_buffer
, key
);
404 *minor_status
= KRB5_PROG_ETYPE_NOSUPP
;
408 krb5_free_keyblock (gssapi_krb5_context
, key
);