aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-11-28 23:10:31 +0000
committerGreg Hudson <ghudson@mit.edu>2009-11-28 23:10:31 +0000
commit52ae4d17e90b69577b845f388621c2f7011056cc (patch)
treefb10774fb413d1f52afd285576d29f757fe35b9b
parent01a2a0fe9b4bd1900773487db290f3138e20c1d7 (diff)
downloadkrb5-52ae4d17e90b69577b845f388621c2f7011056cc.zip
krb5-52ae4d17e90b69577b845f388621c2f7011056cc.tar.gz
krb5-52ae4d17e90b69577b845f388621c2f7011056cc.tar.bz2
Create functional internal interfaces to allow GSSAPI to perform
arcfour encryption of GSS tokens. This factors out derivation of the usage and encryption keys, and removes the need for the provider structures to be visible to all of krb5 via k5-int.h. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23378 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/k5-int.h40
-rw-r--r--src/lib/crypto/krb/arcfour/arcfour.c48
-rw-r--r--src/lib/crypto/krb/arcfour/arcfour_aead.c46
-rw-r--r--src/lib/crypto/krb/prf/des_prf.c2
-rw-r--r--src/lib/crypto/libk5crypto.exports3
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h4
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c142
-rw-r--r--src/lib/krb5/os/accessor.c5
8 files changed, 143 insertions, 147 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index ad7f539..43d9d21 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -752,6 +752,18 @@ krb5int_hmac_iov_keyblock(const struct krb5_hash_provider *hash,
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.
*
@@ -843,15 +855,6 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
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 */
@@ -2192,19 +2195,24 @@ void krb5int_free_srv_dns_data(struct srv_dns_entry *);
/* 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 *);
diff --git a/src/lib/crypto/krb/arcfour/arcfour.c b/src/lib/crypto/krb/arcfour/arcfour.c
index a057da0..b9cb5fc 100644
--- a/src/lib/crypto/krb/arcfour/arcfour.c
+++ b/src/lib/crypto/krb/arcfour/arcfour.c
@@ -70,7 +70,7 @@ krb5int_arcfour_usage_key(const struct krb5_enc_provider *enc,
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,
@@ -264,3 +264,49 @@ cleanup:
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;
+}
diff --git a/src/lib/crypto/krb/arcfour/arcfour_aead.c b/src/lib/crypto/krb/arcfour/arcfour_aead.c
index a409484..c5e65ca 100644
--- a/src/lib/crypto/krb/arcfour/arcfour_aead.c
+++ b/src/lib/crypto/krb/arcfour/arcfour_aead.c
@@ -29,6 +29,7 @@
#include "k5-int.h"
#include "arcfour.h"
#include "arcfour-int.h"
+#include "hash_provider/hash_provider.h"
#include "aead.h"
/* AEAD */
@@ -265,3 +266,48 @@ const struct krb5_aead_provider krb5int_aead_arcfour = {
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;
+}
diff --git a/src/lib/crypto/krb/prf/des_prf.c b/src/lib/crypto/krb/prf/des_prf.c
index 6d5baf6..9b4e135 100644
--- a/src/lib/crypto/krb/prf/des_prf.c
+++ b/src/lib/crypto/krb/prf/des_prf.c
@@ -31,7 +31,7 @@
*/
#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,
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index f108cca..9b19557 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -65,7 +65,6 @@ krb5int_c_free_keyblock_contents
krb5int_c_free_keyblock
krb5int_c_init_keyblock
krb5int_hash_md5
-krb5int_hmac_keyblock
krb5int_enc_arcfour
krb5int_hmac
mit_des_fixup_key_parity
@@ -96,3 +95,5 @@ krb5int_MD5Update
krb5int_MD5Final
krb5int_aes_decrypt
krb5int_enc_des3
+krb5int_arcfour_gsscrypt
+krb5int_arcfour_gsscrypt_iov
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 13413b9..0127e8c 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -299,14 +299,14 @@ krb5_error_code kg_encrypt_iov (krb5_context context,
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);
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index e097086..7478c7f 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -282,73 +282,21 @@ kg_decrypt(krb5_context context, krb5_key key, int usage, krb5_pointer iv,
}
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 */
@@ -626,81 +574,29 @@ kg_decrypt_iov(krb5_context context, int proto, int dce_style, size_t ec,
}
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
diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c
index 20fb30d..4561c6c 100644
--- a/src/lib/krb5/os/accessor.c
+++ b/src/lib/krb5/os/accessor.c
@@ -52,11 +52,10 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
#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),