1 /* $NetBSD: unwrap.c,v 1.1.1.1 2011/04/13 18:14:45 elric Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "gsskrb5_locl.h" 37 38 #ifdef HEIM_WEAK_CRYPTO 39 40 static OM_uint32 41 unwrap_des 42 (OM_uint32 * minor_status, 43 const gsskrb5_ctx context_handle, 44 const gss_buffer_t input_message_buffer, 45 gss_buffer_t output_message_buffer, 46 int * conf_state, 47 gss_qop_t * qop_state, 48 krb5_keyblock *key 49 ) 50 { 51 u_char *p, *seq; 52 size_t len; 53 EVP_MD_CTX *md5; 54 u_char hash[16]; 55 EVP_CIPHER_CTX des_ctx; 56 DES_key_schedule schedule; 57 DES_cblock deskey; 58 DES_cblock zero; 59 int i; 60 uint32_t seq_number; 61 size_t padlength; 62 OM_uint32 ret; 63 int cstate; 64 int cmp; 65 int token_len; 66 67 if (IS_DCE_STYLE(context_handle)) { 68 token_len = 22 + 8 + 15; /* 45 */ 69 } else { 70 token_len = input_message_buffer->length; 71 } 72 73 p = input_message_buffer->value; 74 ret = _gsskrb5_verify_header (&p, 75 token_len, 76 "\x02\x01", 77 GSS_KRB5_MECHANISM); 78 if (ret) 79 return ret; 80 81 if (memcmp (p, "\x00\x00", 2) != 0) 82 return GSS_S_BAD_SIG; 83 p += 2; 84 if (memcmp (p, "\x00\x00", 2) == 0) { 85 cstate = 1; 86 } else if (memcmp (p, "\xFF\xFF", 2) == 0) { 87 cstate = 0; 88 } else 89 return GSS_S_BAD_MIC; 90 p += 2; 91 if(conf_state != NULL) 92 *conf_state = cstate; 93 if (memcmp (p, "\xff\xff", 2) != 0) 94 return GSS_S_DEFECTIVE_TOKEN; 95 p += 2; 96 p += 16; 97 98 len = p - (u_char *)input_message_buffer->value; 99 100 if(cstate) { 101 /* decrypt data */ 102 memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); 103 104 for (i = 0; i < sizeof(deskey); ++i) 105 deskey[i] ^= 0xf0; 106 107 108 EVP_CIPHER_CTX_init(&des_ctx); 109 EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0); 110 EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len); 111 EVP_CIPHER_CTX_cleanup(&des_ctx); 112 113 memset (&schedule, 0, sizeof(schedule)); 114 } 115 116 if (IS_DCE_STYLE(context_handle)) { 117 padlength = 0; 118 } else { 119 /* check pad */ 120 ret = _gssapi_verify_pad(input_message_buffer, 121 input_message_buffer->length - len, 122 &padlength); 123 if (ret) 124 return ret; 125 } 126 127 md5 = EVP_MD_CTX_create(); 128 EVP_DigestInit_ex(md5, EVP_md5(), NULL); 129 EVP_DigestUpdate(md5, p - 24, 8); 130 EVP_DigestUpdate(md5, p, input_message_buffer->length - len); 131 EVP_DigestFinal_ex(md5, hash, NULL); 132 EVP_MD_CTX_destroy(md5); 133 134 memset (&zero, 0, sizeof(zero)); 135 memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); 136 DES_set_key_unchecked (&deskey, &schedule); 137 DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), 138 &schedule, &zero); 139 if (ct_memcmp (p - 8, hash, 8) != 0) 140 return GSS_S_BAD_MIC; 141 142 /* verify sequence number */ 143 144 HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 145 146 p -= 16; 147 148 EVP_CIPHER_CTX_init(&des_ctx); 149 EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0); 150 EVP_Cipher(&des_ctx, p, p, 8); 151 EVP_CIPHER_CTX_cleanup(&des_ctx); 152 153 memset (deskey, 0, sizeof(deskey)); 154 memset (&schedule, 0, sizeof(schedule)); 155 156 seq = p; 157 _gsskrb5_decode_om_uint32(seq, &seq_number); 158 159 if (context_handle->more_flags & LOCAL) 160 cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4); 161 else 162 cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4); 163 164 if (cmp != 0) { 165 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 166 return GSS_S_BAD_MIC; 167 } 168 169 ret = _gssapi_msg_order_check(context_handle->order, seq_number); 170 if (ret) { 171 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 172 return ret; 173 } 174 175 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 176 177 /* copy out data */ 178 179 output_message_buffer->length = input_message_buffer->length 180 - len - padlength - 8; 181 output_message_buffer->value = malloc(output_message_buffer->length); 182 if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) 183 return GSS_S_FAILURE; 184 memcpy (output_message_buffer->value, 185 p + 24, 186 output_message_buffer->length); 187 return GSS_S_COMPLETE; 188 } 189 #endif 190 191 static OM_uint32 192 unwrap_des3 193 (OM_uint32 * minor_status, 194 const gsskrb5_ctx context_handle, 195 krb5_context context, 196 const gss_buffer_t input_message_buffer, 197 gss_buffer_t output_message_buffer, 198 int * conf_state, 199 gss_qop_t * qop_state, 200 krb5_keyblock *key 201 ) 202 { 203 u_char *p; 204 size_t len; 205 u_char *seq; 206 krb5_data seq_data; 207 u_char cksum[20]; 208 uint32_t seq_number; 209 size_t padlength; 210 OM_uint32 ret; 211 int cstate; 212 krb5_crypto crypto; 213 Checksum csum; 214 int cmp; 215 int token_len; 216 217 if (IS_DCE_STYLE(context_handle)) { 218 token_len = 34 + 8 + 15; /* 57 */ 219 } else { 220 token_len = input_message_buffer->length; 221 } 222 223 p = input_message_buffer->value; 224 ret = _gsskrb5_verify_header (&p, 225 token_len, 226 "\x02\x01", 227 GSS_KRB5_MECHANISM); 228 if (ret) 229 return ret; 230 231 if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ 232 return GSS_S_BAD_SIG; 233 p += 2; 234 if (ct_memcmp (p, "\x02\x00", 2) == 0) { 235 cstate = 1; 236 } else if (ct_memcmp (p, "\xff\xff", 2) == 0) { 237 cstate = 0; 238 } else 239 return GSS_S_BAD_MIC; 240 p += 2; 241 if(conf_state != NULL) 242 *conf_state = cstate; 243 if (ct_memcmp (p, "\xff\xff", 2) != 0) 244 return GSS_S_DEFECTIVE_TOKEN; 245 p += 2; 246 p += 28; 247 248 len = p - (u_char *)input_message_buffer->value; 249 250 if(cstate) { 251 /* decrypt data */ 252 krb5_data tmp; 253 254 ret = krb5_crypto_init(context, key, 255 ETYPE_DES3_CBC_NONE, &crypto); 256 if (ret) { 257 *minor_status = ret; 258 return GSS_S_FAILURE; 259 } 260 ret = krb5_decrypt(context, crypto, KRB5_KU_USAGE_SEAL, 261 p, input_message_buffer->length - len, &tmp); 262 krb5_crypto_destroy(context, crypto); 263 if (ret) { 264 *minor_status = ret; 265 return GSS_S_FAILURE; 266 } 267 assert (tmp.length == input_message_buffer->length - len); 268 269 memcpy (p, tmp.data, tmp.length); 270 krb5_data_free(&tmp); 271 } 272 273 if (IS_DCE_STYLE(context_handle)) { 274 padlength = 0; 275 } else { 276 /* check pad */ 277 ret = _gssapi_verify_pad(input_message_buffer, 278 input_message_buffer->length - len, 279 &padlength); 280 if (ret) 281 return ret; 282 } 283 284 /* verify sequence number */ 285 286 HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 287 288 p -= 28; 289 290 ret = krb5_crypto_init(context, key, 291 ETYPE_DES3_CBC_NONE, &crypto); 292 if (ret) { 293 *minor_status = ret; 294 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 295 return GSS_S_FAILURE; 296 } 297 { 298 DES_cblock ivec; 299 300 memcpy(&ivec, p + 8, 8); 301 ret = krb5_decrypt_ivec (context, 302 crypto, 303 KRB5_KU_USAGE_SEQ, 304 p, 8, &seq_data, 305 &ivec); 306 } 307 krb5_crypto_destroy (context, crypto); 308 if (ret) { 309 *minor_status = ret; 310 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 311 return GSS_S_FAILURE; 312 } 313 if (seq_data.length != 8) { 314 krb5_data_free (&seq_data); 315 *minor_status = 0; 316 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 317 return GSS_S_BAD_MIC; 318 } 319 320 seq = seq_data.data; 321 _gsskrb5_decode_om_uint32(seq, &seq_number); 322 323 if (context_handle->more_flags & LOCAL) 324 cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4); 325 else 326 cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4); 327 328 krb5_data_free (&seq_data); 329 if (cmp != 0) { 330 *minor_status = 0; 331 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 332 return GSS_S_BAD_MIC; 333 } 334 335 ret = _gssapi_msg_order_check(context_handle->order, seq_number); 336 if (ret) { 337 *minor_status = 0; 338 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 339 return ret; 340 } 341 342 HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 343 344 /* verify checksum */ 345 346 memcpy (cksum, p + 8, 20); 347 348 memcpy (p + 20, p - 8, 8); 349 350 csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3; 351 csum.checksum.length = 20; 352 csum.checksum.data = cksum; 353 354 ret = krb5_crypto_init(context, key, 0, &crypto); 355 if (ret) { 356 *minor_status = ret; 357 return GSS_S_FAILURE; 358 } 359 360 ret = krb5_verify_checksum (context, crypto, 361 KRB5_KU_USAGE_SIGN, 362 p + 20, 363 input_message_buffer->length - len + 8, 364 &csum); 365 krb5_crypto_destroy (context, crypto); 366 if (ret) { 367 *minor_status = ret; 368 return GSS_S_FAILURE; 369 } 370 371 /* copy out data */ 372 373 output_message_buffer->length = input_message_buffer->length 374 - len - padlength - 8; 375 output_message_buffer->value = malloc(output_message_buffer->length); 376 if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) 377 return GSS_S_FAILURE; 378 memcpy (output_message_buffer->value, 379 p + 36, 380 output_message_buffer->length); 381 return GSS_S_COMPLETE; 382 } 383 384 OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap 385 (OM_uint32 * minor_status, 386 const gss_ctx_id_t context_handle, 387 const gss_buffer_t input_message_buffer, 388 gss_buffer_t output_message_buffer, 389 int * conf_state, 390 gss_qop_t * qop_state 391 ) 392 { 393 krb5_keyblock *key; 394 krb5_context context; 395 OM_uint32 ret; 396 krb5_keytype keytype; 397 gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; 398 399 output_message_buffer->value = NULL; 400 output_message_buffer->length = 0; 401 if (qop_state != NULL) 402 *qop_state = GSS_C_QOP_DEFAULT; 403 404 GSSAPI_KRB5_INIT (&context); 405 406 if (ctx->more_flags & IS_CFX) 407 return _gssapi_unwrap_cfx (minor_status, ctx, context, 408 input_message_buffer, output_message_buffer, 409 conf_state, qop_state); 410 411 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 412 ret = _gsskrb5i_get_token_key(ctx, context, &key); 413 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 414 if (ret) { 415 *minor_status = ret; 416 return GSS_S_FAILURE; 417 } 418 krb5_enctype_to_keytype (context, key->keytype, &keytype); 419 420 *minor_status = 0; 421 422 switch (keytype) { 423 case KEYTYPE_DES : 424 #ifdef HEIM_WEAK_CRYPTO 425 ret = unwrap_des (minor_status, ctx, 426 input_message_buffer, output_message_buffer, 427 conf_state, qop_state, key); 428 #else 429 ret = GSS_S_FAILURE; 430 #endif 431 break; 432 case KEYTYPE_DES3 : 433 ret = unwrap_des3 (minor_status, ctx, context, 434 input_message_buffer, output_message_buffer, 435 conf_state, qop_state, key); 436 break; 437 case KEYTYPE_ARCFOUR: 438 case KEYTYPE_ARCFOUR_56: 439 ret = _gssapi_unwrap_arcfour (minor_status, ctx, context, 440 input_message_buffer, output_message_buffer, 441 conf_state, qop_state, key); 442 break; 443 default : 444 abort(); 445 break; 446 } 447 krb5_free_keyblock (context, key); 448 return ret; 449 } 450