krb5_error_code krb5int_pbkdf2_hmac_sha1(const krb5_data *, unsigned long,
const krb5_data *, const krb5_data *);
+/* These crypto functions are used by GSSAPI via the accessor. */
+
+krb5_error_code
+krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
+ const krb5_data *kd_data, const krb5_data *input,
+ krb5_data *output);
+
+krb5_error_code
+krb5int_arcfour_gsscrypt_iov(const krb5_keyblock *keyblock,
+ krb5_keyusage usage, const krb5_data *kd_data,
+ krb5_crypto_iov *data, size_t num_data);
+
/*
* Attempt to zero memory in a way that compilers won't optimize out.
*
extern void krb5int_prng_cleanup(void);
-/*
- * These declarations are here, so both krb5 and k5crypto
- * can get to them.
- * krb5 needs to get to them so it can make them available to libgssapi.
- */
-extern const struct krb5_enc_provider krb5int_enc_arcfour;
-extern const struct krb5_hash_provider krb5int_hash_md5;
-
-
#ifdef KRB5_OLD_CRYPTO
/* old provider api */
/* To keep happy libraries which are (for now) accessing internal stuff */
/* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 15
+#define KRB5INT_ACCESS_STRUCT_VERSION 16
#ifndef ANAME_SZ
struct ktext; /* from krb.h, for krb524 support */
#endif
typedef struct _krb5int_access {
/* crypto stuff */
- const struct krb5_hash_provider *md5_hash_provider;
- const struct krb5_enc_provider *arcfour_enc_provider;
- krb5_error_code (*hmac)(const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
- unsigned int icount, const krb5_data *input,
- krb5_data *output);
+ krb5_error_code (*arcfour_gsscrypt)(const krb5_keyblock *keyblock,
+ krb5_keyusage usage,
+ const krb5_data *kd_data,
+ const krb5_data *input,
+ krb5_data *output);
+ krb5_error_code (*arcfour_gsscrypt_iov)(const krb5_keyblock *keyblock,
+ krb5_keyusage usage,
+ const krb5_data *kd_data,
+ krb5_crypto_iov *data,
+ size_t num_data);
+
krb5_error_code (*auth_con_get_subkey_enctype)(krb5_context,
krb5_auth_context,
krb5_enctype *);
return krb5int_hmac_keyblock(hash, session_keyblock, 1, &salt, &out_data);
}
-/* Derive an encryption key from a usage key and checksum. */
+/* Derive an encryption key from a usage key and (typically) checksum. */
krb5_error_code
krb5int_arcfour_enc_key(const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
zapfree(comp_checksum.data, comp_checksum.length);
return ret;
}
+
+/* Encrypt or decrypt data for a GSSAPI token. */
+krb5_error_code
+krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
+ const krb5_data *kd_data, const krb5_data *input,
+ krb5_data *output)
+{
+ const struct krb5_enc_provider *enc = &krb5int_enc_arcfour;
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+ krb5_key enc_key;
+ krb5_error_code ret;
+
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive a usage key from the session key and usage. */
+ ret = krb5int_arcfour_usage_key(enc, hash, keyblock, usage,
+ usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the encryption key from the usage key and kd_data. */
+ ret = krb5int_arcfour_enc_key(enc, hash, usage_keyblock, kd_data,
+ enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Encrypt or decrypt (encrypt works for both) the input. */
+ ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
+ if (ret != 0)
+ goto cleanup;
+ ret = (*enc->encrypt)(enc_key, 0, input, output);
+ krb5_k_free_key(NULL, enc_key);
+
+cleanup:
+ krb5int_c_free_keyblock(NULL, usage_keyblock);
+ krb5int_c_free_keyblock(NULL, enc_keyblock);
+ return ret;
+}
#include "k5-int.h"
#include "arcfour.h"
#include "arcfour-int.h"
+#include "hash_provider/hash_provider.h"
#include "aead.h"
/* AEAD */
krb5int_arcfour_encrypt_iov,
krb5int_arcfour_decrypt_iov
};
+
+krb5_error_code
+krb5int_arcfour_gsscrypt_iov(const krb5_keyblock *keyblock,
+ krb5_keyusage usage, const krb5_data *kd_data,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = &krb5int_enc_arcfour;
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+ krb5_key enc_key;
+ krb5_error_code ret;
+
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive a usage key from the session key and usage. */
+ ret = krb5int_arcfour_usage_key(enc, hash, keyblock, usage,
+ usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the encryption key from the usage key and kd_data. */
+ ret = krb5int_arcfour_enc_key(enc, hash, usage_keyblock, kd_data,
+ enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Encrypt or decrypt (encrypt_iov works for both) the input. */
+ ret = krb5_k_create_key(NULL, enc_keyblock, &enc_key);
+ if (ret != 0)
+ goto cleanup;
+ ret = (*enc->encrypt_iov)(enc_key, 0, data, num_data);
+ krb5_k_free_key(NULL, enc_key);
+
+cleanup:
+ krb5int_c_free_keyblock(NULL, usage_keyblock);
+ krb5int_c_free_keyblock(NULL, enc_keyblock);
+ return ret;
+}
*/
#include "prf_int.h"
-//#include <hash_provider/hash_provider.h> /* XXX is this ok? */
+#include "hash_provider/hash_provider.h"
krb5_error_code
krb5int_des_prf (const struct krb5_enc_provider *enc,
krb5int_c_free_keyblock
krb5int_c_init_keyblock
krb5int_hash_md5
-krb5int_hmac_keyblock
krb5int_enc_arcfour
krb5int_hmac
mit_des_fixup_key_parity
krb5int_MD5Final
krb5int_aes_decrypt
krb5int_enc_des3
+krb5int_arcfour_gsscrypt
+krb5int_arcfour_gsscrypt_iov
int iov_count);
krb5_error_code
-kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage,
+kg_arcfour_docrypt (const krb5_keyblock *keyblock, int 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
kg_arcfour_docrypt_iov (krb5_context context,
- const krb5_keyblock *longterm_key , int ms_usage,
+ const krb5_keyblock *keyblock, int usage,
const unsigned char *kd_data, size_t kd_data_len,
gss_iov_buffer_desc *iov,
int iov_count);
}
krb5_error_code
-kg_arcfour_docrypt(const krb5_keyblock *longterm_key , int ms_usage,
+kg_arcfour_docrypt(const krb5_keyblock *keyblock, int 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;
+ krb5_data kd = make_data((char *) kd_data, kd_data_len);
+ krb5_data input = make_data((char *) input_buf, input_len);
+ krb5_data output = make_data(output_buf, input_len);
krb5int_access kaccess;
- krb5_key key;
- krb5_keyblock seq_enc_key, usage_key;
- unsigned char t[14];
- size_t i = 0;
- int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP);
-
- 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;
- if (exportable) {
- memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40));
- i += sizeof(kg_arcfour_l40);
- }
- store_32_le(ms_usage, &t[i]);
- i += 4;
- input.data = (void *) &t;
- input.length = i;
- output.data = (void *) usage_key.contents;
- output.length = usage_key.length;
- code = (*kaccess.hmac)(kaccess.md5_hash_provider, longterm_key, 1,
- &input, &output);
- if (code)
- goto cleanup_arcfour;
- if (exportable)
- memset(usage_key.contents + 7, 0xab, 9);
-
- input.data = ( void *) kd_data;
- input.length = kd_data_len;
- output.data = (void *) seq_enc_key.contents;
- code = (*kaccess.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 = krb5_k_create_key(NULL, &seq_enc_key, &key);
+ code = krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION);
if (code)
- goto cleanup_arcfour;
- code = (*kaccess.arcfour_enc_provider->encrypt)(key, 0, &input, &output);
- krb5_k_free_key(NULL, key);
-cleanup_arcfour:
- memset (seq_enc_key.contents, 0, seq_enc_key.length);
- memset (usage_key.contents, 0, usage_key.length);
- free (usage_key.contents);
- free (seq_enc_key.contents);
- return (code);
+ return code;
+ return (*kaccess.arcfour_gsscrypt)(keyblock, usage, &kd, &input, &output);
}
/* AEAD */
}
krb5_error_code
-kg_arcfour_docrypt_iov(krb5_context context,
- const krb5_keyblock *longterm_key, int ms_usage,
- const unsigned char *kd_data, size_t kd_data_len,
- gss_iov_buffer_desc *iov, int iov_count)
+kg_arcfour_docrypt_iov(krb5_context context, const krb5_keyblock *keyblock,
+ int usage, const unsigned char *kd_data,
+ size_t kd_data_len, gss_iov_buffer_desc *iov,
+ int iov_count)
{
krb5_error_code code;
- krb5_data input, output;
+ krb5_data kd = make_data((char *) kd_data, kd_data_len);
krb5int_access kaccess;
- krb5_key key;
- krb5_keyblock seq_enc_key, usage_key;
- unsigned char t[14];
- size_t i = 0;
- int exportable = (longterm_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP);
krb5_crypto_iov *kiov = NULL;
size_t kiov_count = 0;
- 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;
-
- if (exportable) {
- memcpy(t, kg_arcfour_l40, sizeof(kg_arcfour_l40));
- i += sizeof(kg_arcfour_l40);
- }
- store_32_le(ms_usage, &t[i]);
- i += 4;
- input.data = (void *) &t;
- input.length = i;
- output.data = (void *) usage_key.contents;
- output.length = usage_key.length;
- code = (*kaccess.hmac)(kaccess.md5_hash_provider, longterm_key, 1,
- &input, &output);
- if (code)
- goto cleanup_arcfour;
- if (exportable)
- memset(usage_key.contents + 7, 0xab, 9);
-
- input.data = ( void *) kd_data;
- input.length = kd_data_len;
- output.data = (void *) seq_enc_key.contents;
- code = (*kaccess.hmac)(kaccess.md5_hash_provider, &usage_key, 1,
- &input, &output);
- if (code)
- goto cleanup_arcfour;
-
+ return code;
code = kg_translate_iov(context, 0 /* proto */, 0 /* dce_style */,
- 0 /* ec */, 0 /* rrc */, longterm_key->enctype,
+ 0 /* ec */, 0 /* rrc */, keyblock->enctype,
iov, iov_count, &kiov, &kiov_count);
if (code)
- goto cleanup_arcfour;
-
- code = krb5_k_create_key(context, &seq_enc_key, &key);
- if (code)
- goto cleanup_arcfour;
- code = (*kaccess.arcfour_enc_provider->encrypt_iov)(key, 0, kiov,
- kiov_count);
- krb5_k_free_key(context, key);
-cleanup_arcfour:
- memset (seq_enc_key.contents, 0, seq_enc_key.length);
- memset (usage_key.contents, 0, usage_key.length);
- free (usage_key.contents);
- free (seq_enc_key.contents);
- if (kiov != NULL)
- free(kiov);
- return (code);
+ return code;
+ code = (*kaccess.arcfour_gsscrypt_iov)(keyblock, usage, &kd,
+ kiov, kiov_count);
+ free(kiov);
+ return code;
}
krb5_cryptotype
#define S(FIELD, VAL) internals_temp.FIELD = VAL
krb5int_access internals_temp;
#endif
+ S (arcfour_gsscrypt, krb5int_arcfour_gsscrypt),
+ S (arcfour_gsscrypt_iov, krb5int_arcfour_gsscrypt_iov),
S (free_addrlist, krb5int_free_addrlist),
- S (hmac, krb5int_hmac_keyblock),
S (auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype),
- S (md5_hash_provider, &krb5int_hash_md5),
- S (arcfour_enc_provider, &krb5int_enc_arcfour),
S (sendto_udp, &krb5int_sendto),
S (add_host_to_list, krb5int_add_host_to_list),