1 1.5 christos /* $NetBSD: arcfour.c,v 1.6 2023/06/19 21:41:43 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 2003 - 2006 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "gsskrb5_locl.h" 37 1.1 elric 38 1.1 elric /* 39 1.1 elric * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt 40 1.1 elric * 41 1.1 elric * The arcfour message have the following formats: 42 1.1 elric * 43 1.1 elric * MIC token 44 1.1 elric * TOK_ID[2] = 01 01 45 1.1 elric * SGN_ALG[2] = 11 00 46 1.1 elric * Filler[4] 47 1.1 elric * SND_SEQ[8] 48 1.1 elric * SGN_CKSUM[8] 49 1.1 elric * 50 1.1 elric * WRAP token 51 1.1 elric * TOK_ID[2] = 02 01 52 1.1 elric * SGN_ALG[2]; 53 1.1 elric * SEAL_ALG[2] 54 1.1 elric * Filler[2] 55 1.1 elric * SND_SEQ[2] 56 1.1 elric * SGN_CKSUM[8] 57 1.1 elric * Confounder[8] 58 1.1 elric */ 59 1.1 elric 60 1.1 elric /* 61 1.1 elric * WRAP in DCE-style have a fixed size header, the oid and length over 62 1.1 elric * the WRAP header is a total of 63 1.1 elric * GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE + 64 1.1 elric * GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead, 65 1.1 elric * remember the 2 bytes from APPL [0] SEQ). 66 1.1 elric */ 67 1.1 elric 68 1.1 elric #define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32 69 1.1 elric #define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13 70 1.1 elric 71 1.1 elric 72 1.1 elric static krb5_error_code 73 1.1 elric arcfour_mic_key(krb5_context context, krb5_keyblock *key, 74 1.2 christos const void *cksum_data, size_t cksum_size, 75 1.1 elric void *key6_data, size_t key6_size) 76 1.1 elric { 77 1.1 elric krb5_error_code ret; 78 1.1 elric 79 1.1 elric Checksum cksum_k5; 80 1.1 elric krb5_keyblock key5; 81 1.1 elric char k5_data[16]; 82 1.1 elric 83 1.1 elric Checksum cksum_k6; 84 1.1 elric 85 1.1 elric char T[4]; 86 1.1 elric 87 1.1 elric memset(T, 0, 4); 88 1.1 elric cksum_k5.checksum.data = k5_data; 89 1.1 elric cksum_k5.checksum.length = sizeof(k5_data); 90 1.1 elric 91 1.2 christos if (key->keytype == KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56) { 92 1.1 elric char L40[14] = "fortybits"; 93 1.1 elric 94 1.1 elric memcpy(L40 + 10, T, sizeof(T)); 95 1.1 elric ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5, 96 1.1 elric L40, 14, 0, key, &cksum_k5); 97 1.1 elric memset(&k5_data[7], 0xAB, 9); 98 1.1 elric } else { 99 1.1 elric ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5, 100 1.1 elric T, 4, 0, key, &cksum_k5); 101 1.1 elric } 102 1.1 elric if (ret) 103 1.1 elric return ret; 104 1.1 elric 105 1.2 christos key5.keytype = KRB5_ENCTYPE_ARCFOUR_HMAC_MD5; 106 1.1 elric key5.keyvalue = cksum_k5.checksum; 107 1.1 elric 108 1.1 elric cksum_k6.checksum.data = key6_data; 109 1.1 elric cksum_k6.checksum.length = key6_size; 110 1.1 elric 111 1.1 elric return krb5_hmac(context, CKSUMTYPE_RSA_MD5, 112 1.1 elric cksum_data, cksum_size, 0, &key5, &cksum_k6); 113 1.1 elric } 114 1.1 elric 115 1.1 elric 116 1.1 elric static krb5_error_code 117 1.2 christos arcfour_mic_cksum_iov(krb5_context context, 118 1.2 christos krb5_keyblock *key, unsigned usage, 119 1.2 christos u_char *sgn_cksum, size_t sgn_cksum_sz, 120 1.2 christos const u_char *v1, size_t l1, 121 1.2 christos const void *v2, size_t l2, 122 1.2 christos const gss_iov_buffer_desc *iov, 123 1.2 christos int iov_count, 124 1.2 christos const gss_iov_buffer_desc *padding) 125 1.1 elric { 126 1.1 elric Checksum CKSUM; 127 1.1 elric u_char *ptr; 128 1.1 elric size_t len; 129 1.2 christos size_t ofs = 0; 130 1.2 christos int i; 131 1.1 elric krb5_crypto crypto; 132 1.1 elric krb5_error_code ret; 133 1.1 elric 134 1.1 elric assert(sgn_cksum_sz == 8); 135 1.1 elric 136 1.2 christos len = l1 + l2; 137 1.2 christos 138 1.2 christos for (i=0; i < iov_count; i++) { 139 1.2 christos switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { 140 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 141 1.2 christos case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: 142 1.2 christos break; 143 1.2 christos default: 144 1.2 christos continue; 145 1.2 christos } 146 1.2 christos 147 1.2 christos len += iov[i].buffer.length; 148 1.2 christos } 149 1.2 christos 150 1.2 christos if (padding) { 151 1.2 christos len += padding->buffer.length; 152 1.2 christos } 153 1.1 elric 154 1.1 elric ptr = malloc(len); 155 1.1 elric if (ptr == NULL) 156 1.1 elric return ENOMEM; 157 1.1 elric 158 1.2 christos memcpy(ptr + ofs, v1, l1); 159 1.2 christos ofs += l1; 160 1.2 christos memcpy(ptr + ofs, v2, l2); 161 1.2 christos ofs += l2; 162 1.2 christos 163 1.2 christos for (i=0; i < iov_count; i++) { 164 1.2 christos switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { 165 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 166 1.2 christos case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: 167 1.2 christos break; 168 1.2 christos default: 169 1.2 christos continue; 170 1.2 christos } 171 1.2 christos 172 1.2 christos memcpy(ptr + ofs, 173 1.2 christos iov[i].buffer.value, 174 1.2 christos iov[i].buffer.length); 175 1.2 christos ofs += iov[i].buffer.length; 176 1.2 christos } 177 1.2 christos 178 1.2 christos if (padding) { 179 1.2 christos memcpy(ptr + ofs, 180 1.2 christos padding->buffer.value, 181 1.2 christos padding->buffer.length); 182 1.6 christos /* ofs += padding->buffer.length; */ 183 1.2 christos } 184 1.1 elric 185 1.1 elric ret = krb5_crypto_init(context, key, 0, &crypto); 186 1.1 elric if (ret) { 187 1.1 elric free(ptr); 188 1.1 elric return ret; 189 1.1 elric } 190 1.1 elric 191 1.1 elric ret = krb5_create_checksum(context, 192 1.1 elric crypto, 193 1.1 elric usage, 194 1.1 elric 0, 195 1.1 elric ptr, len, 196 1.1 elric &CKSUM); 197 1.2 christos memset(ptr, 0, len); 198 1.1 elric free(ptr); 199 1.1 elric if (ret == 0) { 200 1.1 elric memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz); 201 1.1 elric free_Checksum(&CKSUM); 202 1.1 elric } 203 1.1 elric krb5_crypto_destroy(context, crypto); 204 1.1 elric 205 1.1 elric return ret; 206 1.1 elric } 207 1.1 elric 208 1.2 christos static krb5_error_code 209 1.2 christos arcfour_mic_cksum(krb5_context context, 210 1.2 christos krb5_keyblock *key, unsigned usage, 211 1.2 christos u_char *sgn_cksum, size_t sgn_cksum_sz, 212 1.2 christos const u_char *v1, size_t l1, 213 1.2 christos const void *v2, size_t l2, 214 1.2 christos const void *v3, size_t l3) 215 1.2 christos { 216 1.2 christos gss_iov_buffer_desc iov; 217 1.2 christos 218 1.2 christos iov.type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; 219 1.2 christos iov.buffer.value = rk_UNCONST(v3); 220 1.2 christos iov.buffer.length = l3; 221 1.2 christos 222 1.2 christos return arcfour_mic_cksum_iov(context, key, usage, 223 1.2 christos sgn_cksum, sgn_cksum_sz, 224 1.2 christos v1, l1, v2, l2, 225 1.2 christos &iov, 1, NULL); 226 1.2 christos } 227 1.2 christos 228 1.1 elric 229 1.1 elric OM_uint32 230 1.1 elric _gssapi_get_mic_arcfour(OM_uint32 * minor_status, 231 1.1 elric const gsskrb5_ctx context_handle, 232 1.1 elric krb5_context context, 233 1.1 elric gss_qop_t qop_req, 234 1.1 elric const gss_buffer_t message_buffer, 235 1.1 elric gss_buffer_t message_token, 236 1.1 elric krb5_keyblock *key) 237 1.1 elric { 238 1.1 elric krb5_error_code ret; 239 1.1 elric int32_t seq_number; 240 1.1 elric size_t len, total_len; 241 1.1 elric u_char k6_data[16], *p0, *p; 242 1.3 christos EVP_CIPHER_CTX *rc4_key; 243 1.1 elric 244 1.1 elric _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); 245 1.1 elric 246 1.1 elric message_token->length = total_len; 247 1.1 elric message_token->value = malloc (total_len); 248 1.1 elric if (message_token->value == NULL) { 249 1.1 elric *minor_status = ENOMEM; 250 1.1 elric return GSS_S_FAILURE; 251 1.1 elric } 252 1.1 elric 253 1.1 elric p0 = _gssapi_make_mech_header(message_token->value, 254 1.1 elric len, 255 1.1 elric GSS_KRB5_MECHANISM); 256 1.1 elric p = p0; 257 1.1 elric 258 1.1 elric *p++ = 0x01; /* TOK_ID */ 259 1.1 elric *p++ = 0x01; 260 1.1 elric *p++ = 0x11; /* SGN_ALG */ 261 1.1 elric *p++ = 0x00; 262 1.1 elric *p++ = 0xff; /* Filler */ 263 1.1 elric *p++ = 0xff; 264 1.1 elric *p++ = 0xff; 265 1.1 elric *p++ = 0xff; 266 1.1 elric 267 1.1 elric p = NULL; 268 1.1 elric 269 1.1 elric ret = arcfour_mic_cksum(context, 270 1.1 elric key, KRB5_KU_USAGE_SIGN, 271 1.1 elric p0 + 16, 8, /* SGN_CKSUM */ 272 1.1 elric p0, 8, /* TOK_ID, SGN_ALG, Filer */ 273 1.1 elric message_buffer->value, message_buffer->length, 274 1.1 elric NULL, 0); 275 1.1 elric if (ret) { 276 1.1 elric _gsskrb5_release_buffer(minor_status, message_token); 277 1.1 elric *minor_status = ret; 278 1.1 elric return GSS_S_FAILURE; 279 1.1 elric } 280 1.1 elric 281 1.1 elric ret = arcfour_mic_key(context, key, 282 1.1 elric p0 + 16, 8, /* SGN_CKSUM */ 283 1.1 elric k6_data, sizeof(k6_data)); 284 1.1 elric if (ret) { 285 1.1 elric _gsskrb5_release_buffer(minor_status, message_token); 286 1.1 elric *minor_status = ret; 287 1.1 elric return GSS_S_FAILURE; 288 1.1 elric } 289 1.1 elric 290 1.1 elric HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 291 1.1 elric krb5_auth_con_getlocalseqnumber (context, 292 1.1 elric context_handle->auth_context, 293 1.1 elric &seq_number); 294 1.1 elric p = p0 + 8; /* SND_SEQ */ 295 1.1 elric _gsskrb5_encode_be_om_uint32(seq_number, p); 296 1.1 elric 297 1.1 elric krb5_auth_con_setlocalseqnumber (context, 298 1.1 elric context_handle->auth_context, 299 1.1 elric ++seq_number); 300 1.1 elric HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 301 1.1 elric 302 1.1 elric memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); 303 1.1 elric 304 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 305 1.3 christos EVP_CIPHER_CTX rc4_keys; 306 1.3 christos rc4_key = &rc4_keys; 307 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 308 1.3 christos #else 309 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 310 1.3 christos #endif 311 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 312 1.5 christos *minor_status = EINVAL; 313 1.5 christos return GSS_S_FAILURE; 314 1.5 christos } 315 1.5 christos 316 1.3 christos EVP_Cipher(rc4_key, p, p, 8); 317 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 318 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 319 1.3 christos #else 320 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 321 1.3 christos #endif 322 1.1 elric 323 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 324 1.1 elric 325 1.1 elric *minor_status = 0; 326 1.1 elric return GSS_S_COMPLETE; 327 1.1 elric } 328 1.1 elric 329 1.1 elric 330 1.1 elric OM_uint32 331 1.1 elric _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, 332 1.1 elric const gsskrb5_ctx context_handle, 333 1.1 elric krb5_context context, 334 1.1 elric const gss_buffer_t message_buffer, 335 1.1 elric const gss_buffer_t token_buffer, 336 1.1 elric gss_qop_t * qop_state, 337 1.1 elric krb5_keyblock *key, 338 1.2 christos const char *type) 339 1.1 elric { 340 1.1 elric krb5_error_code ret; 341 1.1 elric uint32_t seq_number; 342 1.1 elric OM_uint32 omret; 343 1.1 elric u_char SND_SEQ[8], cksum_data[8], *p; 344 1.1 elric char k6_data[16]; 345 1.1 elric int cmp; 346 1.1 elric 347 1.1 elric if (qop_state) 348 1.1 elric *qop_state = 0; 349 1.1 elric 350 1.1 elric p = token_buffer->value; 351 1.1 elric omret = _gsskrb5_verify_header (&p, 352 1.1 elric token_buffer->length, 353 1.2 christos type, 354 1.1 elric GSS_KRB5_MECHANISM); 355 1.1 elric if (omret) 356 1.1 elric return omret; 357 1.1 elric 358 1.1 elric if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ 359 1.1 elric return GSS_S_BAD_SIG; 360 1.1 elric p += 2; 361 1.1 elric if (memcmp (p, "\xff\xff\xff\xff", 4) != 0) 362 1.1 elric return GSS_S_BAD_MIC; 363 1.1 elric p += 4; 364 1.1 elric 365 1.1 elric ret = arcfour_mic_cksum(context, 366 1.1 elric key, KRB5_KU_USAGE_SIGN, 367 1.1 elric cksum_data, sizeof(cksum_data), 368 1.1 elric p - 8, 8, 369 1.1 elric message_buffer->value, message_buffer->length, 370 1.1 elric NULL, 0); 371 1.1 elric if (ret) { 372 1.1 elric *minor_status = ret; 373 1.1 elric return GSS_S_FAILURE; 374 1.1 elric } 375 1.1 elric 376 1.1 elric ret = arcfour_mic_key(context, key, 377 1.1 elric cksum_data, sizeof(cksum_data), 378 1.1 elric k6_data, sizeof(k6_data)); 379 1.1 elric if (ret) { 380 1.1 elric *minor_status = ret; 381 1.1 elric return GSS_S_FAILURE; 382 1.1 elric } 383 1.1 elric 384 1.6 christos cmp = (ct_memcmp(cksum_data, p + 8, 8) == 0); 385 1.1 elric if (cmp) { 386 1.1 elric *minor_status = 0; 387 1.1 elric return GSS_S_BAD_MIC; 388 1.1 elric } 389 1.1 elric 390 1.1 elric { 391 1.3 christos EVP_CIPHER_CTX *rc4_key; 392 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 393 1.3 christos EVP_CIPHER_CTX rc4_keys; 394 1.3 christos rc4_key = &rc4_keys; 395 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 396 1.3 christos #else 397 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 398 1.3 christos #endif 399 1.3 christos 400 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 401 1.5 christos 0)) { 402 1.5 christos *minor_status = EINVAL; 403 1.5 christos return GSS_S_FAILURE; 404 1.5 christos } 405 1.3 christos EVP_Cipher(rc4_key, SND_SEQ, p, 8); 406 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 407 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 408 1.3 christos #else 409 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 410 1.3 christos #endif 411 1.1 elric 412 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 413 1.1 elric } 414 1.1 elric 415 1.1 elric _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); 416 1.1 elric 417 1.1 elric if (context_handle->more_flags & LOCAL) 418 1.6 christos cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0); 419 1.1 elric else 420 1.6 christos cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0); 421 1.1 elric 422 1.4 christos memset_s(SND_SEQ, sizeof(SND_SEQ), 0, sizeof(SND_SEQ)); 423 1.1 elric if (cmp != 0) { 424 1.1 elric *minor_status = 0; 425 1.1 elric return GSS_S_BAD_MIC; 426 1.1 elric } 427 1.1 elric 428 1.1 elric HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 429 1.1 elric omret = _gssapi_msg_order_check(context_handle->order, seq_number); 430 1.1 elric HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 431 1.1 elric if (omret) 432 1.1 elric return omret; 433 1.1 elric 434 1.1 elric *minor_status = 0; 435 1.1 elric return GSS_S_COMPLETE; 436 1.1 elric } 437 1.1 elric 438 1.1 elric OM_uint32 439 1.1 elric _gssapi_wrap_arcfour(OM_uint32 * minor_status, 440 1.1 elric const gsskrb5_ctx context_handle, 441 1.1 elric krb5_context context, 442 1.1 elric int conf_req_flag, 443 1.1 elric gss_qop_t qop_req, 444 1.1 elric const gss_buffer_t input_message_buffer, 445 1.1 elric int * conf_state, 446 1.1 elric gss_buffer_t output_message_buffer, 447 1.1 elric krb5_keyblock *key) 448 1.1 elric { 449 1.1 elric u_char Klocaldata[16], k6_data[16], *p, *p0; 450 1.1 elric size_t len, total_len, datalen; 451 1.1 elric krb5_keyblock Klocal; 452 1.1 elric krb5_error_code ret; 453 1.1 elric int32_t seq_number; 454 1.1 elric 455 1.1 elric if (conf_state) 456 1.1 elric *conf_state = 0; 457 1.1 elric 458 1.1 elric datalen = input_message_buffer->length; 459 1.1 elric 460 1.1 elric if (IS_DCE_STYLE(context_handle)) { 461 1.1 elric len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; 462 1.1 elric _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 463 1.1 elric total_len += datalen; 464 1.1 elric } else { 465 1.1 elric datalen += 1; /* padding */ 466 1.1 elric len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE; 467 1.1 elric _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 468 1.1 elric } 469 1.1 elric 470 1.1 elric output_message_buffer->length = total_len; 471 1.1 elric output_message_buffer->value = malloc (total_len); 472 1.1 elric if (output_message_buffer->value == NULL) { 473 1.1 elric *minor_status = ENOMEM; 474 1.1 elric return GSS_S_FAILURE; 475 1.1 elric } 476 1.1 elric 477 1.1 elric p0 = _gssapi_make_mech_header(output_message_buffer->value, 478 1.1 elric len, 479 1.1 elric GSS_KRB5_MECHANISM); 480 1.1 elric p = p0; 481 1.1 elric 482 1.1 elric *p++ = 0x02; /* TOK_ID */ 483 1.1 elric *p++ = 0x01; 484 1.1 elric *p++ = 0x11; /* SGN_ALG */ 485 1.1 elric *p++ = 0x00; 486 1.1 elric if (conf_req_flag) { 487 1.1 elric *p++ = 0x10; /* SEAL_ALG */ 488 1.1 elric *p++ = 0x00; 489 1.1 elric } else { 490 1.1 elric *p++ = 0xff; /* SEAL_ALG */ 491 1.1 elric *p++ = 0xff; 492 1.1 elric } 493 1.1 elric *p++ = 0xff; /* Filler */ 494 1.1 elric *p++ = 0xff; 495 1.1 elric 496 1.1 elric p = NULL; 497 1.1 elric 498 1.1 elric HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 499 1.1 elric krb5_auth_con_getlocalseqnumber (context, 500 1.1 elric context_handle->auth_context, 501 1.1 elric &seq_number); 502 1.1 elric 503 1.1 elric _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); 504 1.1 elric 505 1.1 elric krb5_auth_con_setlocalseqnumber (context, 506 1.1 elric context_handle->auth_context, 507 1.1 elric ++seq_number); 508 1.1 elric HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 509 1.1 elric 510 1.1 elric memset (p0 + 8 + 4, 511 1.1 elric (context_handle->more_flags & LOCAL) ? 0 : 0xff, 512 1.1 elric 4); 513 1.1 elric 514 1.1 elric krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ 515 1.1 elric 516 1.1 elric /* p points to data */ 517 1.1 elric p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE; 518 1.1 elric memcpy(p, input_message_buffer->value, input_message_buffer->length); 519 1.1 elric 520 1.1 elric if (!IS_DCE_STYLE(context_handle)) 521 1.1 elric p[input_message_buffer->length] = 1; /* padding */ 522 1.1 elric 523 1.1 elric ret = arcfour_mic_cksum(context, 524 1.1 elric key, KRB5_KU_USAGE_SEAL, 525 1.1 elric p0 + 16, 8, /* SGN_CKSUM */ 526 1.1 elric p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ 527 1.1 elric p0 + 24, 8, /* Confounder */ 528 1.1 elric p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, 529 1.1 elric datalen); 530 1.1 elric if (ret) { 531 1.1 elric *minor_status = ret; 532 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 533 1.1 elric return GSS_S_FAILURE; 534 1.1 elric } 535 1.1 elric 536 1.1 elric { 537 1.1 elric int i; 538 1.1 elric 539 1.1 elric Klocal.keytype = key->keytype; 540 1.1 elric Klocal.keyvalue.data = Klocaldata; 541 1.1 elric Klocal.keyvalue.length = sizeof(Klocaldata); 542 1.1 elric 543 1.1 elric for (i = 0; i < 16; i++) 544 1.1 elric Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; 545 1.1 elric } 546 1.1 elric ret = arcfour_mic_key(context, &Klocal, 547 1.1 elric p0 + 8, 4, /* SND_SEQ */ 548 1.1 elric k6_data, sizeof(k6_data)); 549 1.4 christos memset_s(Klocaldata, sizeof(Klocaldata), 0, sizeof(Klocaldata)); 550 1.1 elric if (ret) { 551 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 552 1.1 elric *minor_status = ret; 553 1.1 elric return GSS_S_FAILURE; 554 1.1 elric } 555 1.1 elric 556 1.1 elric 557 1.1 elric if(conf_req_flag) { 558 1.3 christos EVP_CIPHER_CTX *rc4_key; 559 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 560 1.3 christos EVP_CIPHER_CTX rc4_keys; 561 1.3 christos rc4_key = &rc4_keys; 562 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 563 1.3 christos #else 564 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 565 1.3 christos #endif 566 1.3 christos 567 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 568 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 569 1.5 christos *minor_status = EINVAL; 570 1.5 christos return GSS_S_FAILURE; 571 1.5 christos } 572 1.3 christos EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen); 573 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 574 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 575 1.3 christos #else 576 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 577 1.3 christos #endif 578 1.1 elric } 579 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 580 1.1 elric 581 1.1 elric ret = arcfour_mic_key(context, key, 582 1.1 elric p0 + 16, 8, /* SGN_CKSUM */ 583 1.1 elric k6_data, sizeof(k6_data)); 584 1.1 elric if (ret) { 585 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 586 1.1 elric *minor_status = ret; 587 1.1 elric return GSS_S_FAILURE; 588 1.1 elric } 589 1.1 elric 590 1.1 elric { 591 1.3 christos EVP_CIPHER_CTX *rc4_key; 592 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 593 1.3 christos EVP_CIPHER_CTX rc4_keys; 594 1.3 christos rc4_key = &rc4_keys; 595 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 596 1.3 christos #else 597 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 598 1.3 christos #endif 599 1.3 christos 600 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 601 1.5 christos *minor_status = EINVAL; 602 1.5 christos return GSS_S_FAILURE; 603 1.5 christos } 604 1.3 christos EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8); 605 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 606 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 607 1.3 christos #else 608 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 609 1.3 christos #endif 610 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 611 1.1 elric } 612 1.1 elric 613 1.1 elric if (conf_state) 614 1.1 elric *conf_state = conf_req_flag; 615 1.1 elric 616 1.1 elric *minor_status = 0; 617 1.1 elric return GSS_S_COMPLETE; 618 1.1 elric } 619 1.1 elric 620 1.1 elric OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, 621 1.1 elric const gsskrb5_ctx context_handle, 622 1.1 elric krb5_context context, 623 1.1 elric const gss_buffer_t input_message_buffer, 624 1.1 elric gss_buffer_t output_message_buffer, 625 1.1 elric int *conf_state, 626 1.1 elric gss_qop_t *qop_state, 627 1.1 elric krb5_keyblock *key) 628 1.1 elric { 629 1.1 elric u_char Klocaldata[16]; 630 1.1 elric krb5_keyblock Klocal; 631 1.1 elric krb5_error_code ret; 632 1.1 elric uint32_t seq_number; 633 1.1 elric size_t datalen; 634 1.1 elric OM_uint32 omret; 635 1.1 elric u_char k6_data[16], SND_SEQ[8], Confounder[8]; 636 1.1 elric u_char cksum_data[8]; 637 1.1 elric u_char *p, *p0; 638 1.1 elric int cmp; 639 1.1 elric int conf_flag; 640 1.1 elric size_t padlen = 0, len; 641 1.1 elric 642 1.1 elric if (conf_state) 643 1.1 elric *conf_state = 0; 644 1.1 elric if (qop_state) 645 1.1 elric *qop_state = 0; 646 1.1 elric 647 1.1 elric p0 = input_message_buffer->value; 648 1.1 elric 649 1.1 elric if (IS_DCE_STYLE(context_handle)) { 650 1.1 elric len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + 651 1.1 elric GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE; 652 1.1 elric if (input_message_buffer->length < len) 653 1.1 elric return GSS_S_BAD_MECH; 654 1.1 elric } else { 655 1.1 elric len = input_message_buffer->length; 656 1.1 elric } 657 1.1 elric 658 1.1 elric omret = _gssapi_verify_mech_header(&p0, 659 1.1 elric len, 660 1.1 elric GSS_KRB5_MECHANISM); 661 1.1 elric if (omret) 662 1.1 elric return omret; 663 1.1 elric 664 1.1 elric /* length of mech header */ 665 1.1 elric len = (p0 - (u_char *)input_message_buffer->value) + 666 1.1 elric GSS_ARCFOUR_WRAP_TOKEN_SIZE; 667 1.1 elric 668 1.1 elric if (len > input_message_buffer->length) 669 1.1 elric return GSS_S_BAD_MECH; 670 1.1 elric 671 1.1 elric /* length of data */ 672 1.1 elric datalen = input_message_buffer->length - len; 673 1.1 elric 674 1.1 elric p = p0; 675 1.1 elric 676 1.1 elric if (memcmp(p, "\x02\x01", 2) != 0) 677 1.1 elric return GSS_S_BAD_SIG; 678 1.1 elric p += 2; 679 1.1 elric if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ 680 1.1 elric return GSS_S_BAD_SIG; 681 1.1 elric p += 2; 682 1.1 elric 683 1.1 elric if (memcmp (p, "\x10\x00", 2) == 0) 684 1.1 elric conf_flag = 1; 685 1.1 elric else if (memcmp (p, "\xff\xff", 2) == 0) 686 1.1 elric conf_flag = 0; 687 1.1 elric else 688 1.1 elric return GSS_S_BAD_SIG; 689 1.1 elric 690 1.1 elric p += 2; 691 1.1 elric if (memcmp (p, "\xff\xff", 2) != 0) 692 1.1 elric return GSS_S_BAD_MIC; 693 1.1 elric p = NULL; 694 1.1 elric 695 1.1 elric ret = arcfour_mic_key(context, key, 696 1.1 elric p0 + 16, 8, /* SGN_CKSUM */ 697 1.1 elric k6_data, sizeof(k6_data)); 698 1.1 elric if (ret) { 699 1.1 elric *minor_status = ret; 700 1.1 elric return GSS_S_FAILURE; 701 1.1 elric } 702 1.1 elric 703 1.1 elric { 704 1.3 christos EVP_CIPHER_CTX *rc4_key; 705 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 706 1.3 christos EVP_CIPHER_CTX rc4_keys; 707 1.3 christos rc4_key = &rc4_keys; 708 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 709 1.3 christos #else 710 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 711 1.3 christos #endif 712 1.3 christos 713 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 714 1.5 christos *minor_status = EINVAL; 715 1.5 christos return GSS_S_FAILURE; 716 1.5 christos } 717 1.3 christos EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8); 718 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 719 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 720 1.3 christos #else 721 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 722 1.3 christos #endif 723 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 724 1.1 elric } 725 1.1 elric 726 1.1 elric _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); 727 1.1 elric 728 1.1 elric if (context_handle->more_flags & LOCAL) 729 1.6 christos cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0); 730 1.1 elric else 731 1.6 christos cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0); 732 1.1 elric 733 1.1 elric if (cmp != 0) { 734 1.1 elric *minor_status = 0; 735 1.1 elric return GSS_S_BAD_MIC; 736 1.1 elric } 737 1.1 elric 738 1.1 elric { 739 1.1 elric int i; 740 1.1 elric 741 1.1 elric Klocal.keytype = key->keytype; 742 1.1 elric Klocal.keyvalue.data = Klocaldata; 743 1.1 elric Klocal.keyvalue.length = sizeof(Klocaldata); 744 1.1 elric 745 1.1 elric for (i = 0; i < 16; i++) 746 1.1 elric Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; 747 1.1 elric } 748 1.1 elric ret = arcfour_mic_key(context, &Klocal, 749 1.1 elric SND_SEQ, 4, 750 1.1 elric k6_data, sizeof(k6_data)); 751 1.4 christos memset_s(Klocaldata, sizeof(Klocaldata), 0, sizeof(Klocaldata)); 752 1.1 elric if (ret) { 753 1.1 elric *minor_status = ret; 754 1.1 elric return GSS_S_FAILURE; 755 1.1 elric } 756 1.1 elric 757 1.1 elric output_message_buffer->value = malloc(datalen); 758 1.1 elric if (output_message_buffer->value == NULL) { 759 1.1 elric *minor_status = ENOMEM; 760 1.1 elric return GSS_S_FAILURE; 761 1.1 elric } 762 1.1 elric output_message_buffer->length = datalen; 763 1.1 elric 764 1.1 elric if(conf_flag) { 765 1.3 christos EVP_CIPHER_CTX *rc4_key; 766 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 767 1.3 christos EVP_CIPHER_CTX rc4_keys; 768 1.3 christos rc4_key = &rc4_keys; 769 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 770 1.3 christos #else 771 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 772 1.3 christos #endif 773 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 774 1.5 christos *minor_status = EINVAL; 775 1.5 christos return GSS_S_FAILURE; 776 1.5 christos } 777 1.3 christos EVP_Cipher(rc4_key, Confounder, p0 + 24, 8); 778 1.3 christos EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); 779 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 780 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 781 1.3 christos #else 782 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 783 1.3 christos #endif 784 1.1 elric } else { 785 1.1 elric memcpy(Confounder, p0 + 24, 8); /* Confounder */ 786 1.1 elric memcpy(output_message_buffer->value, 787 1.1 elric p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, 788 1.1 elric datalen); 789 1.1 elric } 790 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 791 1.1 elric 792 1.1 elric if (!IS_DCE_STYLE(context_handle)) { 793 1.1 elric ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen); 794 1.1 elric if (ret) { 795 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 796 1.1 elric *minor_status = 0; 797 1.1 elric return ret; 798 1.1 elric } 799 1.1 elric output_message_buffer->length -= padlen; 800 1.1 elric } 801 1.1 elric 802 1.1 elric ret = arcfour_mic_cksum(context, 803 1.1 elric key, KRB5_KU_USAGE_SEAL, 804 1.1 elric cksum_data, sizeof(cksum_data), 805 1.1 elric p0, 8, 806 1.1 elric Confounder, sizeof(Confounder), 807 1.1 elric output_message_buffer->value, 808 1.1 elric output_message_buffer->length + padlen); 809 1.1 elric if (ret) { 810 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 811 1.1 elric *minor_status = ret; 812 1.1 elric return GSS_S_FAILURE; 813 1.1 elric } 814 1.1 elric 815 1.6 christos cmp = (ct_memcmp(cksum_data, p0 + 16, 8) == 0); /* SGN_CKSUM */ 816 1.1 elric if (cmp) { 817 1.1 elric _gsskrb5_release_buffer(minor_status, output_message_buffer); 818 1.1 elric *minor_status = 0; 819 1.1 elric return GSS_S_BAD_MIC; 820 1.1 elric } 821 1.1 elric 822 1.1 elric HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 823 1.1 elric omret = _gssapi_msg_order_check(context_handle->order, seq_number); 824 1.1 elric HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 825 1.1 elric if (omret) 826 1.1 elric return omret; 827 1.1 elric 828 1.1 elric if (conf_state) 829 1.1 elric *conf_state = conf_flag; 830 1.1 elric 831 1.1 elric *minor_status = 0; 832 1.1 elric return GSS_S_COMPLETE; 833 1.1 elric } 834 1.1 elric 835 1.1 elric static OM_uint32 836 1.1 elric max_wrap_length_arcfour(const gsskrb5_ctx ctx, 837 1.1 elric krb5_crypto crypto, 838 1.1 elric size_t input_length, 839 1.1 elric OM_uint32 *max_input_size) 840 1.1 elric { 841 1.1 elric /* 842 1.1 elric * if GSS_C_DCE_STYLE is in use: 843 1.1 elric * - we only need to encapsulate the WRAP token 844 1.1 elric * However, since this is a fixed since, we just 845 1.1 elric */ 846 1.1 elric if (IS_DCE_STYLE(ctx)) { 847 1.1 elric size_t len, total_len; 848 1.1 elric 849 1.1 elric len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; 850 1.1 elric _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 851 1.1 elric 852 1.1 elric if (input_length < len) 853 1.1 elric *max_input_size = 0; 854 1.1 elric else 855 1.1 elric *max_input_size = input_length - len; 856 1.1 elric 857 1.1 elric } else { 858 1.1 elric size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE; 859 1.1 elric size_t blocksize = 8; 860 1.1 elric size_t len, total_len; 861 1.1 elric 862 1.1 elric len = 8 + input_length + blocksize + extrasize; 863 1.1 elric 864 1.1 elric _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 865 1.1 elric 866 1.1 elric total_len -= input_length; /* token length */ 867 1.1 elric if (total_len < input_length) { 868 1.1 elric *max_input_size = (input_length - total_len); 869 1.1 elric (*max_input_size) &= (~(OM_uint32)(blocksize - 1)); 870 1.1 elric } else { 871 1.1 elric *max_input_size = 0; 872 1.1 elric } 873 1.1 elric } 874 1.1 elric 875 1.1 elric return GSS_S_COMPLETE; 876 1.1 elric } 877 1.1 elric 878 1.1 elric OM_uint32 879 1.1 elric _gssapi_wrap_size_arcfour(OM_uint32 *minor_status, 880 1.1 elric const gsskrb5_ctx ctx, 881 1.1 elric krb5_context context, 882 1.1 elric int conf_req_flag, 883 1.1 elric gss_qop_t qop_req, 884 1.1 elric OM_uint32 req_output_size, 885 1.1 elric OM_uint32 *max_input_size, 886 1.1 elric krb5_keyblock *key) 887 1.1 elric { 888 1.1 elric krb5_error_code ret; 889 1.1 elric krb5_crypto crypto; 890 1.1 elric 891 1.1 elric ret = krb5_crypto_init(context, key, 0, &crypto); 892 1.1 elric if (ret != 0) { 893 1.1 elric *minor_status = ret; 894 1.1 elric return GSS_S_FAILURE; 895 1.1 elric } 896 1.1 elric 897 1.1 elric ret = max_wrap_length_arcfour(ctx, crypto, 898 1.1 elric req_output_size, max_input_size); 899 1.1 elric if (ret != 0) { 900 1.1 elric *minor_status = ret; 901 1.1 elric krb5_crypto_destroy(context, crypto); 902 1.1 elric return GSS_S_FAILURE; 903 1.1 elric } 904 1.1 elric 905 1.1 elric krb5_crypto_destroy(context, crypto); 906 1.1 elric 907 1.1 elric return GSS_S_COMPLETE; 908 1.1 elric } 909 1.2 christos 910 1.2 christos OM_uint32 911 1.2 christos _gssapi_wrap_iov_length_arcfour(OM_uint32 *minor_status, 912 1.2 christos gsskrb5_ctx ctx, 913 1.2 christos krb5_context context, 914 1.2 christos int conf_req_flag, 915 1.2 christos gss_qop_t qop_req, 916 1.2 christos int *conf_state, 917 1.2 christos gss_iov_buffer_desc *iov, 918 1.2 christos int iov_count) 919 1.2 christos { 920 1.2 christos OM_uint32 major_status; 921 1.2 christos size_t data_len = 0; 922 1.2 christos int i; 923 1.2 christos gss_iov_buffer_desc *header = NULL; 924 1.2 christos gss_iov_buffer_desc *padding = NULL; 925 1.2 christos gss_iov_buffer_desc *trailer = NULL; 926 1.2 christos 927 1.2 christos *minor_status = 0; 928 1.2 christos 929 1.2 christos for (i = 0; i < iov_count; i++) { 930 1.2 christos switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) { 931 1.2 christos case GSS_IOV_BUFFER_TYPE_EMPTY: 932 1.2 christos break; 933 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 934 1.2 christos data_len += iov[i].buffer.length; 935 1.2 christos break; 936 1.2 christos case GSS_IOV_BUFFER_TYPE_HEADER: 937 1.2 christos if (header != NULL) { 938 1.2 christos *minor_status = EINVAL; 939 1.2 christos return GSS_S_FAILURE; 940 1.2 christos } 941 1.2 christos header = &iov[i]; 942 1.2 christos break; 943 1.2 christos case GSS_IOV_BUFFER_TYPE_TRAILER: 944 1.2 christos if (trailer != NULL) { 945 1.2 christos *minor_status = EINVAL; 946 1.2 christos return GSS_S_FAILURE; 947 1.2 christos } 948 1.2 christos trailer = &iov[i]; 949 1.2 christos break; 950 1.2 christos case GSS_IOV_BUFFER_TYPE_PADDING: 951 1.2 christos if (padding != NULL) { 952 1.2 christos *minor_status = EINVAL; 953 1.2 christos return GSS_S_FAILURE; 954 1.2 christos } 955 1.2 christos padding = &iov[i]; 956 1.2 christos break; 957 1.2 christos case GSS_IOV_BUFFER_TYPE_SIGN_ONLY: 958 1.2 christos break; 959 1.2 christos default: 960 1.2 christos *minor_status = EINVAL; 961 1.2 christos return GSS_S_FAILURE; 962 1.2 christos } 963 1.2 christos } 964 1.2 christos 965 1.6 christos if (header == NULL) { 966 1.6 christos *minor_status = EINVAL; 967 1.6 christos return GSS_S_FAILURE; 968 1.6 christos } 969 1.6 christos 970 1.6 christos major_status = _gk_verify_buffers(minor_status, ctx, header, 971 1.6 christos padding, trailer, FALSE); 972 1.2 christos if (major_status != GSS_S_COMPLETE) { 973 1.2 christos return major_status; 974 1.2 christos } 975 1.2 christos 976 1.2 christos if (IS_DCE_STYLE(ctx)) { 977 1.2 christos size_t len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; 978 1.2 christos size_t total_len; 979 1.2 christos _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 980 1.2 christos header->buffer.length = total_len; 981 1.2 christos } else { 982 1.2 christos size_t len; 983 1.2 christos size_t total_len; 984 1.2 christos if (padding) { 985 1.2 christos data_len += 1; /* padding */ 986 1.2 christos } 987 1.2 christos len = data_len + GSS_ARCFOUR_WRAP_TOKEN_SIZE; 988 1.2 christos _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); 989 1.2 christos header->buffer.length = total_len - data_len; 990 1.2 christos } 991 1.2 christos 992 1.2 christos if (trailer) { 993 1.2 christos trailer->buffer.length = 0; 994 1.2 christos } 995 1.2 christos 996 1.2 christos if (padding) { 997 1.2 christos padding->buffer.length = 1; 998 1.2 christos } 999 1.2 christos 1000 1.2 christos return GSS_S_COMPLETE; 1001 1.2 christos } 1002 1.2 christos 1003 1.2 christos OM_uint32 1004 1.2 christos _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status, 1005 1.2 christos gsskrb5_ctx ctx, 1006 1.2 christos krb5_context context, 1007 1.2 christos int conf_req_flag, 1008 1.2 christos int *conf_state, 1009 1.2 christos gss_iov_buffer_desc *iov, 1010 1.2 christos int iov_count, 1011 1.2 christos krb5_keyblock *key) 1012 1.2 christos { 1013 1.2 christos OM_uint32 major_status, junk; 1014 1.2 christos gss_iov_buffer_desc *header, *padding, *trailer; 1015 1.2 christos krb5_error_code kret; 1016 1.2 christos int32_t seq_number; 1017 1.2 christos u_char Klocaldata[16], k6_data[16], *p, *p0; 1018 1.2 christos size_t make_len = 0; 1019 1.2 christos size_t header_len = 0; 1020 1.2 christos size_t data_len = 0; 1021 1.2 christos krb5_keyblock Klocal; 1022 1.2 christos int i; 1023 1.2 christos 1024 1.2 christos header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); 1025 1.2 christos padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); 1026 1.2 christos trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); 1027 1.2 christos 1028 1.6 christos major_status = _gk_verify_buffers(minor_status, ctx, header, 1029 1.6 christos padding, trailer, FALSE); 1030 1.2 christos if (major_status != GSS_S_COMPLETE) { 1031 1.2 christos return major_status; 1032 1.2 christos } 1033 1.2 christos 1034 1.2 christos for (i = 0; i < iov_count; i++) { 1035 1.2 christos switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { 1036 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 1037 1.2 christos break; 1038 1.2 christos default: 1039 1.2 christos continue; 1040 1.2 christos } 1041 1.2 christos 1042 1.2 christos data_len += iov[i].buffer.length; 1043 1.2 christos } 1044 1.2 christos 1045 1.2 christos if (padding) { 1046 1.2 christos data_len += 1; 1047 1.2 christos } 1048 1.2 christos 1049 1.2 christos if (IS_DCE_STYLE(ctx)) { 1050 1.2 christos size_t unwrapped_len; 1051 1.2 christos unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; 1052 1.2 christos _gssapi_encap_length(unwrapped_len, 1053 1.2 christos &make_len, 1054 1.2 christos &header_len, 1055 1.2 christos GSS_KRB5_MECHANISM); 1056 1.2 christos } else { 1057 1.2 christos size_t unwrapped_len; 1058 1.2 christos unwrapped_len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + data_len; 1059 1.2 christos _gssapi_encap_length(unwrapped_len, 1060 1.2 christos &make_len, 1061 1.2 christos &header_len, 1062 1.2 christos GSS_KRB5_MECHANISM); 1063 1.2 christos header_len -= data_len; 1064 1.2 christos } 1065 1.2 christos 1066 1.6 christos if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) { 1067 1.2 christos major_status = _gk_allocate_buffer(minor_status, header, 1068 1.2 christos header_len); 1069 1.2 christos if (major_status != GSS_S_COMPLETE) 1070 1.2 christos goto failure; 1071 1.2 christos } else if (header->buffer.length < header_len) { 1072 1.2 christos *minor_status = KRB5_BAD_MSIZE; 1073 1.2 christos major_status = GSS_S_FAILURE; 1074 1.2 christos goto failure; 1075 1.2 christos } else { 1076 1.2 christos header->buffer.length = header_len; 1077 1.2 christos } 1078 1.2 christos 1079 1.2 christos if (padding) { 1080 1.6 christos if (GSS_IOV_BUFFER_FLAGS(padding->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) { 1081 1.2 christos major_status = _gk_allocate_buffer(minor_status, padding, 1); 1082 1.2 christos if (major_status != GSS_S_COMPLETE) 1083 1.2 christos goto failure; 1084 1.2 christos } else if (padding->buffer.length < 1) { 1085 1.2 christos *minor_status = KRB5_BAD_MSIZE; 1086 1.2 christos major_status = GSS_S_FAILURE; 1087 1.2 christos goto failure; 1088 1.2 christos } else { 1089 1.2 christos padding->buffer.length = 1; 1090 1.2 christos } 1091 1.2 christos memset(padding->buffer.value, 1, 1); 1092 1.2 christos } 1093 1.2 christos 1094 1.2 christos if (trailer) { 1095 1.2 christos trailer->buffer.length = 0; 1096 1.2 christos trailer->buffer.value = NULL; 1097 1.2 christos } 1098 1.2 christos 1099 1.2 christos p0 = _gssapi_make_mech_header(header->buffer.value, 1100 1.2 christos make_len, 1101 1.2 christos GSS_KRB5_MECHANISM); 1102 1.2 christos p = p0; 1103 1.2 christos 1104 1.2 christos *p++ = 0x02; /* TOK_ID */ 1105 1.2 christos *p++ = 0x01; 1106 1.2 christos *p++ = 0x11; /* SGN_ALG */ 1107 1.2 christos *p++ = 0x00; 1108 1.2 christos if (conf_req_flag) { 1109 1.2 christos *p++ = 0x10; /* SEAL_ALG */ 1110 1.2 christos *p++ = 0x00; 1111 1.2 christos } else { 1112 1.2 christos *p++ = 0xff; /* SEAL_ALG */ 1113 1.2 christos *p++ = 0xff; 1114 1.2 christos } 1115 1.2 christos *p++ = 0xff; /* Filler */ 1116 1.2 christos *p++ = 0xff; 1117 1.2 christos 1118 1.2 christos p = NULL; 1119 1.2 christos 1120 1.2 christos HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 1121 1.2 christos krb5_auth_con_getlocalseqnumber(context, 1122 1.2 christos ctx->auth_context, 1123 1.2 christos &seq_number); 1124 1.2 christos _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); 1125 1.2 christos 1126 1.2 christos krb5_auth_con_setlocalseqnumber(context, 1127 1.2 christos ctx->auth_context, 1128 1.2 christos ++seq_number); 1129 1.2 christos HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 1130 1.2 christos 1131 1.2 christos memset(p0 + 8 + 4, 1132 1.2 christos (ctx->more_flags & LOCAL) ? 0 : 0xff, 1133 1.2 christos 4); 1134 1.2 christos 1135 1.2 christos krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ 1136 1.2 christos 1137 1.2 christos /* Sign Data */ 1138 1.2 christos kret = arcfour_mic_cksum_iov(context, 1139 1.2 christos key, KRB5_KU_USAGE_SEAL, 1140 1.2 christos p0 + 16, 8, /* SGN_CKSUM */ 1141 1.2 christos p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ 1142 1.2 christos p0 + 24, 8, /* Confounder */ 1143 1.2 christos iov, iov_count, /* Data + SignOnly */ 1144 1.2 christos padding); /* padding */ 1145 1.2 christos if (kret) { 1146 1.2 christos *minor_status = kret; 1147 1.2 christos major_status = GSS_S_FAILURE; 1148 1.2 christos goto failure; 1149 1.2 christos } 1150 1.2 christos 1151 1.2 christos Klocal.keytype = key->keytype; 1152 1.2 christos Klocal.keyvalue.data = Klocaldata; 1153 1.2 christos Klocal.keyvalue.length = sizeof(Klocaldata); 1154 1.2 christos 1155 1.2 christos for (i = 0; i < 16; i++) { 1156 1.2 christos Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; 1157 1.2 christos } 1158 1.2 christos kret = arcfour_mic_key(context, &Klocal, 1159 1.2 christos p0 + 8, 4, /* SND_SEQ */ 1160 1.2 christos k6_data, sizeof(k6_data)); 1161 1.4 christos memset_s(Klocaldata, sizeof(Klocaldata), 0, sizeof(Klocaldata)); 1162 1.2 christos if (kret) { 1163 1.2 christos *minor_status = kret; 1164 1.2 christos major_status = GSS_S_FAILURE; 1165 1.2 christos goto failure; 1166 1.2 christos } 1167 1.2 christos 1168 1.2 christos if (conf_req_flag) { 1169 1.3 christos EVP_CIPHER_CTX *rc4_key; 1170 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1171 1.3 christos EVP_CIPHER_CTX rc4_keys; 1172 1.3 christos rc4_key = &rc4_keys; 1173 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 1174 1.3 christos #else 1175 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 1176 1.3 christos #endif 1177 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 1178 1.5 christos *minor_status = EINVAL; 1179 1.5 christos return GSS_S_FAILURE; 1180 1.5 christos } 1181 1.2 christos 1182 1.2 christos /* Confounder */ 1183 1.3 christos EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8); 1184 1.2 christos 1185 1.2 christos /* Seal Data */ 1186 1.2 christos for (i=0; i < iov_count; i++) { 1187 1.2 christos switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { 1188 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 1189 1.2 christos break; 1190 1.2 christos default: 1191 1.2 christos continue; 1192 1.2 christos } 1193 1.2 christos 1194 1.3 christos EVP_Cipher(rc4_key, iov[i].buffer.value, 1195 1.2 christos iov[i].buffer.value, iov[i].buffer.length); 1196 1.2 christos } 1197 1.2 christos 1198 1.2 christos /* Padding */ 1199 1.2 christos if (padding) { 1200 1.3 christos EVP_Cipher(rc4_key, padding->buffer.value, 1201 1.2 christos padding->buffer.value, padding->buffer.length); 1202 1.2 christos } 1203 1.2 christos 1204 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1205 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 1206 1.3 christos #else 1207 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 1208 1.3 christos #endif 1209 1.2 christos } 1210 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 1211 1.2 christos 1212 1.2 christos kret = arcfour_mic_key(context, key, 1213 1.2 christos p0 + 16, 8, /* SGN_CKSUM */ 1214 1.2 christos k6_data, sizeof(k6_data)); 1215 1.2 christos if (kret) { 1216 1.2 christos *minor_status = kret; 1217 1.2 christos major_status = GSS_S_FAILURE; 1218 1.2 christos return major_status; 1219 1.2 christos } 1220 1.2 christos 1221 1.2 christos { 1222 1.3 christos EVP_CIPHER_CTX *rc4_key; 1223 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1224 1.3 christos EVP_CIPHER_CTX rc4_keys; 1225 1.3 christos rc4_key = &rc4_keys; 1226 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 1227 1.3 christos #else 1228 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 1229 1.3 christos #endif 1230 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 1231 1.5 christos *minor_status = EINVAL; 1232 1.5 christos return GSS_S_FAILURE; 1233 1.5 christos } 1234 1.3 christos EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8); /* SND_SEQ */ 1235 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1236 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 1237 1.3 christos #else 1238 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 1239 1.3 christos #endif 1240 1.2 christos 1241 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 1242 1.2 christos } 1243 1.2 christos 1244 1.2 christos if (conf_state) 1245 1.2 christos *conf_state = conf_req_flag; 1246 1.2 christos 1247 1.2 christos *minor_status = 0; 1248 1.2 christos return GSS_S_COMPLETE; 1249 1.2 christos 1250 1.2 christos failure: 1251 1.2 christos 1252 1.2 christos gss_release_iov_buffer(&junk, iov, iov_count); 1253 1.2 christos 1254 1.2 christos return major_status; 1255 1.2 christos } 1256 1.2 christos 1257 1.2 christos OM_uint32 1258 1.2 christos _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, 1259 1.2 christos gsskrb5_ctx ctx, 1260 1.2 christos krb5_context context, 1261 1.2 christos int *pconf_state, 1262 1.2 christos gss_qop_t *pqop_state, 1263 1.2 christos gss_iov_buffer_desc *iov, 1264 1.2 christos int iov_count, 1265 1.2 christos krb5_keyblock *key) 1266 1.2 christos { 1267 1.2 christos OM_uint32 major_status; 1268 1.2 christos gss_iov_buffer_desc *header, *padding, *trailer; 1269 1.2 christos krb5_keyblock Klocal; 1270 1.2 christos uint8_t Klocaldata[16]; 1271 1.2 christos uint8_t k6_data[16], snd_seq[8], Confounder[8]; 1272 1.2 christos uint8_t cksum_data[8]; 1273 1.2 christos uint8_t *_p = NULL; 1274 1.2 christos const uint8_t *p, *p0; 1275 1.2 christos size_t verify_len = 0; 1276 1.2 christos uint32_t seq_number; 1277 1.2 christos size_t hlen = 0; 1278 1.2 christos int conf_state; 1279 1.2 christos int cmp; 1280 1.2 christos size_t i; 1281 1.2 christos krb5_error_code kret; 1282 1.2 christos OM_uint32 ret; 1283 1.2 christos 1284 1.2 christos if (pconf_state != NULL) { 1285 1.2 christos *pconf_state = 0; 1286 1.2 christos } 1287 1.2 christos if (pqop_state != NULL) { 1288 1.2 christos *pqop_state = 0; 1289 1.2 christos } 1290 1.2 christos 1291 1.2 christos header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); 1292 1.2 christos padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING); 1293 1.2 christos trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); 1294 1.2 christos 1295 1.2 christos /* Check if the packet is correct */ 1296 1.2 christos major_status = _gk_verify_buffers(minor_status, 1297 1.6 christos ctx, 1298 1.6 christos header, 1299 1.6 christos padding, 1300 1.6 christos trailer, 1301 1.6 christos FALSE); /* behaves as stream cipher */ 1302 1.2 christos if (major_status != GSS_S_COMPLETE) { 1303 1.2 christos return major_status; 1304 1.2 christos } 1305 1.2 christos 1306 1.2 christos if (padding != NULL && padding->buffer.length != 1) { 1307 1.2 christos *minor_status = EINVAL; 1308 1.2 christos return GSS_S_FAILURE; 1309 1.2 christos } 1310 1.2 christos 1311 1.6 christos verify_len = header->buffer.length; 1312 1.6 christos 1313 1.6 christos if (!IS_DCE_STYLE(context)) { 1314 1.6 christos for (i = 0; i < iov_count; i++) { 1315 1.6 christos /* length in header also includes data and padding */ 1316 1.6 christos if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA) 1317 1.6 christos verify_len += iov[i].buffer.length; 1318 1.2 christos } 1319 1.6 christos 1320 1.6 christos if (padding) 1321 1.6 christos verify_len += padding->buffer.length; 1322 1.2 christos } 1323 1.6 christos 1324 1.2 christos _p = header->buffer.value; 1325 1.2 christos 1326 1.2 christos ret = _gssapi_verify_mech_header(&_p, 1327 1.2 christos verify_len, 1328 1.2 christos GSS_KRB5_MECHANISM); 1329 1.2 christos if (ret) { 1330 1.2 christos return ret; 1331 1.2 christos } 1332 1.2 christos p0 = _p; 1333 1.2 christos 1334 1.2 christos /* length of mech header */ 1335 1.2 christos hlen = (p0 - (uint8_t *)header->buffer.value); 1336 1.2 christos hlen += GSS_ARCFOUR_WRAP_TOKEN_SIZE; 1337 1.2 christos 1338 1.2 christos if (hlen > header->buffer.length) { 1339 1.2 christos return GSS_S_BAD_MECH; 1340 1.2 christos } 1341 1.2 christos 1342 1.2 christos p = p0; 1343 1.2 christos 1344 1.2 christos if (memcmp(p, "\x02\x01", 2) != 0) 1345 1.2 christos return GSS_S_BAD_SIG; 1346 1.2 christos p += 2; 1347 1.2 christos if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ 1348 1.2 christos return GSS_S_BAD_SIG; 1349 1.2 christos p += 2; 1350 1.2 christos 1351 1.2 christos if (memcmp (p, "\x10\x00", 2) == 0) 1352 1.2 christos conf_state = 1; 1353 1.2 christos else if (memcmp (p, "\xff\xff", 2) == 0) 1354 1.2 christos conf_state = 0; 1355 1.2 christos else 1356 1.2 christos return GSS_S_BAD_SIG; 1357 1.2 christos 1358 1.2 christos p += 2; 1359 1.2 christos if (memcmp (p, "\xff\xff", 2) != 0) 1360 1.2 christos return GSS_S_BAD_MIC; 1361 1.2 christos p = NULL; 1362 1.2 christos 1363 1.2 christos kret = arcfour_mic_key(context, 1364 1.2 christos key, 1365 1.2 christos p0 + 16, /* SGN_CKSUM */ 1366 1.2 christos 8, /* SGN_CKSUM_LEN */ 1367 1.2 christos k6_data, 1368 1.2 christos sizeof(k6_data)); 1369 1.2 christos if (kret) { 1370 1.2 christos *minor_status = kret; 1371 1.2 christos return GSS_S_FAILURE; 1372 1.2 christos } 1373 1.2 christos 1374 1.2 christos { 1375 1.3 christos EVP_CIPHER_CTX *rc4_key; 1376 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1377 1.3 christos EVP_CIPHER_CTX rc4_keys; 1378 1.3 christos rc4_key = &rc4_keys; 1379 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 1380 1.3 christos #else 1381 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 1382 1.3 christos #endif 1383 1.3 christos 1384 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 1385 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 1386 1.5 christos *minor_status = EINVAL; 1387 1.5 christos return GSS_S_FAILURE; 1388 1.5 christos } 1389 1.3 christos EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8); /* SND_SEQ */ 1390 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1391 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 1392 1.3 christos #else 1393 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 1394 1.3 christos #endif 1395 1.2 christos 1396 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 1397 1.2 christos } 1398 1.2 christos 1399 1.2 christos _gsskrb5_decode_be_om_uint32(snd_seq, &seq_number); 1400 1.2 christos 1401 1.2 christos if (ctx->more_flags & LOCAL) { 1402 1.6 christos cmp = (ct_memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4) != 0); 1403 1.2 christos } else { 1404 1.6 christos cmp = (ct_memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4) != 0); 1405 1.2 christos } 1406 1.2 christos if (cmp != 0) { 1407 1.2 christos *minor_status = 0; 1408 1.2 christos return GSS_S_BAD_MIC; 1409 1.2 christos } 1410 1.2 christos 1411 1.2 christos /* keyblock */ 1412 1.2 christos Klocal.keytype = key->keytype; 1413 1.2 christos Klocal.keyvalue.data = Klocaldata; 1414 1.2 christos Klocal.keyvalue.length = sizeof(Klocaldata); 1415 1.2 christos 1416 1.2 christos for (i = 0; i < 16; i++) { 1417 1.2 christos Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; 1418 1.2 christos } 1419 1.2 christos 1420 1.2 christos kret = arcfour_mic_key(context, 1421 1.2 christos &Klocal, 1422 1.2 christos snd_seq, 1423 1.2 christos 4, 1424 1.2 christos k6_data, sizeof(k6_data)); 1425 1.4 christos memset_s(Klocaldata, sizeof(Klocaldata), 0, sizeof(Klocaldata)); 1426 1.2 christos if (kret) { 1427 1.2 christos *minor_status = kret; 1428 1.2 christos return GSS_S_FAILURE; 1429 1.2 christos } 1430 1.2 christos 1431 1.2 christos if (conf_state == 1) { 1432 1.3 christos EVP_CIPHER_CTX *rc4_key; 1433 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1434 1.3 christos EVP_CIPHER_CTX rc4_keys; 1435 1.3 christos rc4_key = &rc4_keys; 1436 1.3 christos EVP_CIPHER_CTX_init(rc4_key); 1437 1.3 christos #else 1438 1.3 christos rc4_key = EVP_CIPHER_CTX_new(); 1439 1.3 christos #endif 1440 1.2 christos 1441 1.5 christos if (!EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1)) { 1442 1.5 christos *minor_status = EINVAL; 1443 1.5 christos return GSS_S_FAILURE; 1444 1.5 christos } 1445 1.2 christos 1446 1.2 christos /* Confounder */ 1447 1.3 christos EVP_Cipher(rc4_key, Confounder, p0 + 24, 8); 1448 1.2 christos 1449 1.2 christos /* Data */ 1450 1.2 christos for (i = 0; i < iov_count; i++) { 1451 1.2 christos switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) { 1452 1.2 christos case GSS_IOV_BUFFER_TYPE_DATA: 1453 1.2 christos break; 1454 1.2 christos default: 1455 1.2 christos continue; 1456 1.2 christos } 1457 1.2 christos 1458 1.3 christos EVP_Cipher(rc4_key, iov[i].buffer.value, 1459 1.2 christos iov[i].buffer.value, iov[i].buffer.length); 1460 1.2 christos } 1461 1.2 christos 1462 1.2 christos /* Padding */ 1463 1.2 christos if (padding) { 1464 1.3 christos EVP_Cipher(rc4_key, padding->buffer.value, 1465 1.2 christos padding->buffer.value, padding->buffer.length); 1466 1.2 christos } 1467 1.2 christos 1468 1.3 christos #if OPENSSL_VERSION_NUMBER < 0x10100000UL 1469 1.3 christos EVP_CIPHER_CTX_cleanup(rc4_key); 1470 1.3 christos #else 1471 1.3 christos EVP_CIPHER_CTX_free(rc4_key); 1472 1.3 christos #endif 1473 1.2 christos } else { 1474 1.2 christos /* Confounder */ 1475 1.2 christos memcpy(Confounder, p0 + 24, 8); 1476 1.2 christos } 1477 1.4 christos memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data)); 1478 1.2 christos 1479 1.2 christos /* Prepare the buffer for signing */ 1480 1.2 christos kret = arcfour_mic_cksum_iov(context, 1481 1.2 christos key, KRB5_KU_USAGE_SEAL, 1482 1.2 christos cksum_data, sizeof(cksum_data), 1483 1.2 christos p0, 8, 1484 1.2 christos Confounder, sizeof(Confounder), 1485 1.2 christos iov, iov_count, 1486 1.2 christos padding); 1487 1.2 christos if (kret) { 1488 1.2 christos *minor_status = kret; 1489 1.2 christos return GSS_S_FAILURE; 1490 1.2 christos } 1491 1.2 christos 1492 1.2 christos cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ 1493 1.2 christos if (cmp != 0) { 1494 1.2 christos *minor_status = 0; 1495 1.2 christos return GSS_S_BAD_MIC; 1496 1.2 christos } 1497 1.2 christos 1498 1.2 christos if (padding) { 1499 1.2 christos size_t plen; 1500 1.2 christos 1501 1.2 christos ret = _gssapi_verify_pad(&padding->buffer, 1, &plen); 1502 1.2 christos if (ret) { 1503 1.2 christos *minor_status = 0; 1504 1.2 christos return ret; 1505 1.2 christos } 1506 1.2 christos } 1507 1.2 christos 1508 1.2 christos HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 1509 1.2 christos ret = _gssapi_msg_order_check(ctx->order, seq_number); 1510 1.2 christos HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 1511 1.2 christos if (ret != 0) { 1512 1.2 christos return ret; 1513 1.2 christos } 1514 1.2 christos 1515 1.2 christos if (pconf_state) { 1516 1.2 christos *pconf_state = conf_state; 1517 1.2 christos } 1518 1.2 christos 1519 1.2 christos *minor_status = 0; 1520 1.2 christos return GSS_S_COMPLETE; 1521 1.2 christos } 1522