krb5: Add an optional encrypt_iov function to encryption types

Add a encrypt_iov function pointer to all of our encryption types
which can be used to implement an iovec based encryption routine.

Modify krb5_encrypt_iov so that it calls the iovec based routine
if it is available.
This commit is contained in:
Simon Wilkinson
2018-05-14 14:25:50 +01:00
committed by Jeffrey Altman
parent 62a8fc89bc
commit 57f7373583
8 changed files with 62 additions and 24 deletions

View File

@@ -154,6 +154,7 @@ struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = {
&_krb5_checksum_hmac_sha1_aes128, &_krb5_checksum_hmac_sha1_aes128,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt_cts, _krb5_evp_encrypt_cts,
NULL,
16, 16,
AES_SHA1_PRF AES_SHA1_PRF
}; };
@@ -170,6 +171,7 @@ struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
&_krb5_checksum_hmac_sha1_aes256, &_krb5_checksum_hmac_sha1_aes256,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt_cts, _krb5_evp_encrypt_cts,
NULL,
16, 16,
AES_SHA1_PRF AES_SHA1_PRF
}; };

View File

@@ -176,6 +176,7 @@ struct _krb5_encryption_type _krb5_enctype_aes128_cts_hmac_sha256_128 = {
&_krb5_checksum_hmac_sha256_128_aes128, &_krb5_checksum_hmac_sha256_128_aes128,
F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF, F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
_krb5_evp_encrypt_cts, _krb5_evp_encrypt_cts,
NULL,
16, 16,
AES_SHA2_PRF AES_SHA2_PRF
}; };
@@ -192,6 +193,7 @@ struct _krb5_encryption_type _krb5_enctype_aes256_cts_hmac_sha384_192 = {
&_krb5_checksum_hmac_sha384_192_aes256, &_krb5_checksum_hmac_sha384_192_aes256,
F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF, F_DERIVED | F_ENC_THEN_CKSUM | F_SP800_108_HMAC_KDF,
_krb5_evp_encrypt_cts, _krb5_evp_encrypt_cts,
NULL,
16, 16,
AES_SHA2_PRF AES_SHA2_PRF
}; };

View File

@@ -362,6 +362,7 @@ struct _krb5_encryption_type _krb5_enctype_arcfour_hmac_md5 = {
&_krb5_checksum_hmac_md5, &_krb5_checksum_hmac_md5,
F_SPECIAL | F_WEAK, F_SPECIAL | F_WEAK,
ARCFOUR_encrypt, ARCFOUR_encrypt,
NULL,
0, 0,
ARCFOUR_prf ARCFOUR_prf
}; };

View File

@@ -311,6 +311,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_crc = {
NULL, NULL,
F_DISABLED|F_WEAK, F_DISABLED|F_WEAK,
evp_des_encrypt_key_ivec, evp_des_encrypt_key_ivec,
NULL,
0, 0,
NULL NULL
}; };
@@ -327,6 +328,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = {
&_krb5_checksum_rsa_md4_des, &_krb5_checksum_rsa_md4_des,
F_DISABLED|F_WEAK, F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec, evp_des_encrypt_null_ivec,
NULL,
0, 0,
NULL NULL
}; };
@@ -343,6 +345,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = {
&_krb5_checksum_rsa_md5_des, &_krb5_checksum_rsa_md5_des,
F_DISABLED|F_WEAK, F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec, evp_des_encrypt_null_ivec,
NULL,
0, 0,
NULL NULL
}; };
@@ -359,6 +362,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cbc_none = {
NULL, NULL,
F_PSEUDO|F_DISABLED|F_WEAK, F_PSEUDO|F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec, evp_des_encrypt_null_ivec,
NULL,
0, 0,
NULL NULL
}; };
@@ -375,6 +379,7 @@ struct _krb5_encryption_type _krb5_enctype_des_cfb64_none = {
NULL, NULL,
F_PSEUDO|F_DISABLED|F_WEAK, F_PSEUDO|F_DISABLED|F_WEAK,
DES_CFB64_encrypt_null_ivec, DES_CFB64_encrypt_null_ivec,
NULL,
0, 0,
NULL NULL
}; };
@@ -391,6 +396,7 @@ struct _krb5_encryption_type _krb5_enctype_des_pcbc_none = {
NULL, NULL,
F_PSEUDO|F_DISABLED|F_WEAK, F_PSEUDO|F_DISABLED|F_WEAK,
DES_PCBC_encrypt_key_ivec, DES_PCBC_encrypt_key_ivec,
NULL,
0, 0,
NULL NULL
}; };

View File

@@ -198,6 +198,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = {
&_krb5_checksum_rsa_md5_des3, &_krb5_checksum_rsa_md5_des3,
0, 0,
_krb5_evp_encrypt, _krb5_evp_encrypt,
NULL,
0, 0,
NULL NULL
}; };
@@ -215,6 +216,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = {
&_krb5_checksum_hmac_sha1_des3, &_krb5_checksum_hmac_sha1_des3,
F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF,
_krb5_evp_encrypt, _krb5_evp_encrypt,
NULL,
16, 16,
DES3_prf DES3_prf
}; };
@@ -232,6 +234,7 @@ struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = {
&_krb5_checksum_hmac_sha1_des3, &_krb5_checksum_hmac_sha1_des3,
0, 0,
_krb5_evp_encrypt, _krb5_evp_encrypt,
NULL,
0, 0,
NULL NULL
}; };
@@ -249,6 +252,7 @@ struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = {
NULL, NULL,
F_PSEUDO, F_PSEUDO,
_krb5_evp_encrypt, _krb5_evp_encrypt,
NULL,
0, 0,
NULL NULL
}; };

View File

@@ -97,6 +97,7 @@ struct _krb5_encryption_type _krb5_enctype_null = {
NULL, NULL,
F_DISABLED, F_DISABLED,
NULL_encrypt, NULL_encrypt,
NULL,
0, 0,
NULL NULL
}; };

View File

@@ -1632,9 +1632,8 @@ krb5_encrypt_iov_ivec(krb5_context context,
unsigned char old_ivec[EVP_MAX_IV_LENGTH]; unsigned char old_ivec[EVP_MAX_IV_LENGTH];
krb5_data ivec_data; krb5_data ivec_data;
ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); heim_assert(et->blocksize <= sizeof(old_ivec),
if(ret) "blocksize too big for ivec buffer");
goto cleanup;
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) if(ret)
@@ -1644,14 +1643,21 @@ krb5_encrypt_iov_ivec(krb5_context context,
if(ret) if(ret)
goto cleanup; goto cleanup;
heim_assert(et->blocksize <= sizeof(old_ivec),
"blocksize too big for ivec buffer");
if (ivec) if (ivec)
memcpy(old_ivec, ivec, et->blocksize); memcpy(old_ivec, ivec, et->blocksize);
else else
memset(old_ivec, 0, et->blocksize); memset(old_ivec, 0, et->blocksize);
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 = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length,
1, usage, ivec); 1, usage, ivec);
if (ret) if (ret)
@@ -1660,6 +1666,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
ret = iov_uncoalesce(context, &enc_data, data, num_data); ret = iov_uncoalesce(context, &enc_data, data, num_data);
if (ret) if (ret)
goto cleanup; goto cleanup;
}
ivec_data.length = et->blocksize; ivec_data.length = et->blocksize;
ivec_data.data = old_ivec; ivec_data.data = old_ivec;
@@ -1700,10 +1707,8 @@ krb5_encrypt_iov_ivec(krb5_context context,
if (ret) if (ret)
goto cleanup; goto cleanup;
ret = iov_coalesce(context, NULL, data, num_data, FALSE, &enc_data); /* create_checksum may realloc the derived key space, so any keys
if(ret) * obtained before it was called may no longer be valid */
goto cleanup;
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) if(ret)
goto cleanup; goto cleanup;
@@ -1712,6 +1717,16 @@ krb5_encrypt_iov_ivec(krb5_context context,
if(ret) if(ret)
goto cleanup; 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 = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length, ret = (*et->encrypt)(context, dkey, enc_data.data, enc_data.length,
1, usage, ivec); 1, usage, ivec);
if (ret) if (ret)
@@ -1721,6 +1736,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
if (ret) if (ret)
goto cleanup; goto cleanup;
} }
}
cleanup: cleanup:
if (enc_data.data) { if (enc_data.data) {

View File

@@ -120,6 +120,12 @@ struct _krb5_encryption_type {
krb5_boolean encryptp, krb5_boolean encryptp,
int usage, int usage,
void *ivec); 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; size_t prf_length;
krb5_error_code (*prf)(krb5_context, krb5_error_code (*prf)(krb5_context,
krb5_crypto, const krb5_data *, krb5_data *); krb5_crypto, const krb5_data *, krb5_data *);