diff options
Diffstat (limited to 'freebsd/sys/opencrypto/criov.c')
-rw-r--r-- | freebsd/sys/opencrypto/criov.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/freebsd/sys/opencrypto/criov.c b/freebsd/sys/opencrypto/criov.c index 7fc7d392..a1893691 100644 --- a/freebsd/sys/opencrypto/criov.c +++ b/freebsd/sys/opencrypto/criov.c @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/mbuf.h> #include <sys/uio.h> +#include <sys/limits.h> +#include <sys/lock.h> #include <opencrypto/cryptodev.h> @@ -241,3 +243,55 @@ crypto_mbuftoiov(struct mbuf *mbuf, struct iovec **iovptr, int *cnt, *cnt = i; return 0; } + +static inline void * +m_contiguous_subsegment(struct mbuf *m, size_t skip, size_t len) +{ + int rel_off; + + MPASS(skip <= INT_MAX); + + m = m_getptr(m, (int)skip, &rel_off); + if (m == NULL) + return (NULL); + + MPASS(rel_off >= 0); + skip = rel_off; + if (skip + len > m->m_len) + return (NULL); + + return (mtod(m, char*) + skip); +} + +static inline void * +cuio_contiguous_segment(struct uio *uio, size_t skip, size_t len) +{ + int rel_off, idx; + + MPASS(skip <= INT_MAX); + idx = cuio_getptr(uio, (int)skip, &rel_off); + if (idx < 0) + return (NULL); + + MPASS(rel_off >= 0); + skip = rel_off; + if (skip + len > uio->uio_iov[idx].iov_len) + return (NULL); + return ((char *)uio->uio_iov[idx].iov_base + skip); +} + +void * +crypto_contiguous_subsegment(int crp_flags, void *crpbuf, + size_t skip, size_t len) +{ + if ((crp_flags & CRYPTO_F_IMBUF) != 0) + return (m_contiguous_subsegment(crpbuf, skip, len)); + else if ((crp_flags & CRYPTO_F_IOV) != 0) + return (cuio_contiguous_segment(crpbuf, skip, len)); + else { + MPASS((crp_flags & (CRYPTO_F_IMBUF | CRYPTO_F_IOV)) != + (CRYPTO_F_IMBUF | CRYPTO_F_IOV)); + return ((char*)crpbuf + skip); + } +} + |