summaryrefslogtreecommitdiffstats
path: root/crypto/userspace/cryptodev_cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/userspace/cryptodev_cipher.c')
-rw-r--r--crypto/userspace/cryptodev_cipher.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/crypto/userspace/cryptodev_cipher.c b/crypto/userspace/cryptodev_cipher.c
index 8a003c5613a..1fb11473715 100644
--- a/crypto/userspace/cryptodev_cipher.c
+++ b/crypto/userspace/cryptodev_cipher.c
@@ -23,7 +23,6 @@
*/
#include <linux/crypto.h>
-#include <linux/cryptodev.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/ioctl.h>
@@ -217,7 +216,7 @@ ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatte
/* Hash functions */
-int cryptodev_hash_init( struct hash_data* hdata, const char* alg_name, int hmac_mode, void * mackey, size_t mackeylen)
+int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, const void *mackey, size_t mackeylen)
{
int ret;
@@ -229,7 +228,7 @@ int ret;
}
/* Copy the key from user and set to TFM. */
- if (hmac_mode != 0) {
+ if (mackey != NULL) {
ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen);
if (unlikely(ret)) {
@@ -279,6 +278,48 @@ error:
return ret;
}
+int cryptodev_hash_clone(struct hash_data *hdata, struct hash_data *old_data,
+ const void *mackey, size_t mackeylen)
+{
+ const char *algo;
+ void *state;
+ int ret;
+
+ /* We want exactly the same driver. */
+ algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(old_data->async.s));
+ ret = cryptodev_hash_init(hdata, algo, mackey, mackeylen);
+ if (unlikely(ret != 0))
+ return ret;
+
+ state = kmalloc(crypto_ahash_statesize(hdata->async.s), GFP_KERNEL);
+ if (unlikely(state == NULL)) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = crypto_ahash_export(old_data->async.request, state);
+ if (unlikely(ret != 0)) {
+ dprintk(0, KERN_ERR, "error exporting hash state\n");
+ goto err;
+ }
+ ret = crypto_ahash_import(hdata->async.request, state);
+ if (unlikely(ret != 0)) {
+ dprintk(0,KERN_ERR,
+ "error in crypto_hash_init()\n");
+ goto err;
+ }
+
+ kfree(state);
+
+ hdata->init = 1;
+ return 0;
+
+err:
+ kfree(state);
+ cryptodev_hash_deinit(hdata);
+ return ret;
+}
+
void cryptodev_hash_deinit(struct hash_data* hdata)
{
if (hdata->init) {