1178825Sdfr/* 2233294Sstas * Copyright (c) 2007 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34233294Sstas#include "gsskrb5_locl.h" 35178825Sdfr 36233294SstasOM_uint32 GSSAPI_CALLCONV 37178825Sdfr_gsskrb5_pseudo_random(OM_uint32 *minor_status, 38178825Sdfr gss_ctx_id_t context_handle, 39178825Sdfr int prf_key, 40178825Sdfr const gss_buffer_t prf_in, 41178825Sdfr ssize_t desired_output_len, 42178825Sdfr gss_buffer_t prf_out) 43178825Sdfr{ 44178825Sdfr gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle; 45178825Sdfr krb5_context context; 46178825Sdfr krb5_error_code ret; 47178825Sdfr krb5_crypto crypto; 48178825Sdfr krb5_data input, output; 49178825Sdfr uint32_t num; 50233294Sstas OM_uint32 junk; 51178825Sdfr unsigned char *p; 52178825Sdfr krb5_keyblock *key = NULL; 53233294Sstas size_t dol; 54178825Sdfr 55178825Sdfr if (ctx == NULL) { 56178825Sdfr *minor_status = 0; 57178825Sdfr return GSS_S_NO_CONTEXT; 58178825Sdfr } 59178825Sdfr 60233294Sstas if (desired_output_len <= 0 || prf_in->length + 4 < prf_in->length) { 61178825Sdfr *minor_status = 0; 62178825Sdfr return GSS_S_FAILURE; 63178825Sdfr } 64233294Sstas dol = desired_output_len; 65178825Sdfr 66178825Sdfr GSSAPI_KRB5_INIT (&context); 67178825Sdfr 68178825Sdfr switch(prf_key) { 69178825Sdfr case GSS_C_PRF_KEY_FULL: 70178825Sdfr _gsskrb5i_get_acceptor_subkey(ctx, context, &key); 71178825Sdfr break; 72178825Sdfr case GSS_C_PRF_KEY_PARTIAL: 73178825Sdfr _gsskrb5i_get_initiator_subkey(ctx, context, &key); 74178825Sdfr break; 75178825Sdfr default: 76233294Sstas _gsskrb5_set_status(EINVAL, "unknown kerberos prf_key"); 77233294Sstas *minor_status = EINVAL; 78178825Sdfr return GSS_S_FAILURE; 79178825Sdfr } 80178825Sdfr 81178825Sdfr if (key == NULL) { 82233294Sstas _gsskrb5_set_status(EINVAL, "no prf_key found"); 83233294Sstas *minor_status = EINVAL; 84178825Sdfr return GSS_S_FAILURE; 85178825Sdfr } 86178825Sdfr 87178825Sdfr ret = krb5_crypto_init(context, key, 0, &crypto); 88178825Sdfr krb5_free_keyblock (context, key); 89178825Sdfr if (ret) { 90178825Sdfr *minor_status = ret; 91178825Sdfr return GSS_S_FAILURE; 92178825Sdfr } 93178825Sdfr 94233294Sstas prf_out->value = malloc(dol); 95178825Sdfr if (prf_out->value == NULL) { 96233294Sstas _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory"); 97178825Sdfr *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG; 98178825Sdfr krb5_crypto_destroy(context, crypto); 99178825Sdfr return GSS_S_FAILURE; 100178825Sdfr } 101233294Sstas prf_out->length = dol; 102178825Sdfr 103178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 104178825Sdfr 105178825Sdfr input.length = prf_in->length + 4; 106178825Sdfr input.data = malloc(prf_in->length + 4); 107178825Sdfr if (input.data == NULL) { 108233294Sstas _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory"); 109178825Sdfr *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG; 110178825Sdfr gss_release_buffer(&junk, prf_out); 111178825Sdfr krb5_crypto_destroy(context, crypto); 112178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 113178825Sdfr return GSS_S_FAILURE; 114178825Sdfr } 115233294Sstas memcpy(((uint8_t *)input.data) + 4, prf_in->value, prf_in->length); 116178825Sdfr 117178825Sdfr num = 0; 118178825Sdfr p = prf_out->value; 119233294Sstas while(dol > 0) { 120233294Sstas size_t tsize; 121233294Sstas 122259447Sbjk _gsskrb5_encode_be_om_uint32(num, input.data); 123233294Sstas 124178825Sdfr ret = krb5_crypto_prf(context, crypto, &input, &output); 125178825Sdfr if (ret) { 126178825Sdfr *minor_status = ret; 127178825Sdfr free(input.data); 128178825Sdfr gss_release_buffer(&junk, prf_out); 129178825Sdfr krb5_crypto_destroy(context, crypto); 130178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 131178825Sdfr return GSS_S_FAILURE; 132178825Sdfr } 133233294Sstas 134233294Sstas tsize = min(dol, output.length); 135233294Sstas memcpy(p, output.data, tsize); 136259447Sbjk p += tsize; 137233294Sstas dol -= tsize; 138178825Sdfr krb5_data_free(&output); 139178825Sdfr num++; 140178825Sdfr } 141233294Sstas free(input.data); 142178825Sdfr 143178825Sdfr krb5_crypto_destroy(context, crypto); 144178825Sdfr 145178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 146178825Sdfr 147178825Sdfr return GSS_S_COMPLETE; 148178825Sdfr} 149