cryptodev: Fix some input validation bugs

- When we do not have a separate IV, make sure that the IV length
  specified by the session is not larger than the payload size.
- Disallow AEAD requests without a separate IV.  crp_sanity() asserts
  that CRYPTO_F_IV_SEPARATE is set for AEAD requests, and some (but not
  all) drivers require it.
- Return EINVAL for AEAD requests if an IV is specified but the
  transform does not expect one.

Reported by:	syzbot+c9e8f6ff5cb7fa6a1250@syzkaller.appspotmail.com
Reported by:	syzbot+007341439ae295cee74f@syzkaller.appspotmail.com
Reported by:	syzbot+46e0cc42a428b3b0a40d@syzkaller.appspotmail.com
Reported by:	syzbot+2c4d670173b8bdb947df@syzkaller.appspotmail.com
Reported by:	syzbot+220faa5eeb4d47b23877@syzkaller.appspotmail.com
Reported by:	syzbot+e83434b40f05843722f7@syzkaller.appspotmail.com
Reviewed by:	jhb
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D30154
This commit is contained in:
Mark Johnston 2021-05-11 17:36:12 -04:00
parent b8f113cab9
commit 1a04f0156c

View File

@ -878,6 +878,11 @@ cryptodev_op(struct csession *cse, const struct crypt_op *cop)
}
crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
} else if (cse->ivsize != 0) {
if (crp->crp_payload_length < cse->ivsize) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
error = EINVAL;
goto bail;
}
crp->crp_iv_start = 0;
crp->crp_payload_start += cse->ivsize;
crp->crp_payload_length -= cse->ivsize;
@ -1058,6 +1063,11 @@ cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
cse->ivsize == AES_XTS_IV_LEN)
caead->ivlen = AES_XTS_IV_LEN;
if (cse->ivsize == 0) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
error = EINVAL;
goto bail;
}
if (caead->ivlen != cse->ivsize) {
error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
@ -1071,10 +1081,9 @@ cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
}
crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
} else {
crp->crp_iv_start = crp->crp_payload_start;
crp->crp_payload_start += cse->ivsize;
crp->crp_payload_length -= cse->ivsize;
dst += cse->ivsize;
error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {