root/source4/heimdal/lib/gssapi/krb5/prf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _gsskrb5_pseudo_random

   1 /*
   2  * Copyright (c) 2007 Kungliga Tekniska Högskolan
   3  * (Royal Institute of Technology, Stockholm, Sweden).
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  *
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * 3. Neither the name of the Institute nor the names of its contributors
  18  *    may be used to endorse or promote products derived from this software
  19  *    without specific prior written permission.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31  * SUCH DAMAGE.
  32  */
  33 
  34 #include "krb5/gsskrb5_locl.h"
  35 
  36 RCSID("$Id$");
  37 
  38 OM_uint32
  39 _gsskrb5_pseudo_random(OM_uint32 *minor_status,
     /* [<][>][^][v][top][bottom][index][help] */
  40                        gss_ctx_id_t context_handle,
  41                        int prf_key,
  42                        const gss_buffer_t prf_in,
  43                        ssize_t desired_output_len,
  44                        gss_buffer_t prf_out)
  45 {
  46     gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
  47     krb5_context context;
  48     krb5_error_code ret;
  49     krb5_crypto crypto;
  50     krb5_data input, output;
  51     uint32_t num;
  52     unsigned char *p;
  53     krb5_keyblock *key = NULL;
  54 
  55     if (ctx == NULL) {
  56         *minor_status = 0;
  57         return GSS_S_NO_CONTEXT;
  58     }
  59 
  60     if (desired_output_len <= 0) {
  61         *minor_status = 0;
  62         return GSS_S_FAILURE;
  63     }
  64 
  65     GSSAPI_KRB5_INIT (&context);
  66 
  67     switch(prf_key) {
  68     case GSS_C_PRF_KEY_FULL:
  69         _gsskrb5i_get_acceptor_subkey(ctx, context, &key);
  70         break;
  71     case GSS_C_PRF_KEY_PARTIAL:
  72         _gsskrb5i_get_initiator_subkey(ctx, context, &key);
  73         break;
  74     default:
  75         _gsskrb5_set_status(EINVAL, "unknown kerberos prf_key");
  76         *minor_status = EINVAL;
  77         return GSS_S_FAILURE;
  78     }
  79 
  80     if (key == NULL) {
  81         _gsskrb5_set_status(EINVAL, "no prf_key found");
  82         *minor_status = EINVAL;
  83         return GSS_S_FAILURE;
  84     }
  85 
  86     ret = krb5_crypto_init(context, key, 0, &crypto);
  87     krb5_free_keyblock (context, key);
  88     if (ret) {
  89         *minor_status = ret;
  90         return GSS_S_FAILURE;
  91     }
  92 
  93     prf_out->value = malloc(desired_output_len);
  94     if (prf_out->value == NULL) {
  95         _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
  96         *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
  97         krb5_crypto_destroy(context, crypto);
  98         return GSS_S_FAILURE;
  99     }
 100     prf_out->length = desired_output_len;
 101 
 102     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
 103 
 104     input.length = prf_in->length + 4;
 105     input.data = malloc(prf_in->length + 4);
 106     if (input.data == NULL) {
 107         OM_uint32 junk;
 108         _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
 109         *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
 110         gss_release_buffer(&junk, prf_out);
 111         krb5_crypto_destroy(context, crypto);
 112         HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 113         return GSS_S_FAILURE;
 114     }
 115     memcpy(((unsigned char *)input.data) + 4, prf_in->value, prf_in->length);
 116 
 117     num = 0;
 118     p = prf_out->value;
 119     while(desired_output_len > 0) {
 120         _gsskrb5_encode_om_uint32(num, input.data);
 121         ret = krb5_crypto_prf(context, crypto, &input, &output);
 122         if (ret) {
 123             OM_uint32 junk;
 124             *minor_status = ret;
 125             free(input.data);
 126             gss_release_buffer(&junk, prf_out);
 127             krb5_crypto_destroy(context, crypto);
 128             HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 129             return GSS_S_FAILURE;
 130         }
 131         memcpy(p, output.data, min(desired_output_len, output.length));
 132         p += output.length;
 133         desired_output_len -= output.length;
 134         krb5_data_free(&output);
 135         num++;
 136     }
 137 
 138     krb5_crypto_destroy(context, crypto);
 139 
 140     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
 141 
 142     return GSS_S_COMPLETE;
 143 }

/* [<][>][^][v][top][bottom][index][help] */