summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto/cryptosoft.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2010-09-23 11:52:32 +0000
committerpjd <pjd@FreeBSD.org>2010-09-23 11:52:32 +0000
commitaebc765efad05587abd0cf7f3ebd3e9012b23f72 (patch)
treed3d9022b198d92bfe920c75f7f1cdfcae31ca835 /sys/opencrypto/cryptosoft.c
parented0ad07f3dd1bc5f1fad46c75e5d57ecbbca3cf8 (diff)
downloadFreeBSD-src-aebc765efad05587abd0cf7f3ebd3e9012b23f72.zip
FreeBSD-src-aebc765efad05587abd0cf7f3ebd3e9012b23f72.tar.gz
Add support for AES-XTS.
Obtained from: OpenBSD MFC after: 1 week
Diffstat (limited to 'sys/opencrypto/cryptosoft.c')
-rw-r--r--sys/opencrypto/cryptosoft.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c
index a404cbc..e05b015 100644
--- a/sys/opencrypto/cryptosoft.c
+++ b/sys/opencrypto/cryptosoft.c
@@ -114,8 +114,16 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
if (error)
return (error);
}
+
ivp = iv;
+ /*
+ * xforms that provide a reinit method perform all IV
+ * handling themselves.
+ */
+ if (exf->reinit)
+ exf->reinit(sw->sw_kschedule, iv);
+
if (flags & CRYPTO_F_IMBUF) {
struct mbuf *m = (struct mbuf *) buf;
@@ -135,7 +143,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
m_copydata(m, k, blks, blk);
/* Actual encryption/decryption */
- if (crd->crd_flags & CRD_F_ENCRYPT) {
+ if (exf->reinit) {
+ if (crd->crd_flags & CRD_F_ENCRYPT) {
+ exf->encrypt(sw->sw_kschedule,
+ blk);
+ } else {
+ exf->decrypt(sw->sw_kschedule,
+ blk);
+ }
+ } else if (crd->crd_flags & CRD_F_ENCRYPT) {
/* XOR with previous block */
for (j = 0; j < blks; j++)
blk[j] ^= ivp[j];
@@ -205,7 +221,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
idat = mtod(m, unsigned char *) + k;
while (m->m_len >= k + blks && i > 0) {
- if (crd->crd_flags & CRD_F_ENCRYPT) {
+ if (exf->reinit) {
+ if (crd->crd_flags & CRD_F_ENCRYPT) {
+ exf->encrypt(sw->sw_kschedule,
+ idat);
+ } else {
+ exf->decrypt(sw->sw_kschedule,
+ idat);
+ }
+ } else if (crd->crd_flags & CRD_F_ENCRYPT) {
/* XOR with previous block/IV */
for (j = 0; j < blks; j++)
idat[j] ^= ivp[j];
@@ -261,7 +285,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
cuio_copydata(uio, k, blks, blk);
/* Actual encryption/decryption */
- if (crd->crd_flags & CRD_F_ENCRYPT) {
+ if (exf->reinit) {
+ if (crd->crd_flags & CRD_F_ENCRYPT) {
+ exf->encrypt(sw->sw_kschedule,
+ blk);
+ } else {
+ exf->decrypt(sw->sw_kschedule,
+ blk);
+ }
+ } else if (crd->crd_flags & CRD_F_ENCRYPT) {
/* XOR with previous block */
for (j = 0; j < blks; j++)
blk[j] ^= ivp[j];
@@ -319,7 +351,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
idat = (char *)iov->iov_base + k;
while (iov->iov_len >= k + blks && i > 0) {
- if (crd->crd_flags & CRD_F_ENCRYPT) {
+ if (exf->reinit) {
+ if (crd->crd_flags & CRD_F_ENCRYPT) {
+ exf->encrypt(sw->sw_kschedule,
+ idat);
+ } else {
+ exf->decrypt(sw->sw_kschedule,
+ idat);
+ }
+ } else if (crd->crd_flags & CRD_F_ENCRYPT) {
/* XOR with previous block/IV */
for (j = 0; j < blks; j++)
idat[j] ^= ivp[j];
@@ -360,7 +400,15 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
return 0; /* Done with iovec encryption/decryption */
} else { /* contiguous buffer */
- if (crd->crd_flags & CRD_F_ENCRYPT) {
+ if (exf->reinit) {
+ for (i = crd->crd_skip;
+ i < crd->crd_skip + crd->crd_len; i += blks) {
+ if (crd->crd_flags & CRD_F_ENCRYPT)
+ exf->encrypt(sw->sw_kschedule, buf + i);
+ else
+ exf->decrypt(sw->sw_kschedule, buf + i);
+ }
+ } else if (crd->crd_flags & CRD_F_ENCRYPT) {
for (i = crd->crd_skip;
i < crd->crd_skip + crd->crd_len; i += blks) {
/* XOR with the IV/previous block, as appropriate. */
@@ -687,6 +735,9 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
case CRYPTO_RIJNDAEL128_CBC:
txf = &enc_xform_rijndael128;
goto enccommon;
+ case CRYPTO_AES_XTS:
+ txf = &enc_xform_aes_xts;
+ goto enccommon;
case CRYPTO_CAMELLIA_CBC:
txf = &enc_xform_camellia;
goto enccommon;
@@ -845,6 +896,7 @@ swcr_freesession(device_t dev, u_int64_t tid)
case CRYPTO_CAST_CBC:
case CRYPTO_SKIPJACK_CBC:
case CRYPTO_RIJNDAEL128_CBC:
+ case CRYPTO_AES_XTS:
case CRYPTO_CAMELLIA_CBC:
case CRYPTO_NULL_CBC:
txf = swd->sw_exf;
@@ -958,6 +1010,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
case CRYPTO_CAST_CBC:
case CRYPTO_SKIPJACK_CBC:
case CRYPTO_RIJNDAEL128_CBC:
+ case CRYPTO_AES_XTS:
case CRYPTO_CAMELLIA_CBC:
if ((crp->crp_etype = swcr_encdec(crd, sw,
crp->crp_buf, crp->crp_flags)) != 0)
@@ -1050,6 +1103,7 @@ swcr_attach(device_t dev)
REGISTER(CRYPTO_MD5);
REGISTER(CRYPTO_SHA1);
REGISTER(CRYPTO_RIJNDAEL128_CBC);
+ REGISTER(CRYPTO_AES_XTS);
REGISTER(CRYPTO_CAMELLIA_CBC);
REGISTER(CRYPTO_DEFLATE_COMP);
#undef REGISTER
OpenPOWER on IntegriCloud