diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/k5-int.h | 40 | ||||
-rw-r--r-- | src/lib/crypto/krb/arcfour/arcfour.c | 48 | ||||
-rw-r--r-- | src/lib/crypto/krb/arcfour/arcfour_aead.c | 46 | ||||
-rw-r--r-- | src/lib/crypto/krb/prf/des_prf.c | 2 | ||||
-rw-r--r-- | src/lib/crypto/libk5crypto.exports | 3 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapiP_krb5.h | 4 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/util_crypt.c | 142 | ||||
-rw-r--r-- | src/lib/krb5/os/accessor.c | 5 |
8 files changed, 143 insertions, 147 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h index ad7f53994..43d9d21fe 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 a057da09f..b9cb5fc67 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 a409484c5..c5e65ca42 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 6d5baf60b..9b4e1355a 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 f108cca89..9b1955756 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 13413b972..0127e8ccb 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 e0970865b..7478c7f12 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 20fb30d20..4561c6cf4 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), |