#include "k5-int.h"
#include "gssapiP_krb5.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
int
kg_confounder_size(context, key)
krb5_context context;
krb5_keyblock *key;
{
krb5_error_code code;
size_t blocksize;
if (key->enctype == ENCTYPE_ARCFOUR_HMAC)
return 8;
code = krb5_c_block_size(context, key->enctype, &blocksize);
if (code)
return(-1);
return(blocksize);
}
krb5_error_code
kg_make_confounder(context, key, buf)
krb5_context context;
krb5_keyblock *key;
unsigned char *buf;
{
krb5_error_code code;
size_t blocksize;
krb5_data lrandom;
code = krb5_c_block_size(context, key->enctype, &blocksize);
if (code)
return(code);
lrandom.length = blocksize;
lrandom.data = buf;
return(krb5_c_random_make_octets(context, &lrandom));
}
krb5_error_code
kg_encrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
unsigned int length;
{
krb5_error_code code;
size_t blocksize;
krb5_data ivd, *pivd, inputd;
krb5_enc_data outputd;
if (iv) {
code = krb5_c_block_size(context, key->enctype, &blocksize);
if (code)
return(code);
ivd.length = blocksize;
ivd.data = malloc(ivd.length);
if (ivd.data == NULL)
return ENOMEM;
memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
}
inputd.length = length;
inputd.data = in;
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
if (pivd != NULL)
free(pivd->data);
return code;
}
krb5_error_code
kg_decrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
unsigned int length;
{
krb5_error_code code;
size_t blocksize;
krb5_data ivd, *pivd, outputd;
krb5_enc_data inputd;
if (iv) {
code = krb5_c_block_size(context, key->enctype, &blocksize);
if (code)
return(code);
ivd.length = blocksize;
ivd.data = malloc(ivd.length);
if (ivd.data == NULL)
return ENOMEM;
memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
}
inputd.enctype = ENCTYPE_UNKNOWN;
inputd.ciphertext.length = length;
inputd.ciphertext.data = in;
outputd.length = length;
outputd.data = out;
code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
if (pivd != NULL)
free(pivd->data);
return code;
}
krb5_error_code
kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage,
const unsigned char *kd_data, size_t kd_data_len,
const unsigned char *input_buf, size_t input_len,
unsigned char *output_buf)
{
krb5_error_code code;
krb5_data input, output;
krb5int_access kaccess;
krb5_keyblock seq_enc_key, usage_key;
unsigned char t[4];
usage_key.length = longterm_key->length;
usage_key.contents = malloc(usage_key.length);
if (usage_key.contents == NULL)
return (ENOMEM);
seq_enc_key.length = longterm_key->length;
seq_enc_key.contents = malloc(seq_enc_key.length);
if (seq_enc_key.contents == NULL) {
free ((void *) usage_key.contents);
return (ENOMEM);
}
code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
if (code)
goto cleanup_arcfour;
t[0] = ms_usage &0xff;
t[1] = (ms_usage>>8) & 0xff;
t[2] = (ms_usage>>16) & 0xff;
t[3] = (ms_usage>>24) & 0xff;
input.data = (void *) &t;
input.length = 4;
output.data = (void *) usage_key.contents;
output.length = usage_key.length;
code = (*kaccess.krb5_hmac) (kaccess.md5_hash_provider,
longterm_key, 1, &input, &output);
if (code)
goto cleanup_arcfour;
input.data = ( void *) kd_data;
input.length = kd_data_len;
output.data = (void *) seq_enc_key.contents;
code = (*kaccess.krb5_hmac) (kaccess.md5_hash_provider,
&usage_key, 1, &input, &output);
if (code)
goto cleanup_arcfour;
input.data = ( void * ) input_buf;
input.length = input_len;
output.data = (void * ) output_buf;
output.length = input_len;
code = ((*kaccess.arcfour_enc_provider->encrypt)(
&seq_enc_key, 0,
&input, &output));
cleanup_arcfour:
memset ((void *) seq_enc_key.contents, 0, seq_enc_key.length);
memset ((void *) usage_key.contents, 0, usage_key.length);
free ((void *) usage_key.contents);
free ((void *) seq_enc_key.contents);
return (code);
}