Path: blob/main/crypto/heimdal/lib/gssapi/krb5/arcfour.c
34923 views
/*1* Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "gsskrb5_locl.h"3435/*36* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt37*38* The arcfour message have the following formats:39*40* MIC token41* TOK_ID[2] = 01 0142* SGN_ALG[2] = 11 0043* Filler[4]44* SND_SEQ[8]45* SGN_CKSUM[8]46*47* WRAP token48* TOK_ID[2] = 02 0149* SGN_ALG[2];50* SEAL_ALG[2]51* Filler[2]52* SND_SEQ[2]53* SGN_CKSUM[8]54* Confounder[8]55*/5657/*58* WRAP in DCE-style have a fixed size header, the oid and length over59* the WRAP header is a total of60* GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE +61* GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead,62* remember the 2 bytes from APPL [0] SEQ).63*/6465#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 3266#define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13676869static krb5_error_code70arcfour_mic_key(krb5_context context, krb5_keyblock *key,71void *cksum_data, size_t cksum_size,72void *key6_data, size_t key6_size)73{74krb5_error_code ret;7576Checksum cksum_k5;77krb5_keyblock key5;78char k5_data[16];7980Checksum cksum_k6;8182char T[4];8384memset(T, 0, 4);85cksum_k5.checksum.data = k5_data;86cksum_k5.checksum.length = sizeof(k5_data);8788if (key->keytype == ENCTYPE_ARCFOUR_HMAC_MD5_56) {89char L40[14] = "fortybits";9091memcpy(L40 + 10, T, sizeof(T));92ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,93L40, 14, 0, key, &cksum_k5);94memset(&k5_data[7], 0xAB, 9);95} else {96ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,97T, 4, 0, key, &cksum_k5);98}99if (ret)100return ret;101102key5.keytype = ENCTYPE_ARCFOUR_HMAC_MD5;103key5.keyvalue = cksum_k5.checksum;104105cksum_k6.checksum.data = key6_data;106cksum_k6.checksum.length = key6_size;107108return krb5_hmac(context, CKSUMTYPE_RSA_MD5,109cksum_data, cksum_size, 0, &key5, &cksum_k6);110}111112113static krb5_error_code114arcfour_mic_cksum(krb5_context context,115krb5_keyblock *key, unsigned usage,116u_char *sgn_cksum, size_t sgn_cksum_sz,117const u_char *v1, size_t l1,118const void *v2, size_t l2,119const void *v3, size_t l3)120{121Checksum CKSUM;122u_char *ptr;123size_t len;124krb5_crypto crypto;125krb5_error_code ret;126127assert(sgn_cksum_sz == 8);128129len = l1 + l2 + l3;130131ptr = malloc(len);132if (ptr == NULL)133return ENOMEM;134135memcpy(ptr, v1, l1);136memcpy(ptr + l1, v2, l2);137memcpy(ptr + l1 + l2, v3, l3);138139ret = krb5_crypto_init(context, key, 0, &crypto);140if (ret) {141free(ptr);142return ret;143}144145ret = krb5_create_checksum(context,146crypto,147usage,1480,149ptr, len,150&CKSUM);151free(ptr);152if (ret == 0) {153memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);154free_Checksum(&CKSUM);155}156krb5_crypto_destroy(context, crypto);157158return ret;159}160161162OM_uint32163_gssapi_get_mic_arcfour(OM_uint32 * minor_status,164const gsskrb5_ctx context_handle,165krb5_context context,166gss_qop_t qop_req,167const gss_buffer_t message_buffer,168gss_buffer_t message_token,169krb5_keyblock *key)170{171krb5_error_code ret;172int32_t seq_number;173size_t len, total_len;174u_char k6_data[16], *p0, *p;175EVP_CIPHER_CTX *rc4_key;176177_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);178179message_token->length = total_len;180message_token->value = malloc (total_len);181if (message_token->value == NULL) {182*minor_status = ENOMEM;183return GSS_S_FAILURE;184}185186p0 = _gssapi_make_mech_header(message_token->value,187len,188GSS_KRB5_MECHANISM);189p = p0;190191*p++ = 0x01; /* TOK_ID */192*p++ = 0x01;193*p++ = 0x11; /* SGN_ALG */194*p++ = 0x00;195*p++ = 0xff; /* Filler */196*p++ = 0xff;197*p++ = 0xff;198*p++ = 0xff;199200p = NULL;201202ret = arcfour_mic_cksum(context,203key, KRB5_KU_USAGE_SIGN,204p0 + 16, 8, /* SGN_CKSUM */205p0, 8, /* TOK_ID, SGN_ALG, Filer */206message_buffer->value, message_buffer->length,207NULL, 0);208if (ret) {209_gsskrb5_release_buffer(minor_status, message_token);210*minor_status = ret;211return GSS_S_FAILURE;212}213214ret = arcfour_mic_key(context, key,215p0 + 16, 8, /* SGN_CKSUM */216k6_data, sizeof(k6_data));217if (ret) {218_gsskrb5_release_buffer(minor_status, message_token);219*minor_status = ret;220return GSS_S_FAILURE;221}222223HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);224krb5_auth_con_getlocalseqnumber (context,225context_handle->auth_context,226&seq_number);227p = p0 + 8; /* SND_SEQ */228_gsskrb5_encode_be_om_uint32(seq_number, p);229230krb5_auth_con_setlocalseqnumber (context,231context_handle->auth_context,232++seq_number);233HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);234235memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);236237rc4_key = EVP_CIPHER_CTX_new();238if (rc4_key == NULL) {239_gsskrb5_release_buffer(minor_status, message_token);240*minor_status = ENOMEM;241return GSS_S_FAILURE;242}243244EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);245EVP_Cipher(rc4_key, p, p, 8);246EVP_CIPHER_CTX_free(rc4_key);247248memset(k6_data, 0, sizeof(k6_data));249250*minor_status = 0;251return GSS_S_COMPLETE;252}253254255OM_uint32256_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,257const gsskrb5_ctx context_handle,258krb5_context context,259const gss_buffer_t message_buffer,260const gss_buffer_t token_buffer,261gss_qop_t * qop_state,262krb5_keyblock *key,263const char *type)264{265krb5_error_code ret;266uint32_t seq_number;267OM_uint32 omret;268u_char SND_SEQ[8], cksum_data[8], *p;269char k6_data[16];270int cmp;271272if (qop_state)273*qop_state = 0;274275p = token_buffer->value;276omret = _gsskrb5_verify_header (&p,277token_buffer->length,278type,279GSS_KRB5_MECHANISM);280if (omret)281return omret;282283if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */284return GSS_S_BAD_SIG;285p += 2;286if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)287return GSS_S_BAD_MIC;288p += 4;289290ret = arcfour_mic_cksum(context,291key, KRB5_KU_USAGE_SIGN,292cksum_data, sizeof(cksum_data),293p - 8, 8,294message_buffer->value, message_buffer->length,295NULL, 0);296if (ret) {297*minor_status = ret;298return GSS_S_FAILURE;299}300301ret = arcfour_mic_key(context, key,302cksum_data, sizeof(cksum_data),303k6_data, sizeof(k6_data));304if (ret) {305*minor_status = ret;306return GSS_S_FAILURE;307}308309cmp = (ct_memcmp(cksum_data, p + 8, 8) != 0);310if (cmp) {311*minor_status = 0;312return GSS_S_BAD_MIC;313}314315{316EVP_CIPHER_CTX *rc4_key;317318rc4_key = EVP_CIPHER_CTX_new();319if (rc4_key == NULL) {320*minor_status = ENOMEM;321return GSS_S_FAILURE;322}323EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);324EVP_Cipher(rc4_key, SND_SEQ, p, 8);325EVP_CIPHER_CTX_free(rc4_key);326327memset(k6_data, 0, sizeof(k6_data));328}329330_gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);331332if (context_handle->more_flags & LOCAL)333cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0);334else335cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0);336337memset(SND_SEQ, 0, sizeof(SND_SEQ));338if (cmp != 0) {339*minor_status = 0;340return GSS_S_BAD_MIC;341}342343HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);344omret = _gssapi_msg_order_check(context_handle->order, seq_number);345HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);346if (omret)347return omret;348349*minor_status = 0;350return GSS_S_COMPLETE;351}352353OM_uint32354_gssapi_wrap_arcfour(OM_uint32 * minor_status,355const gsskrb5_ctx context_handle,356krb5_context context,357int conf_req_flag,358gss_qop_t qop_req,359const gss_buffer_t input_message_buffer,360int * conf_state,361gss_buffer_t output_message_buffer,362krb5_keyblock *key)363{364u_char Klocaldata[16], k6_data[16], *p, *p0;365size_t len, total_len, datalen;366krb5_keyblock Klocal;367krb5_error_code ret;368int32_t seq_number;369370if (conf_state)371*conf_state = 0;372373datalen = input_message_buffer->length;374375if (IS_DCE_STYLE(context_handle)) {376len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;377_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);378total_len += datalen;379} else {380datalen += 1; /* padding */381len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;382_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);383}384385output_message_buffer->length = total_len;386output_message_buffer->value = malloc (total_len);387if (output_message_buffer->value == NULL) {388*minor_status = ENOMEM;389return GSS_S_FAILURE;390}391392p0 = _gssapi_make_mech_header(output_message_buffer->value,393len,394GSS_KRB5_MECHANISM);395p = p0;396397*p++ = 0x02; /* TOK_ID */398*p++ = 0x01;399*p++ = 0x11; /* SGN_ALG */400*p++ = 0x00;401if (conf_req_flag) {402*p++ = 0x10; /* SEAL_ALG */403*p++ = 0x00;404} else {405*p++ = 0xff; /* SEAL_ALG */406*p++ = 0xff;407}408*p++ = 0xff; /* Filler */409*p++ = 0xff;410411p = NULL;412413HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);414krb5_auth_con_getlocalseqnumber (context,415context_handle->auth_context,416&seq_number);417418_gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);419420krb5_auth_con_setlocalseqnumber (context,421context_handle->auth_context,422++seq_number);423HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);424425memset (p0 + 8 + 4,426(context_handle->more_flags & LOCAL) ? 0 : 0xff,4274);428429krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */430431/* p points to data */432p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;433memcpy(p, input_message_buffer->value, input_message_buffer->length);434435if (!IS_DCE_STYLE(context_handle))436p[input_message_buffer->length] = 1; /* padding */437438ret = arcfour_mic_cksum(context,439key, KRB5_KU_USAGE_SEAL,440p0 + 16, 8, /* SGN_CKSUM */441p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */442p0 + 24, 8, /* Confounder */443p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,444datalen);445if (ret) {446*minor_status = ret;447_gsskrb5_release_buffer(minor_status, output_message_buffer);448return GSS_S_FAILURE;449}450451{452int i;453454Klocal.keytype = key->keytype;455Klocal.keyvalue.data = Klocaldata;456Klocal.keyvalue.length = sizeof(Klocaldata);457458for (i = 0; i < 16; i++)459Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;460}461ret = arcfour_mic_key(context, &Klocal,462p0 + 8, 4, /* SND_SEQ */463k6_data, sizeof(k6_data));464memset(Klocaldata, 0, sizeof(Klocaldata));465if (ret) {466_gsskrb5_release_buffer(minor_status, output_message_buffer);467*minor_status = ret;468return GSS_S_FAILURE;469}470471472if(conf_req_flag) {473EVP_CIPHER_CTX *rc4_key;474475rc4_key = EVP_CIPHER_CTX_new();476if (rc4_key == NULL) {477_gsskrb5_release_buffer(minor_status, output_message_buffer);478*minor_status = ENOMEM;479return GSS_S_FAILURE;480}481EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);482EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen);483EVP_CIPHER_CTX_free(rc4_key);484}485memset(k6_data, 0, sizeof(k6_data));486487ret = arcfour_mic_key(context, key,488p0 + 16, 8, /* SGN_CKSUM */489k6_data, sizeof(k6_data));490if (ret) {491_gsskrb5_release_buffer(minor_status, output_message_buffer);492*minor_status = ret;493return GSS_S_FAILURE;494}495496{497EVP_CIPHER_CTX *rc4_key;498499rc4_key = EVP_CIPHER_CTX_new();500if (rc4_key == NULL) {501_gsskrb5_release_buffer(minor_status, output_message_buffer);502*minor_status = ENOMEM;503return GSS_S_FAILURE;504}505EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);506EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);507EVP_CIPHER_CTX_free(rc4_key);508memset(k6_data, 0, sizeof(k6_data));509}510511if (conf_state)512*conf_state = conf_req_flag;513514*minor_status = 0;515return GSS_S_COMPLETE;516}517518OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,519const gsskrb5_ctx context_handle,520krb5_context context,521const gss_buffer_t input_message_buffer,522gss_buffer_t output_message_buffer,523int *conf_state,524gss_qop_t *qop_state,525krb5_keyblock *key)526{527u_char Klocaldata[16];528krb5_keyblock Klocal;529krb5_error_code ret;530uint32_t seq_number;531size_t datalen;532OM_uint32 omret;533u_char k6_data[16], SND_SEQ[8], Confounder[8];534u_char cksum_data[8];535u_char *p, *p0;536int cmp;537int conf_flag;538size_t padlen = 0, len;539540if (conf_state)541*conf_state = 0;542if (qop_state)543*qop_state = 0;544545p0 = input_message_buffer->value;546547if (IS_DCE_STYLE(context_handle)) {548len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +549GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;550if (input_message_buffer->length < len)551return GSS_S_BAD_MECH;552} else {553len = input_message_buffer->length;554}555556omret = _gssapi_verify_mech_header(&p0,557len,558GSS_KRB5_MECHANISM);559if (omret)560return omret;561562/* length of mech header */563len = (p0 - (u_char *)input_message_buffer->value) +564GSS_ARCFOUR_WRAP_TOKEN_SIZE;565566if (len > input_message_buffer->length)567return GSS_S_BAD_MECH;568569/* length of data */570datalen = input_message_buffer->length - len;571572p = p0;573574if (memcmp(p, "\x02\x01", 2) != 0)575return GSS_S_BAD_SIG;576p += 2;577if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */578return GSS_S_BAD_SIG;579p += 2;580581if (memcmp (p, "\x10\x00", 2) == 0)582conf_flag = 1;583else if (memcmp (p, "\xff\xff", 2) == 0)584conf_flag = 0;585else586return GSS_S_BAD_SIG;587588p += 2;589if (memcmp (p, "\xff\xff", 2) != 0)590return GSS_S_BAD_MIC;591p = NULL;592593ret = arcfour_mic_key(context, key,594p0 + 16, 8, /* SGN_CKSUM */595k6_data, sizeof(k6_data));596if (ret) {597*minor_status = ret;598return GSS_S_FAILURE;599}600601{602EVP_CIPHER_CTX *rc4_key;603604rc4_key = EVP_CIPHER_CTX_new();605if (rc4_key == NULL) {606*minor_status = ENOMEM;607return GSS_S_FAILURE;608}609EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);610EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8);611EVP_CIPHER_CTX_free(rc4_key);612memset(k6_data, 0, sizeof(k6_data));613}614615_gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);616617if (context_handle->more_flags & LOCAL)618cmp = (ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4) != 0);619else620cmp = (ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4) != 0);621622if (cmp != 0) {623*minor_status = 0;624return GSS_S_BAD_MIC;625}626627{628int i;629630Klocal.keytype = key->keytype;631Klocal.keyvalue.data = Klocaldata;632Klocal.keyvalue.length = sizeof(Klocaldata);633634for (i = 0; i < 16; i++)635Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;636}637ret = arcfour_mic_key(context, &Klocal,638SND_SEQ, 4,639k6_data, sizeof(k6_data));640memset(Klocaldata, 0, sizeof(Klocaldata));641if (ret) {642*minor_status = ret;643return GSS_S_FAILURE;644}645646output_message_buffer->value = malloc(datalen);647if (output_message_buffer->value == NULL) {648*minor_status = ENOMEM;649return GSS_S_FAILURE;650}651output_message_buffer->length = datalen;652653if(conf_flag) {654EVP_CIPHER_CTX *rc4_key;655656rc4_key = EVP_CIPHER_CTX_new();657if (rc4_key == NULL) {658_gsskrb5_release_buffer(minor_status, output_message_buffer);659*minor_status = ENOMEM;660return GSS_S_FAILURE;661}662EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);663EVP_Cipher(rc4_key, Confounder, p0 + 24, 8);664EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);665EVP_CIPHER_CTX_free(rc4_key);666} else {667memcpy(Confounder, p0 + 24, 8); /* Confounder */668memcpy(output_message_buffer->value,669p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,670datalen);671}672memset(k6_data, 0, sizeof(k6_data));673674if (!IS_DCE_STYLE(context_handle)) {675ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);676if (ret) {677_gsskrb5_release_buffer(minor_status, output_message_buffer);678*minor_status = 0;679return ret;680}681output_message_buffer->length -= padlen;682}683684ret = arcfour_mic_cksum(context,685key, KRB5_KU_USAGE_SEAL,686cksum_data, sizeof(cksum_data),687p0, 8,688Confounder, sizeof(Confounder),689output_message_buffer->value,690output_message_buffer->length + padlen);691if (ret) {692_gsskrb5_release_buffer(minor_status, output_message_buffer);693*minor_status = ret;694return GSS_S_FAILURE;695}696697cmp = (ct_memcmp(cksum_data, p0 + 16, 8) != 0); /* SGN_CKSUM */698if (cmp) {699_gsskrb5_release_buffer(minor_status, output_message_buffer);700*minor_status = 0;701return GSS_S_BAD_MIC;702}703704HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);705omret = _gssapi_msg_order_check(context_handle->order, seq_number);706HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);707if (omret)708return omret;709710if (conf_state)711*conf_state = conf_flag;712713*minor_status = 0;714return GSS_S_COMPLETE;715}716717static OM_uint32718max_wrap_length_arcfour(const gsskrb5_ctx ctx,719krb5_crypto crypto,720size_t input_length,721OM_uint32 *max_input_size)722{723/*724* if GSS_C_DCE_STYLE is in use:725* - we only need to encapsulate the WRAP token726* However, since this is a fixed since, we just727*/728if (IS_DCE_STYLE(ctx)) {729size_t len, total_len;730731len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;732_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);733734if (input_length < len)735*max_input_size = 0;736else737*max_input_size = input_length - len;738739} else {740size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE;741size_t blocksize = 8;742size_t len, total_len;743744len = 8 + input_length + blocksize + extrasize;745746_gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);747748total_len -= input_length; /* token length */749if (total_len < input_length) {750*max_input_size = (input_length - total_len);751(*max_input_size) &= (~(OM_uint32)(blocksize - 1));752} else {753*max_input_size = 0;754}755}756757return GSS_S_COMPLETE;758}759760OM_uint32761_gssapi_wrap_size_arcfour(OM_uint32 *minor_status,762const gsskrb5_ctx ctx,763krb5_context context,764int conf_req_flag,765gss_qop_t qop_req,766OM_uint32 req_output_size,767OM_uint32 *max_input_size,768krb5_keyblock *key)769{770krb5_error_code ret;771krb5_crypto crypto;772773ret = krb5_crypto_init(context, key, 0, &crypto);774if (ret != 0) {775*minor_status = ret;776return GSS_S_FAILURE;777}778779ret = max_wrap_length_arcfour(ctx, crypto,780req_output_size, max_input_size);781if (ret != 0) {782*minor_status = ret;783krb5_crypto_destroy(context, crypto);784return GSS_S_FAILURE;785}786787krb5_crypto_destroy(context, crypto);788789return GSS_S_COMPLETE;790}791792793