summaryrefslogtreecommitdiffstats
path: root/sys/kgssapi/krb5
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2016-05-13 08:25:06 +0000
committerngie <ngie@FreeBSD.org>2016-05-13 08:25:06 +0000
commit29310b2c8f33351be0a1fdf7ee237bc3ebc2991d (patch)
treefd4039ca7dd089b8b2de97635d1fe61ee193ca4f /sys/kgssapi/krb5
parent8d808d7b779a395d962236552309cbafe956a3d2 (diff)
downloadFreeBSD-src-29310b2c8f33351be0a1fdf7ee237bc3ebc2991d.zip
FreeBSD-src-29310b2c8f33351be0a1fdf7ee237bc3ebc2991d.tar.gz
MFC r295134,r298338,r298655:
r295134 (by cem): kcrypto_aes: Use separate sessions for AES and SHA1 Some hardware supports AES acceleration but not SHA1, e.g., AES-NI extensions. It is useful to have accelerated AES even if SHA1 must be software. Suggested by: asomers r298338 (by cem): kgssapi(4): Don't allow user-provided arguments to overrun stack buffer An over-long path argument to gssd_syscall could overrun the stack sockaddr_un buffer. Fix gssd_syscall to not permit that. If an over-long path is provided, gssd_syscall now returns EINVAL. It looks like PRIV_NFS_DAEMON isn't granted anywhere, so my best guess is that this is likely only triggerable by root. CID: 1006751 r298655 (by cem): kgssapi: Don't leak memory in error cases CIDs: 1007046, 1007047, 1007048
Diffstat (limited to 'sys/kgssapi/krb5')
-rw-r--r--sys/kgssapi/krb5/kcrypto_aes.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/sys/kgssapi/krb5/kcrypto_aes.c b/sys/kgssapi/krb5/kcrypto_aes.c
index d2dac21..fca963c 100644
--- a/sys/kgssapi/krb5/kcrypto_aes.c
+++ b/sys/kgssapi/krb5/kcrypto_aes.c
@@ -43,7 +43,8 @@ __FBSDID("$FreeBSD$");
struct aes_state {
struct mtx as_lock;
- uint64_t as_session;
+ uint64_t as_session_aes;
+ uint64_t as_session_sha1;
};
static void
@@ -61,8 +62,10 @@ aes_destroy(struct krb5_key_state *ks)
{
struct aes_state *as = ks->ks_priv;
- if (as->as_session)
- crypto_freesession(as->as_session);
+ if (as->as_session_aes != 0)
+ crypto_freesession(as->as_session_aes);
+ if (as->as_session_sha1 != 0)
+ crypto_freesession(as->as_session_sha1);
mtx_destroy(&as->as_lock);
free(ks->ks_priv, M_GSSAPI);
}
@@ -72,32 +75,35 @@ aes_set_key(struct krb5_key_state *ks, const void *in)
{
void *kp = ks->ks_key;
struct aes_state *as = ks->ks_priv;
- struct cryptoini cri[2];
+ struct cryptoini cri;
if (kp != in)
bcopy(in, kp, ks->ks_class->ec_keylen);
- if (as->as_session)
- crypto_freesession(as->as_session);
-
- bzero(cri, sizeof(cri));
+ if (as->as_session_aes != 0)
+ crypto_freesession(as->as_session_aes);
+ if (as->as_session_sha1 != 0)
+ crypto_freesession(as->as_session_sha1);
/*
* We only want the first 96 bits of the HMAC.
*/
- cri[0].cri_alg = CRYPTO_SHA1_HMAC;
- cri[0].cri_klen = ks->ks_class->ec_keybits;
- cri[0].cri_mlen = 12;
- cri[0].cri_key = ks->ks_key;
- cri[0].cri_next = &cri[1];
-
- cri[1].cri_alg = CRYPTO_AES_CBC;
- cri[1].cri_klen = ks->ks_class->ec_keybits;
- cri[1].cri_mlen = 0;
- cri[1].cri_key = ks->ks_key;
- cri[1].cri_next = NULL;
-
- crypto_newsession(&as->as_session, cri,
+ bzero(&cri, sizeof(cri));
+ cri.cri_alg = CRYPTO_SHA1_HMAC;
+ cri.cri_klen = ks->ks_class->ec_keybits;
+ cri.cri_mlen = 12;
+ cri.cri_key = ks->ks_key;
+ cri.cri_next = NULL;
+ crypto_newsession(&as->as_session_sha1, &cri,
+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
+
+ bzero(&cri, sizeof(cri));
+ cri.cri_alg = CRYPTO_AES_CBC;
+ cri.cri_klen = ks->ks_class->ec_keybits;
+ cri.cri_mlen = 0;
+ cri.cri_key = ks->ks_key;
+ cri.cri_next = NULL;
+ crypto_newsession(&as->as_session_aes, &cri,
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
}
@@ -114,7 +120,7 @@ aes_crypto_cb(struct cryptop *crp)
int error;
struct aes_state *as = (struct aes_state *) crp->crp_opaque;
- if (CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC)
+ if (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC)
return (0);
error = crp->crp_etype;
@@ -151,7 +157,7 @@ aes_encrypt_1(const struct krb5_key_state *ks, int buftype, void *buf,
crd->crd_next = NULL;
crd->crd_alg = CRYPTO_AES_CBC;
- crp->crp_sid = as->as_session;
+ crp->crp_sid = as->as_session_aes;
crp->crp_flags = buftype | CRYPTO_F_CBIFSYNC;
crp->crp_buf = buf;
crp->crp_opaque = (void *) as;
@@ -159,7 +165,7 @@ aes_encrypt_1(const struct krb5_key_state *ks, int buftype, void *buf,
error = crypto_dispatch(crp);
- if ((CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC) == 0) {
+ if ((CRYPTO_SESID2CAPS(as->as_session_aes) & CRYPTOCAP_F_SYNC) == 0) {
mtx_lock(&as->as_lock);
if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
error = msleep(crp, &as->as_lock, 0, "gssaes", 0);
@@ -326,7 +332,7 @@ aes_checksum(const struct krb5_key_state *ks, int usage,
crd->crd_next = NULL;
crd->crd_alg = CRYPTO_SHA1_HMAC;
- crp->crp_sid = as->as_session;
+ crp->crp_sid = as->as_session_sha1;
crp->crp_ilen = inlen;
crp->crp_olen = 12;
crp->crp_etype = 0;
@@ -337,7 +343,7 @@ aes_checksum(const struct krb5_key_state *ks, int usage,
error = crypto_dispatch(crp);
- if ((CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC) == 0) {
+ if ((CRYPTO_SESID2CAPS(as->as_session_sha1) & CRYPTOCAP_F_SYNC) == 0) {
mtx_lock(&as->as_lock);
if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
error = msleep(crp, &as->as_lock, 0, "gssaes", 0);
OpenPOWER on IntegriCloud