diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2009-12-04 01:34:03 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2009-12-04 01:34:03 +0200 |
commit | 7e13b2bef6fd81b5eadeaa982e7e82f82ae59209 (patch) | |
tree | 1797adabd90ca2faec674d137fbf21b737c5ba23 | |
parent | 0ae0d8cf7ba637036e1ad73c74b55b0cd084c64a (diff) | |
download | cryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.tar.gz cryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.tar.xz cryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.zip |
Revert "Added CIOCCRYPTV that will encrypt/hash iovectors.". This
is a cryptodev release that intends to be fully compatible with
OpenBSD and FreeBSD APIs.
This reverts commit 30181c1a49a63fddc97dd10dbac1b49568aede1f.
Conflicts:
cryptodev.c
-rw-r--r-- | cryptodev.c | 188 | ||||
-rw-r--r-- | cryptodev.h | 29 |
2 files changed, 77 insertions, 140 deletions
diff --git a/cryptodev.c b/cryptodev.c index 5380804..17a4708 100644 --- a/cryptodev.c +++ b/cryptodev.c @@ -401,7 +401,10 @@ crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid) return ses_ptr; } -static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv) +/* This is the main crypto function - feed it with plaintext + and get a ciphertext (or vice versa :-) */ +static int +crypto_run(struct fcrypt *fcr, struct crypt_op *cop) { char *data, ivp[EALG_MAX_BLOCK_LEN]; char __user *src, __user *dst; @@ -411,7 +414,6 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv) size_t nbytes, bufsize; int ret = 0; uint8_t hash_output[HASH_MAX_LEN]; - int blocksize=1, i; struct blkcipher_desc bdesc = { .flags = CRYPTO_TFM_REQ_MAY_SLEEP, }; @@ -420,27 +422,29 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv) }; - if (unlikely(copv->op != COP_ENCRYPT && copv->op != COP_DECRYPT)) { - dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", copv->op); + if (unlikely(cop->op != COP_ENCRYPT && cop->op != COP_DECRYPT)) { + dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", cop->op); return -EINVAL; } - ses_ptr = crypto_get_session_by_sid(fcr, copv->ses); + ses_ptr = crypto_get_session_by_sid(fcr, cop->ses); if (!ses_ptr) { - dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", copv->ses); + dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", cop->ses); return -EINVAL; } + nbytes = cop->len; data = (char*)__get_free_page(GFP_KERNEL); if (unlikely(!data)) { ret = -ENOMEM; goto out_unlock; } + bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes; + nbytes = cop->len; bdesc.tfm = ses_ptr->tfm; hdesc.tfm = ses_ptr->hash_tfm; - if (hdesc.tfm) { ret = crypto_hash_init(&hdesc); if (unlikely(ret)) { @@ -450,97 +454,81 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv) } } - if (ses_ptr->tfm) { - blocksize = crypto_blkcipher_blocksize(ses_ptr->tfm); - ivsize = crypto_blkcipher_ivsize(ses_ptr->tfm); - - if (copv->iv) { - copy_from_user(ivp, copv->iv, ivsize); - crypto_blkcipher_set_iv(ses_ptr->tfm, ivp, ivsize); - } - } - - dst = copv->dst; + if (bdesc.tfm) { + int blocksize = crypto_blkcipher_blocksize(bdesc.tfm); - for (i=0;i<copv->iovec_cnt;i++) { - nbytes = copv->iovec[i].len; - - if (unlikely(bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER) && (nbytes % blocksize))) { + if (unlikely(nbytes % blocksize)) { dprintk(1, KERN_ERR, "data size (%zu) isn't a multiple of block size (%u)\n", - nbytes, crypto_blkcipher_blocksize(ses_ptr->tfm)); + nbytes, blocksize); ret = -EINVAL; goto out_unlock; } - bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes; + ivsize = crypto_blkcipher_ivsize(bdesc.tfm); - src = copv->iovec[i].src; + if (cop->iv) { + copy_from_user(ivp, cop->iv, ivsize); + crypto_blkcipher_set_iv(bdesc.tfm, ivp, ivsize); + } + } - while(nbytes > 0) { - size_t current_len = nbytes > bufsize ? bufsize : nbytes; + src = cop->src; + dst = cop->dst; - copy_from_user(data, src, current_len); - sg_set_buf(&sg, data, current_len); + while(nbytes > 0) { + size_t current_len = nbytes > bufsize ? bufsize : nbytes; - /* Always hash before encryption and after decryption. Maybe - * we should introduce a flag to switch... TBD later on. - */ - if (copv->op == COP_ENCRYPT) { - if (hdesc.tfm && (copv->iovec[i].op_flags & IOP_HASH)) { - ret = crypto_hash_update(&hdesc, &sg, current_len); - if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - goto out; - } - } - if (bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER)) { - ret = crypto_blkcipher_encrypt(&bdesc, &sg, &sg, current_len); - - if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - goto out; - } - copy_to_user(dst, data, current_len); - dst += current_len; - } - } else { - if (bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER)) { - ret = crypto_blkcipher_decrypt(&bdesc, &sg, &sg, current_len); + copy_from_user(data, src, current_len); - if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - goto out; - } - copy_to_user(dst, data, current_len); - dst += current_len; + sg_set_buf(&sg, data, current_len); + /* Always hash before encryption and after decryption. Maybe + * we should introduce a flag to switch... TBD later on. + */ + if (cop->op == COP_ENCRYPT) { + if (hdesc.tfm) { + ret = crypto_hash_update(&hdesc, &sg, current_len); + if (unlikely(ret)) { + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + goto out; } + } + if (bdesc.tfm) { + ret = crypto_blkcipher_encrypt(&bdesc, &sg, &sg, current_len); - if (hdesc.tfm && (copv->iovec[i].op_flags & IOP_HASH)) { - ret = crypto_hash_update(&hdesc, &sg, current_len); - if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - goto out; - } + if (unlikely(ret)) { + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + goto out; } + copy_to_user(dst, data, current_len); + dst += current_len; } + } else { + if (bdesc.tfm) { + ret = crypto_blkcipher_decrypt(&bdesc, &sg, &sg, current_len); - nbytes -= current_len; - src += current_len; - } + if (unlikely(ret)) { + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + goto out; + } + copy_to_user(dst, data, current_len); + dst += current_len; -#if defined(CRYPTODEV_STATS) - if (enable_stats) { - /* this is safe - we check cop->op at the function entry */ - ses_ptr->stat[copv->op] += copv->iovec[i].len; - if (ses_ptr->stat_max_size < copv->iovec[i].len) - ses_ptr->stat_max_size = copv->iovec[i].len; - ses_ptr->stat_count++; - } -#endif + } + if (hdesc.tfm) { + ret = crypto_hash_update(&hdesc, &sg, current_len); + if (unlikely(ret)) { + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + goto out; + } + } + } + + nbytes -= current_len; + src += current_len; } if (hdesc.tfm) { @@ -550,8 +538,18 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv) goto out; } - copy_to_user(copv->mac, hash_output, crypto_hash_digestsize(ses_ptr->hash_tfm)); + copy_to_user(cop->mac, hash_output, crypto_hash_digestsize(ses_ptr->hash_tfm)); + } + +#if defined(CRYPTODEV_STATS) + if (enable_stats) { + /* this is safe - we check cop->op at the function entry */ + ses_ptr->stat[cop->op] += cop->len; + if (ses_ptr->stat_max_size < cop->len) + ses_ptr->stat_max_size = cop->len; + ses_ptr->stat_count++; } +#endif out: free_page((unsigned long)data); @@ -562,33 +560,6 @@ out_unlock: return ret; } -/* This is the main crypto function - feed it with plaintext - and get a ciphertext (or vice versa :-) */ -static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) -{ - struct crypt_opv copv; - struct crypt_iovec iovec; - - iovec.src = cop->src; - iovec.len = cop->len; - iovec.op_flags = IOP_CIPHER|IOP_HASH; - - copv.op = cop->op; - copv.ses = cop->ses; - copv.flags = cop->flags; - copv.iovec = &iovec; - copv.iovec_cnt = 1; - - copv.dst = cop->dst; - copv.mac = cop->mac; - copv.iv = cop->iv; - - return crypto_runv(fcr, &copv); - -} - - - /* ====== /dev/crypto ====== */ static int @@ -644,7 +615,6 @@ cryptodev_ioctl(struct inode *inode, struct file *filp, int __user *p = (void __user *)arg; struct session_op sop; struct crypt_op cop; - struct crypt_opv copv; struct fcrypt *fcr = filp->private_data; uint32_t ses; int ret, fd; @@ -680,12 +650,6 @@ cryptodev_ioctl(struct inode *inode, struct file *filp, copy_to_user((void*)arg, &cop, sizeof(cop)); return ret; - case CIOCCRYPTV: - copy_from_user(&cop, (void*)arg, sizeof(copv)); - ret = crypto_runv(fcr, &copv); - copy_to_user((void*)arg, &copv, sizeof(copv)); - return ret; - default: return -EINVAL; } diff --git a/cryptodev.h b/cryptodev.h index 55c3279..fcdd006 100644 --- a/cryptodev.h +++ b/cryptodev.h @@ -75,7 +75,7 @@ struct crypt_op { uint32_t ses; /* from session_op->ses */ #define COP_DECRYPT 0 #define COP_ENCRYPT 1 - uint16_t op; /* ie. COP_ENCRYPT */ + uint32_t op; /* ie. COP_ENCRYPT */ uint32_t flags; /* unused */ size_t len; @@ -84,30 +84,6 @@ struct crypt_op { void *iv; }; -struct crypt_iovec { -#define IOP_CIPHER 1 -#define IOP_HASH 2 - uint16_t op_flags; /* ie. IOP_CIPHER|IOP_HASH */ - void *src; - size_t len; -}; - -/* ioctl parameter to request a crypt/decrypt operation against a session */ -struct crypt_opv { - uint32_t ses; /* from session_op->ses */ - #define COP_DECRYPT 0 - #define COP_ENCRYPT 1 - uint16_t op; /* ie. COP_ENCRYPT */ - uint32_t flags; /* unused */ - - struct crypt_iovec* iovec; - uint16_t iovec_cnt; - - void *dst; - void *mac; - void *iv; -}; - /* clone original filedescriptor */ #define CRIOGET _IOWR('c', 101, uint32_t) @@ -124,9 +100,6 @@ struct crypt_opv { #define CIOCKEY _IOWR('c', 105, void *) #define CIOCASYMFEAT _IOR('c', 106, uint32_t) -/* request encryption/decryptions of a given buffer vector */ -#define CIOCCRYPTV _IOWR('c', 107, struct crypt_opv) - #endif /* _CRYPTODEV_H */ /* unused structures */ |