diff options
author | Greg Hudson <ghudson@mit.edu> | 2009-10-19 20:04:21 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2009-10-19 20:04:21 +0000 |
commit | e6b93b7dd43bb765900b2db71641479b597844da (patch) | |
tree | 2b6da09e37da6ca699a8cb43c87e8a4218132254 /src/lib/gssapi/krb5/util_crypt.c | |
parent | 04a5d19e61bedbb1da4db52334c00f7a54a9d5a8 (diff) | |
download | krb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.gz krb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.xz krb5-e6b93b7dd43bb765900b2db71641479b597844da.zip |
Implement new APIs to allow improved crypto performance
Merge branches/enc-perf to trunk. Adds the krb5_key opaque type, the
krb5_k_* APIs to use them, and caching of derived keys when krb5_k_*
functions are used. Updates the krb5 auth context and GSS id-rec to
use krb5_keys.
ticket: 6576
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22944 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi/krb5/util_crypt.c')
-rw-r--r-- | src/lib/gssapi/krb5/util_crypt.c | 133 |
1 files changed, 80 insertions, 53 deletions
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 87e04065f..53e420d9f 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -59,39 +59,53 @@ static const char kg_arcfour_l40[] = "fortybits"; static krb5_error_code kg_copy_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, - krb5_keyblock *subkey) + krb5_key subkey) { krb5_error_code code; - if (ctx->enc != NULL) { - krb5_free_keyblock(context, ctx->enc); - ctx->enc = NULL; - } + krb5_k_free_key(context, ctx->enc); + ctx->enc = NULL; + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->enc); + if (code != 0) + return code; - code = krb5_copy_keyblock(context, subkey, &ctx->enc); + krb5_k_free_key(context, ctx->seq); + ctx->seq = NULL; + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq); if (code != 0) return code; - if (ctx->seq != NULL) { - krb5_free_keyblock(context, ctx->seq); - ctx->seq = NULL; - } + return 0; +} + +static krb5_error_code +kg_derive_des_enc_key(krb5_context context, krb5_key subkey, krb5_key *out) +{ + krb5_error_code code; + krb5_keyblock *keyblock; + unsigned int i; + + *out = NULL; - code = krb5_copy_keyblock(context, subkey, &ctx->seq); + code = krb5_k_key_keyblock(context, subkey, &keyblock); if (code != 0) return code; - return 0; + for (i = 0; i < keyblock->length; i++) + keyblock->contents[i] ^= 0xF0; + + code = krb5_k_create_key(context, keyblock, out); + krb5_free_keyblock(context, keyblock); + return code; } krb5_error_code kg_setup_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, - krb5_keyblock *subkey, + krb5_key subkey, krb5_cksumtype *cksumtype) { krb5_error_code code; - unsigned int i; krb5int_access kaccess; assert(ctx != NULL); @@ -109,36 +123,40 @@ kg_setup_keys(krb5_context context, if (code != 0) return code; - code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, subkey->enctype, + code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, + subkey->keyblock.enctype, cksumtype); if (code != 0) return code; - switch (subkey->enctype) { + switch (subkey->keyblock.enctype) { case ENCTYPE_DES_CBC_MD5: case ENCTYPE_DES_CBC_MD4: case ENCTYPE_DES_CBC_CRC: - code = kg_copy_keys(context, ctx, subkey); + krb5_k_free_key(context, ctx->seq); + code = krb5_k_create_key(context, &subkey->keyblock, &ctx->seq); + if (code != 0) + return code; + + krb5_k_free_key(context, ctx->enc); + code = kg_derive_des_enc_key(context, subkey, &ctx->enc); if (code != 0) return code; - ctx->enc->enctype = ENCTYPE_DES_CBC_RAW; - ctx->seq->enctype = ENCTYPE_DES_CBC_RAW; + ctx->enc->keyblock.enctype = ENCTYPE_DES_CBC_RAW; + ctx->seq->keyblock.enctype = ENCTYPE_DES_CBC_RAW; ctx->signalg = SGN_ALG_DES_MAC_MD5; ctx->cksum_size = 8; ctx->sealalg = SEAL_ALG_DES; - for (i = 0; i < ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xF0; break; case ENCTYPE_DES3_CBC_SHA1: code = kg_copy_keys(context, ctx, subkey); if (code != 0) return code; - ctx->enc->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->seq->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->enc->keyblock.enctype = ENCTYPE_DES3_CBC_RAW; + ctx->seq->keyblock.enctype = ENCTYPE_DES3_CBC_RAW; ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; ctx->cksum_size = 20; ctx->sealalg = SEAL_ALG_DES3KD; @@ -164,15 +182,15 @@ kg_setup_keys(krb5_context context, int kg_confounder_size(context, key) krb5_context context; - krb5_keyblock *key; + krb5_key key; { krb5_error_code code; size_t blocksize; /* We special case rc4*/ - if (key->enctype == ENCTYPE_ARCFOUR_HMAC || - key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) + if (key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC || + key->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC_EXP) return 8; - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(-1); /* XXX */ @@ -182,7 +200,7 @@ kg_confounder_size(context, key) krb5_error_code kg_make_confounder(context, key, buf) krb5_context context; - krb5_keyblock *key; + krb5_key key; unsigned char *buf; { int confsize; @@ -201,7 +219,7 @@ kg_make_confounder(context, key, buf) krb5_error_code kg_encrypt(context, key, usage, iv, in, out, length) krb5_context context; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; krb5_const_pointer in; @@ -214,7 +232,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) krb5_enc_data outputd; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -234,7 +252,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) outputd.ciphertext.length = length; outputd.ciphertext.data = out; - code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd); + code = krb5_k_encrypt(context, key, usage, pivd, &inputd, &outputd); if (pivd != NULL) free(pivd->data); return code; @@ -245,7 +263,7 @@ kg_encrypt(context, key, usage, iv, in, out, length) krb5_error_code kg_decrypt(context, key, usage, iv, in, out, length) krb5_context context; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; krb5_const_pointer in; @@ -258,7 +276,7 @@ kg_decrypt(context, key, usage, iv, in, out, length) krb5_enc_data inputd; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -279,7 +297,7 @@ kg_decrypt(context, key, usage, iv, in, out, length) outputd.length = length; outputd.data = out; - code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd); + code = krb5_k_decrypt(context, key, usage, pivd, &inputd, &outputd); if (pivd != NULL) free(pivd->data); return code; @@ -294,6 +312,7 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, krb5_error_code code; krb5_data input, output; krb5int_access kaccess; + krb5_key key; krb5_keyblock seq_enc_key, usage_key; unsigned char t[14]; size_t i = 0; @@ -341,9 +360,11 @@ kg_arcfour_docrypt (const krb5_keyblock *longterm_key , int ms_usage, 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)); + code = krb5_k_create_key(NULL, &seq_enc_key, &key); + 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); @@ -356,7 +377,7 @@ cleanup_arcfour: static krb5_error_code kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count) krb5_context context; - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -372,7 +393,7 @@ kg_translate_iov_v1(context, key, iov, iov_count, pkiov, pkiov_count) *pkiov = NULL; *pkiov_count = 0; - conf_len = kg_confounder_size(context, (krb5_keyblock *)key); + conf_len = kg_confounder_size(context, key); header = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER); assert(header != NULL); @@ -427,7 +448,7 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki int dce_style; /* DCE_STYLE indicates actual RRC is EC + RRC */ size_t ec; /* Extra rotate count for DCE_STYLE, pad length otherwise */ size_t rrc; /* Rotate count */ - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -451,11 +472,13 @@ kg_translate_iov_v3(context, dce_style, ec, rrc, key, iov, iov_count, pkiov, pki trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER); assert(trailer == NULL || rrc == 0); - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen); if (code != 0) return code; - code = krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); + code = krb5_c_crypto_length(context, key->keyblock.enctype, + KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen); if (code != 0) return code; @@ -541,7 +564,7 @@ kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, pkiov, int dce_style; size_t ec; size_t rrc; - const krb5_keyblock *key; + krb5_key key; gss_iov_buffer_desc *iov; int iov_count; krb5_crypto_iov **pkiov; @@ -559,7 +582,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun int dce_style; size_t ec; size_t rrc; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; gss_iov_buffer_desc *iov; @@ -572,7 +595,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun krb5_crypto_iov *kiov; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -589,7 +612,7 @@ kg_encrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, &kiov, &kiov_count); if (code == 0) { - code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count); + code = krb5_k_encrypt_iov(context, key, usage, pivd, kiov, kiov_count); free(kiov); } @@ -608,7 +631,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun int dce_style; size_t ec; size_t rrc; - krb5_keyblock *key; + krb5_key key; int usage; krb5_pointer iv; gss_iov_buffer_desc *iov; @@ -621,7 +644,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun krb5_crypto_iov *kiov; if (iv) { - code = krb5_c_block_size(context, key->enctype, &blocksize); + code = krb5_c_block_size(context, key->keyblock.enctype, &blocksize); if (code) return(code); @@ -638,7 +661,7 @@ kg_decrypt_iov(context, proto, dce_style, ec, rrc, key, usage, iv, iov, iov_coun code = kg_translate_iov(context, proto, dce_style, ec, rrc, key, iov, iov_count, &kiov, &kiov_count); if (code == 0) { - code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count); + code = krb5_k_decrypt_iov(context, key, usage, pivd, kiov, kiov_count); free(kiov); } @@ -657,6 +680,7 @@ kg_arcfour_docrypt_iov (krb5_context context, krb5_error_code code; krb5_data input, output; krb5int_access kaccess; + krb5_key key; krb5_keyblock seq_enc_key, usage_key; unsigned char t[14]; size_t i = 0; @@ -709,9 +733,12 @@ kg_arcfour_docrypt_iov (krb5_context context, if (code) goto cleanup_arcfour; - code = ((*kaccess.arcfour_enc_provider->encrypt_iov)( - &seq_enc_key, 0, - kiov, kiov_count)); + 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); |