diff --git a/lib/krb5/crypto-aes-sha1.c b/lib/krb5/crypto-aes-sha1.c index bc7f0fc39..76f32d94a 100644 --- a/lib/krb5/crypto-aes-sha1.c +++ b/lib/krb5/crypto-aes-sha1.c @@ -154,6 +154,7 @@ struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = { &_krb5_checksum_hmac_sha1_aes128, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, _krb5_evp_encrypt_cts, + NULL, 16, AES_SHA1_PRF }; @@ -170,6 +171,7 @@ struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = { &_krb5_checksum_hmac_sha1_aes256, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, _krb5_evp_encrypt_cts, + NULL, 16, AES_SHA1_PRF }; diff --git a/lib/krb5/crypto-aes-sha2.c b/lib/krb5/crypto-aes-sha2.c index a5e9f14f6..94ec9a1d6 100644 --- a/lib/krb5/crypto-aes-sha2.c +++ b/lib/krb5/crypto-aes-sha2.c @@ -176,6 +176,7 @@ struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha256_128 = { &_krb5_checksum_hmac_sha256_128_aes128, F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF, _krb5_evp_encrypt_cts, + NULL, 16, AES_SHA2_PRF }; @@ -192,6 +193,7 @@ struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha384_192 = { &_krb5_checksum_hmac_sha384_192_aes256, F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF, _krb5_evp_encrypt_cts, + NULL, 16, AES_SHA2_PRF }; diff --git a/lib/krb5/crypto-arcfour.c b/lib/krb5/crypto-arcfour.c index 2a5d295a2..9b5250aed 100644 --- a/lib/krb5/crypto-arcfour.c +++ b/lib/krb5/crypto-arcfour.c @@ -362,6 +362,7 @@ struct _krb5_encryption_type _krb5_enctype_arcfour_hmac_md5 = { &_krb5_checksum_hmac_md5, F_SPECIAL | F_WEAK, ARCFOUR_encrypt, + NULL, 0, ARCFOUR_prf }; diff --git a/lib/krb5/crypto-des.c b/lib/krb5/crypto-des.c index fbb7c347b..7060283f3 100644 --- a/lib/krb5/crypto-des.c +++ b/lib/krb5/crypto-des.c @@ -311,6 +311,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_crc = { NULL, F_DISABLED|F_WEAK, evp_des_encrypt_key_ivec, + NULL, 0, NULL }; @@ -327,6 +328,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = { &_krb5_checksum_rsa_md4_des, F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, + NULL, 0, NULL }; @@ -343,6 +345,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = { &_krb5_checksum_rsa_md5_des, F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, + NULL, 0, NULL }; @@ -359,6 +362,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_none = { NULL, F_PSEUDO|F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, + NULL, 0, NULL }; @@ -375,6 +379,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cfb64_none = { NULL, F_PSEUDO|F_DISABLED|F_WEAK, DES_CFB64_encrypt_null_ivec, + NULL, 0, NULL }; @@ -391,6 +396,7 @@ struct _krb5_encryption_type _krb5_enctype_des_pcbc_none = { NULL, F_PSEUDO|F_DISABLED|F_WEAK, DES_PCBC_encrypt_key_ivec, + NULL, 0, NULL }; diff --git a/lib/krb5/crypto-des3.c b/lib/krb5/crypto-des3.c index 9b8853db9..17a073d5c 100644 --- a/lib/krb5/crypto-des3.c +++ b/lib/krb5/crypto-des3.c @@ -198,6 +198,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = { &_krb5_checksum_rsa_md5_des3, 0, _krb5_evp_encrypt, + NULL, 0, NULL }; @@ -215,6 +216,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = { &_krb5_checksum_hmac_sha1_des3, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, _krb5_evp_encrypt, + NULL, 16, DES3_prf }; @@ -232,6 +234,7 @@ struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = { &_krb5_checksum_hmac_sha1_des3, 0, _krb5_evp_encrypt, + NULL, 0, NULL }; @@ -249,6 +252,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = { NULL, F_PSEUDO, _krb5_evp_encrypt, + NULL, 0, NULL }; diff --git a/lib/krb5/crypto-null.c b/lib/krb5/crypto-null.c index 4e5934282..53f97c529 100644 --- a/lib/krb5/crypto-null.c +++ b/lib/krb5/crypto-null.c @@ -97,6 +97,7 @@ struct _krb5_encryption_type _krb5_enctype_null = { NULL, F_DISABLED, NULL_encrypt, + NULL, 0, NULL }; diff --git a/lib/krb5/crypto.c b/lib/krb5/crypto.c index 49b6acf98..c84fcf619 100644 --- a/lib/krb5/crypto.c +++ b/lib/krb5/crypto.c @@ -1632,9 +1632,8 @@ krb5_encrypt_iov_ivec(krb5_context context, unsigned char old_ivec[EVP_MAX_IV_LENGTH]; krb5_data ivec_data; - ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); - if(ret) - goto cleanup; + heim_assert(et->blocksize <= sizeof(old_ivec), + "blocksize too big for ivec buffer"); ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) @@ -1644,22 +1643,30 @@ krb5_encrypt_iov_ivec(krb5_context context, if(ret) goto cleanup; - heim_assert(et->blocksize <= sizeof(old_ivec), - "blocksize too big for ivec buffer"); - if (ivec) memcpy(old_ivec, ivec, et->blocksize); else memset(old_ivec, 0, et->blocksize); - ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, - 1, usage, ivec); - if(ret) - goto cleanup; + if (et->encrypt_iov != NULL) { + ret = (*et->encrypt_iov)(context, dkey, data, num_data, 1, usage, + ivec); + if (ret) + goto cleanup; + } else { + ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); + if (ret) + goto cleanup; - ret = iov_uncoalesce(context, &enc_data, data, num_data); - if(ret) - goto cleanup; + ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, + 1, usage, ivec); + if (ret) + goto cleanup; + + ret = iov_uncoalesce(context, &enc_data, data, num_data); + if (ret) + goto cleanup; + } ivec_data.length = et->blocksize; ivec_data.data = old_ivec; @@ -1700,10 +1707,8 @@ krb5_encrypt_iov_ivec(krb5_context context, if (ret) goto cleanup; - ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); - if(ret) - goto cleanup; - + /* create_checksum may realloc the derived key space, so any keys + * obtained before it was called may no longer be valid */ ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) goto cleanup; @@ -1712,14 +1717,25 @@ krb5_encrypt_iov_ivec(krb5_context context, if(ret) goto cleanup; - ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, - 1, usage, ivec); - if(ret) - goto cleanup; + if (et->encrypt_iov != NULL) { + ret = (*et->encrypt_iov)(context, dkey, data, num_data, 1, usage, + ivec); + if (ret) + goto cleanup; + } else { + ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); + if (ret) + goto cleanup; - ret = iov_uncoalesce(context, &enc_data, data, num_data); - if(ret) - goto cleanup; + ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, + 1, usage, ivec); + if (ret) + goto cleanup; + + ret = iov_uncoalesce(context, &enc_data, data, num_data); + if (ret) + goto cleanup; + } } cleanup: diff --git a/lib/krb5/crypto.h b/lib/krb5/crypto.h index 48201b546..7bde0bef2 100644 --- a/lib/krb5/crypto.h +++ b/lib/krb5/crypto.h @@ -120,6 +120,12 @@ struct _krb5_encryption_type { krb5_boolean encryptp, int usage, void *ivec); + krb5_error_code (*encrypt_iov)(krb5_context context, + struct _krb5_key_data *key, + krb5_crypto_iov *iov, int niov, + krb5_boolean encryptp, + int usage, + void *ivec); size_t prf_length; krb5_error_code (*prf)(krb5_context, krb5_crypto, const krb5_data *, krb5_data *);