#include "k5-int.h"
#include "keyhash_provider.h"
#include "arcfour-int.h"
#include <CommonCrypto/CommonDigest.h>
#include "hash_provider.h"
static krb5_error_code
k5_hmac_md5_hash (const krb5_keyblock *key, krb5_keyusage usage,
const krb5_data *iv,
const krb5_data *input, krb5_data *output)
{
krb5_keyusage ms_usage;
krb5_error_code ret;
krb5_keyblock ks;
krb5_data ds, ks_constant, md5tmp;
CC_MD5_CTX ctx;
unsigned char digest[CC_MD5_DIGEST_LENGTH];
char t[4];
ds.length = key->length;
ks.length = key->length;
ds.data = malloc(ds.length);
if (ds.data == NULL)
return ENOMEM;
ks.contents = (void *) ds.data;
ks_constant.data = "signaturekey";
ks_constant.length = strlen(ks_constant.data)+1;
ret = krb5_hmac( &krb5int_hash_md5, key, 1,
&ks_constant, &ds);
if (ret)
goto cleanup;
CC_MD5_Init (&ctx);
ms_usage = krb5int_arcfour_translate_usage (usage);
t[0] = (ms_usage) & 0xff;
t[1] = (ms_usage>>8) & 0xff;
t[2] = (ms_usage >>16) & 0xff;
t[3] = (ms_usage>>24) & 0XFF;
CC_MD5_Update (&ctx, (unsigned char * ) &t, 4);
CC_MD5_Update (&ctx, (unsigned char *) input-> data,
(unsigned int) input->length );
CC_MD5_Final(digest, &ctx);
md5tmp.data = (void *) digest;
md5tmp.length = 16;
ret = krb5_hmac ( &krb5int_hash_md5, &ks, 1, &md5tmp,
output);
cleanup:
memset(&ctx, 0, sizeof(ctx));
memset (ks.contents, 0, ks.length);
free (ks.contents);
return ret;
}
const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5 = {
16,
k5_hmac_md5_hash,
NULL
};