summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-07-27 18:04:50 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-07-27 18:04:50 +0200
commite6b93d8a7e1d3d4a3d76312fc84319ff6d596067 (patch)
treeeb79baf203de7e9574cc52ff0536478392c3dd4c /crypto
parent7cc28b8bafe112037edae18ea0e590e7c9d074fa (diff)
parentd5c2b894102e59efe499c231a32065afcf37e463 (diff)
downloadkernel-crypto-e6b93d8a7e1d3d4a3d76312fc84319ff6d596067.tar.gz
kernel-crypto-e6b93d8a7e1d3d4a3d76312fc84319ff6d596067.tar.xz
kernel-crypto-e6b93d8a7e1d3d4a3d76312fc84319ff6d596067.zip
Merge branch 'standalone-rename' into userspace-crypto
Conflicts: crypto/userspace/Makefile
Diffstat (limited to 'crypto')
-rw-r--r--crypto/userspace/Makefile2
-rw-r--r--crypto/userspace/cryptodev_cipher.c19
-rw-r--r--crypto/userspace/cryptodev_int.h2
-rw-r--r--crypto/userspace/cryptodev_main.c49
-rw-r--r--crypto/userspace/ncr-dh.c282
-rw-r--r--crypto/userspace/ncr-dh.h25
-rw-r--r--crypto/userspace/ncr-int.h9
-rw-r--r--crypto/userspace/ncr-key-storage.c21
-rw-r--r--crypto/userspace/ncr-key-wrap.c23
-rw-r--r--crypto/userspace/ncr-key.c108
-rw-r--r--crypto/userspace/ncr-limits.c21
-rw-r--r--crypto/userspace/ncr-pk.c189
-rw-r--r--crypto/userspace/ncr-pk.h5
-rw-r--r--crypto/userspace/ncr-sessions.c118
-rw-r--r--crypto/userspace/ncr.c27
15 files changed, 718 insertions, 182 deletions
diff --git a/crypto/userspace/Makefile b/crypto/userspace/Makefile
index 6e5d5388499..e82aabdbd7e 100644
--- a/crypto/userspace/Makefile
+++ b/crypto/userspace/Makefile
@@ -64,7 +64,7 @@ TOMCRYPT_OBJECTS = libtomcrypt/misc/zeromem.o libtomcrypt/misc/crypt/crypt_argch
libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.o
cryptodev-objs := cryptodev_main.o cryptodev_cipher.o ncr.o \
- ncr-key.o ncr-limits.o ncr-pk.o ncr-sessions.o \
+ ncr-key.o ncr-limits.o ncr-pk.o ncr-sessions.o ncr-dh.o \
ncr-key-wrap.o ncr-key-storage.o $(TOMMATH_OBJECTS) \
$(TOMCRYPT_OBJECTS)
diff --git a/crypto/userspace/cryptodev_cipher.c b/crypto/userspace/cryptodev_cipher.c
index d5e1df729ba..00fa76391fe 100644
--- a/crypto/userspace/cryptodev_cipher.c
+++ b/crypto/userspace/cryptodev_cipher.c
@@ -2,21 +2,24 @@
* Driver for /dev/crypto device (aka CryptoDev)
*
* Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Portions Copyright (c) 2010 Michael Weiser
+ * Portions Copyright (c) 2010 Phil Sutter
*
* This file is part of linux cryptodev.
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/crypto.h>
diff --git a/crypto/userspace/cryptodev_int.h b/crypto/userspace/cryptodev_int.h
index 4b63225d09e..fdab390df4b 100644
--- a/crypto/userspace/cryptodev_int.h
+++ b/crypto/userspace/cryptodev_int.h
@@ -25,7 +25,7 @@
extern int cryptodev_verbosity;
/* For zero copy */
-int __get_userbuf(uint8_t *addr, uint32_t len, int write,
+int __get_userbuf(uint8_t __user *addr, uint32_t len, int write,
int pgcount, struct page **pg, struct scatterlist *sg);
void release_user_pages(struct page **pg, int pagecount);
diff --git a/crypto/userspace/cryptodev_main.c b/crypto/userspace/cryptodev_main.c
index 167689e73af..4d673e472a2 100644
--- a/crypto/userspace/cryptodev_main.c
+++ b/crypto/userspace/cryptodev_main.c
@@ -6,18 +6,19 @@
*
* This file is part of linux cryptodev.
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
@@ -446,7 +447,7 @@ static int
__crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop)
{
char *data;
- char __user *src, __user *dst;
+ char __user *src, *dst;
struct scatterlist sg;
size_t nbytes, bufsize;
int ret = 0;
@@ -508,7 +509,7 @@ void release_user_pages(struct page **pg, int pagecount)
#define PAGEOFFSET(buf) ((unsigned long)buf & ~PAGE_MASK)
/* fetch the pages addr resides in into pg and initialise sg with them */
-int __get_userbuf(uint8_t *addr, uint32_t len, int write,
+int __get_userbuf(uint8_t __user *addr, uint32_t len, int write,
int pgcount, struct page **pg, struct scatterlist *sg)
{
int ret, pglen, i = 0;
@@ -560,19 +561,27 @@ static int get_userbuf(struct csession *ses,
(*tot_pages) = pagecount = src_pagecount + dst_pagecount;
if (pagecount > ses->array_size) {
- while (ses->array_size < pagecount)
- ses->array_size *= 2;
+ struct scatterlist *sg;
+ struct page **pages;
+ int array_size;
- dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
- __func__, ses->array_size);
- ses->pages = krealloc(ses->pages, ses->array_size *
- sizeof(struct page *), GFP_KERNEL);
- ses->sg = krealloc(ses->sg, ses->array_size *
- sizeof(struct scatterlist), GFP_KERNEL);
+ for (array_size = ses->array_size; array_size < pagecount;
+ array_size *= 2)
+ ;
- if (ses->sg == NULL || ses->pages == NULL) {
+ dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
+ __func__, array_size);
+ pages = krealloc(ses->pages, array_size * sizeof(struct page *),
+ GFP_KERNEL);
+ if (pages == NULL)
return -ENOMEM;
- }
+ ses->pages = pages;
+ sg = krealloc(ses->sg, array_size * sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (sg == NULL)
+ return -ENOMEM;
+ ses->sg = sg;
+ ses->array_size = array_size;
}
if (__get_userbuf(cop->src, cop->len, write_src,
diff --git a/crypto/userspace/ncr-dh.c b/crypto/userspace/ncr-dh.c
new file mode 100644
index 00000000000..00178420c31
--- /dev/null
+++ b/crypto/userspace/ncr-dh.c
@@ -0,0 +1,282 @@
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
+ *
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ *
+ * This file is part of linux cryptodev.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/cryptodev.h>
+#include <linux/mm.h>
+#include <linux/ncr.h>
+#include <linux/random.h>
+#include <asm/uaccess.h>
+#include <asm/ioctl.h>
+#include <linux/scatterlist.h>
+#include <ncr-int.h>
+#include <tomcrypt.h>
+#include <ncr-dh.h>
+
+void dh_free(dh_key * key)
+{
+ mp_clear_multi(&key->p, &key->g, &key->x, NULL);
+}
+
+int dh_import_params(dh_key * key, uint8_t * p, size_t p_size, uint8_t * g,
+ size_t g_size)
+{
+ int ret;
+ int err;
+
+ if ((err =
+ mp_init_multi(&key->p, &key->g, &key->x, &key->y,
+ NULL)) != CRYPT_OK) {
+ err();
+ return -ENOMEM;
+ }
+
+ if ((err =
+ mp_read_unsigned_bin(&key->p, (unsigned char *) p,
+ p_size)) != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ if ((err =
+ mp_read_unsigned_bin(&key->g, (unsigned char *) g,
+ g_size)) != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ return 0;
+ fail:
+ mp_clear_multi(&key->p, &key->g, &key->x, &key->y, NULL);
+
+ return ret;
+}
+
+int dh_generate_key(dh_key * key)
+{
+ void *buf;
+ int size;
+ int err, ret;
+
+ size = mp_unsigned_bin_size(&key->p);
+ if (size == 0) {
+ err();
+ return -EINVAL;
+ }
+
+ buf = kmalloc(size, GFP_KERNEL);
+ if (buf == NULL) {
+ err();
+ return -ENOMEM;
+ }
+
+ get_random_bytes(buf, size);
+
+ if ((err = mp_read_unsigned_bin(&key->x, buf, size)) != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ err = mp_mod(&key->x, &key->p, &key->x);
+ if (err != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ key->type = PK_PRIVATE;
+
+ ret = 0;
+ fail:
+ kfree(buf);
+
+ return ret;
+
+}
+
+int dh_generate_public(dh_key * public, dh_key * private)
+{
+ int err, ret;
+
+ err =
+ mp_exptmod(&private->g, &private->x, &private->p, &public->y);
+ if (err != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ public->type = PK_PUBLIC;
+
+ ret = 0;
+ fail:
+
+ return ret;
+}
+
+int dh_export(uint8_t * out, unsigned long * outlen, int type, dh_key * key)
+{
+ unsigned long zero = 0;
+ int err;
+
+ if (out == NULL || outlen == NULL || key == NULL) {
+ err();
+ return -EINVAL;
+ }
+
+ /* can we store the static header? */
+ if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
+ return -EINVAL;
+ }
+
+ if (type != PK_PUBLIC && type != PK_PRIVATE) {
+ return -EINVAL;
+ }
+
+ /* This encoding is different from the one in original
+ * libtomcrypt. It uses a compatible encoding with gnutls
+ * and openssl
+ */
+ if (type == PK_PRIVATE) {
+ err = der_encode_sequence_multi(out, outlen,
+ LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
+ LTC_ASN1_INTEGER, 1UL, &key->p,
+ LTC_ASN1_INTEGER, 1UL, &key->g,
+ LTC_ASN1_INTEGER, 1UL, &key->x,
+ LTC_ASN1_EOL, 0UL, NULL);
+ } else {
+ err = mp_unsigned_bin_size(&key->y);
+ if (err > *outlen) {
+ err();
+ return -EOVERFLOW;
+ }
+
+ *outlen = err;
+
+ err = mp_to_unsigned_bin(&key->y, out);
+ }
+
+ if (err != CRYPT_OK) {
+ err();
+ return _ncr_tomerr(err);
+ }
+
+ return 0;
+}
+
+int dh_import(const uint8_t * in, size_t inlen, dh_key * key)
+{
+ int err;
+ unsigned long zero = 0;
+
+ if (in == NULL || key == NULL) {
+ err();
+ return -EINVAL;
+ }
+
+ /* init key */
+ if (mp_init_multi
+ (&key->p, &key->g, &key->x, &key->y, NULL) != CRYPT_OK) {
+ return -ENOMEM;
+ }
+
+ /* get key type */
+ if ((err = der_decode_sequence_multi(in, inlen,
+ LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
+ LTC_ASN1_INTEGER, 1UL, &key->p,
+ LTC_ASN1_INTEGER, 1UL, &key->g,
+ LTC_ASN1_INTEGER, 1UL, &key->x,
+ LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
+ key->type = PK_PRIVATE;
+ } else { /* public */
+ err = mp_read_unsigned_bin(&key->y, in, inlen);
+ key->type = PK_PUBLIC;
+ }
+
+ if (err != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+
+ return 0;
+
+ LBL_ERR:
+ mp_clear_multi(&key->p, &key->g, &key->x, &key->y, NULL);
+ return _ncr_tomerr(err);
+}
+
+int dh_derive_gxy(struct key_item_st* newkey, dh_key * key,
+ void* pk, size_t pk_size)
+{
+int ret, err;
+mp_int y, gxy;
+ /* newkey will be a secret key with value of g^{xy}
+ */
+
+ if (mp_init_multi(&y, &gxy, NULL) != CRYPT_OK) {
+ err();
+ return -ENOMEM;
+ }
+
+ if (key->type != PK_PRIVATE) {
+ err();
+ return -EINVAL;
+ }
+
+ if ((err=mp_read_unsigned_bin(&y, pk, pk_size)) != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ if ((err=mp_exptmod(&y, &key->x, &key->p, &gxy))!= CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ err = mp_unsigned_bin_size(&gxy);
+ if (err > NCR_CIPHER_MAX_KEY_LEN) {
+ err();
+ ret = -EOVERFLOW;
+ goto fail;
+ }
+ newkey->key.secret.size = err;
+
+ err = mp_to_unsigned_bin(&gxy, newkey->key.secret.data);
+ if (err != CRYPT_OK) {
+ err();
+ ret = _ncr_tomerr(err);
+ goto fail;
+ }
+
+ newkey->type = NCR_KEY_TYPE_SECRET;
+
+ ret = 0;
+fail:
+ mp_clear_multi(&y, &gxy, NULL);
+
+ return ret;
+}
diff --git a/crypto/userspace/ncr-dh.h b/crypto/userspace/ncr-dh.h
new file mode 100644
index 00000000000..cc45d3206cc
--- /dev/null
+++ b/crypto/userspace/ncr-dh.h
@@ -0,0 +1,25 @@
+#ifndef NCR_DH_H
+# define NCR_DH_H
+
+#include <tomcrypt.h>
+
+typedef struct {
+ int type; /* PK_PRIVATE or PK_PUBLIC */
+ mp_int p;
+ mp_int g;
+ mp_int x; /* private */
+ mp_int y; /* public: y=g^x */
+} dh_key;
+
+int dh_generate_key(dh_key * key);
+int dh_import_params(dh_key * key, uint8_t* p, size_t p_size, uint8_t* g, size_t g_size);
+void dh_free(dh_key * key);
+int dh_generate_public(dh_key * public, dh_key* private);
+
+int dh_export(uint8_t *out, unsigned long *outlen, int type, dh_key *key);
+int dh_import(const uint8_t *in, size_t inlen, dh_key *key);
+
+int dh_derive_gxy(struct key_item_st* newkey, dh_key * key,
+ void* pk, size_t pk_size);
+
+#endif
diff --git a/crypto/userspace/ncr-int.h b/crypto/userspace/ncr-int.h
index db6950b596c..5572f71f217 100644
--- a/crypto/userspace/ncr-int.h
+++ b/crypto/userspace/ncr-int.h
@@ -5,6 +5,7 @@
#include <asm/atomic.h>
#include "cryptodev_int.h"
#include <ncr-pk.h>
+#include <ncr-dh.h>
#define KEY_DATA_MAX_SIZE 3*1024
@@ -18,6 +19,7 @@ struct algo_properties_st {
unsigned can_sign:1;
unsigned can_digest:1;
unsigned can_encrypt:1;
+ unsigned can_kx:1; /* key exchange */
unsigned is_symmetric:1;
unsigned is_pk:1;
int digest_size;
@@ -73,6 +75,7 @@ struct key_item_st {
union {
rsa_key rsa;
dsa_key dsa;
+ dh_key dh;
} pk;
} key;
@@ -107,7 +110,11 @@ void ncr_deinit_lists(struct ncr_lists *lst);
int ncr_ioctl(struct ncr_lists*, struct file *filp,
unsigned int cmd, unsigned long arg);
-
+
+/* key derivation */
+int ncr_key_derive(struct list_sem_st* key_lst, void __user* arg);
+
+/* key handling */
int ncr_key_init(struct list_sem_st*, void __user* arg);
int ncr_key_deinit(struct list_sem_st*, void __user* arg);
int ncr_key_export(struct list_sem_st* key_lst,void __user* arg);
diff --git a/crypto/userspace/ncr-key-storage.c b/crypto/userspace/ncr-key-storage.c
index af6c9c15531..63c88eab440 100644
--- a/crypto/userspace/ncr-key-storage.c
+++ b/crypto/userspace/ncr-key-storage.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * This file is part of linux cryptodev.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This file is part of linux cryptodev.
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/cryptodev.h>
diff --git a/crypto/userspace/ncr-key-wrap.c b/crypto/userspace/ncr-key-wrap.c
index e105e3ad415..ed8297dfd59 100644
--- a/crypto/userspace/ncr-key-wrap.c
+++ b/crypto/userspace/ncr-key-wrap.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * This file is part of linux cryptodev.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This file is part of linux cryptodev.
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/cryptodev.h>
@@ -222,7 +225,7 @@ size_t size;
if (ret < 0) {
err();
kfree(R);
- return ret;
+ goto cleanup;
}
if (memcmp(A, iv, 4)!= 0) {
diff --git a/crypto/userspace/ncr-key.c b/crypto/userspace/ncr-key.c
index 09e3174a19b..de282b87ea9 100644
--- a/crypto/userspace/ncr-key.c
+++ b/crypto/userspace/ncr-key.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
-
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * This file is part of linux cryptodev.
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This file is part of linux cryptodev.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/cryptodev.h>
@@ -273,6 +276,7 @@ int ret;
goto fail;
}
}
+
data.idata_size = item->key.secret.size;
break;
case NCR_KEY_TYPE_PUBLIC:
@@ -343,7 +347,9 @@ size_t tmp_size;
err();
return ret;
}
-
+
+ ncr_key_clear(item);
+
tmp = kmalloc(data.idata_size, GFP_KERNEL);
if (tmp == NULL) {
err();
@@ -423,6 +429,9 @@ static void ncr_key_clear(struct key_item_st* item)
ncr_pk_clear(item);
}
memset(&item->key, 0, sizeof(item->key));
+ memset(item->key_id, 0, sizeof(item->key_id));
+ item->key_id_size = 0;
+ item->flags = 0;
return;
}
@@ -459,8 +468,7 @@ size_t size;
}
item->type = algo->key_type;
if (item->type == NCR_KEY_TYPE_SECRET) {
- /* arbitrary */
- item->algorithm = _ncr_algo_to_properties(NCR_ALG_AES_CBC);
+ item->algorithm = algo;
size = gen.params.params.secret.bits/8;
if ((gen.params.params.secret.bits % 8 != 0) ||
@@ -508,14 +516,23 @@ int ret;
err();
return ret;
}
+
+ if (item->type == NCR_KEY_TYPE_INVALID) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
info.flags = item->flags;
info.type = item->type;
info.algorithm = item->algorithm->algo;
+
+ ret = 0;
+fail:
_ncr_key_item_put( item);
- return 0;
+ return ret;
}
int ncr_key_generate_pair(struct list_sem_st* lst, void __user* arg)
@@ -582,13 +599,64 @@ fail:
return ret;
}
-int ncr_key_derive(struct list_sem_st* lst, void __user* arg)
+/* "exports" a key to a data item. If the key is not exportable
+ * to userspace then the data item will also not be.
+ */
+int ncr_key_derive(struct list_sem_st* key_lst, void __user* arg)
{
- return -EINVAL;
-}
+struct ncr_key_derivation_params_st data;
+int ret;
+struct key_item_st* key = NULL;
+struct key_item_st* newkey = NULL;
-int ncr_key_get_public(struct list_sem_st* lst, void __user* arg)
-{
- return -EINVAL;
+ if (unlikely(copy_from_user(&data, arg, sizeof(data)))) {
+ err();
+ return -EFAULT;
+ }
+
+ ret = ncr_key_item_get_read( &key, key_lst, data.key);
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+
+ ret = ncr_key_item_get_write( &newkey, key_lst, data.newkey);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ ncr_key_clear(newkey);
+
+ newkey->flags = data.keyflags;
+
+ switch (key->type) {
+ case NCR_KEY_TYPE_PUBLIC:
+ case NCR_KEY_TYPE_PRIVATE:
+ ret = ncr_pk_derive(newkey, key, &data);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+ break;
+ default:
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (unlikely(copy_to_user(arg, &data, sizeof(data)))) {
+ err();
+ ret = -EFAULT;
+ } else
+ ret = 0;
+
+fail:
+ if (key)
+ _ncr_key_item_put(key);
+ if (newkey)
+ _ncr_key_item_put(newkey);
+ return ret;
+
}
diff --git a/crypto/userspace/ncr-limits.c b/crypto/userspace/ncr-limits.c
index 1e8da1af4ac..eabf4b083c6 100644
--- a/crypto/userspace/ncr-limits.c
+++ b/crypto/userspace/ncr-limits.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * This file is part of linux cryptodev.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This file is part of linux cryptodev.
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/cryptodev.h>
diff --git a/crypto/userspace/ncr-pk.c b/crypto/userspace/ncr-pk.c
index de23e94d73b..54a505fb77b 100644
--- a/crypto/userspace/ncr-pk.c
+++ b/crypto/userspace/ncr-pk.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * This file is part of linux cryptodev.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This file is part of linux cryptodev.
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/cryptodev.h>
@@ -31,7 +34,7 @@
static struct workqueue_struct * pk_wq = NULL;
-static int tomerr(int err)
+int _ncr_tomerr(int err)
{
switch (err) {
case CRYPT_BUFFER_OVERFLOW:
@@ -54,6 +57,9 @@ void ncr_pk_clear(struct key_item_st* key)
case NCR_ALG_DSA:
dsa_free(&key->key.pk.dsa);
break;
+ case NCR_ALG_DH:
+ dh_free(&key->key.pk.dh);
+ break;
default:
return;
}
@@ -78,14 +84,14 @@ static int ncr_pk_make_public_and_id( struct key_item_st * private, struct key_i
cret = rsa_export(tmp, &max_size, PK_PUBLIC, &private->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
cret = rsa_import(tmp, max_size, &public->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
break;
@@ -93,14 +99,21 @@ static int ncr_pk_make_public_and_id( struct key_item_st * private, struct key_i
cret = dsa_export(tmp, &max_size, PK_PUBLIC, &private->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
cret = dsa_import(tmp, max_size, &public->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
+ goto fail;
+ }
+ break;
+ case NCR_ALG_DH:
+ ret = dh_generate_public(&public->key.pk.dh, &private->key.pk.dh);
+ if (ret < 0) {
+ err();
goto fail;
}
break;
@@ -114,7 +127,7 @@ static int ncr_pk_make_public_and_id( struct key_item_st * private, struct key_i
cret = hash_memory(_ncr_algo_to_properties(NCR_ALG_SHA1), tmp, max_size, private->key_id, &key_id_size);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
private->key_id_size = public->key_id_size = key_id_size;
@@ -130,7 +143,7 @@ fail:
int ncr_pk_pack( const struct key_item_st * key, uint8_t * packed, uint32_t * packed_size)
{
unsigned long max_size = *packed_size;
- int cret;
+ int cret, ret;
if (packed == NULL || packed_size == NULL) {
err();
@@ -143,7 +156,7 @@ int ncr_pk_pack( const struct key_item_st * key, uint8_t * packed, uint32_t * pa
if (cret != CRYPT_OK) {
*packed_size = max_size;
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
}
break;
case NCR_ALG_DSA:
@@ -151,21 +164,29 @@ int ncr_pk_pack( const struct key_item_st * key, uint8_t * packed, uint32_t * pa
if (cret != CRYPT_OK) {
*packed_size = max_size;
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
+ }
+ break;
+ case NCR_ALG_DH:
+ ret = dh_export(packed, &max_size, key->key.pk.dsa.type, (void*)&key->key.pk.dsa);
+ if (ret < 0) {
+ err();
+ return ret;
}
break;
default:
err();
return -EINVAL;
}
-
+
*packed_size = max_size;
+
return 0;
}
int ncr_pk_unpack( struct key_item_st * key, const void * packed, size_t packed_size)
{
- int cret;
+ int cret, ret;
if (key == NULL || packed == NULL) {
err();
@@ -177,14 +198,21 @@ int ncr_pk_unpack( struct key_item_st * key, const void * packed, size_t packed_
cret = rsa_import(packed, packed_size, (void*)&key->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
}
break;
case NCR_ALG_DSA:
cret = dsa_import(packed, packed_size, (void*)&key->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
+ }
+ break;
+ case NCR_ALG_DH:
+ ret = dh_import(packed, packed_size, (void*)&key->key.pk.dh);
+ if (ret < 0) {
+ err();
+ return ret;
}
break;
default:
@@ -208,7 +236,8 @@ struct keygen_st {
static void keygen_handler(struct work_struct *instance)
{
unsigned long e;
- int cret;
+ int cret, ret;
+ uint8_t * tmp = NULL;
struct keygen_st *st =
container_of(instance, struct keygen_st, pk_gen);
@@ -221,7 +250,7 @@ static void keygen_handler(struct work_struct *instance)
cret = rsa_make_key(st->params->params.rsa.bits/8, e, &st->private->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- st->ret = tomerr(cret);
+ st->ret = _ncr_tomerr(cret);
} else
st->ret = 0;
break;
@@ -235,15 +264,62 @@ static void keygen_handler(struct work_struct *instance)
st->params->params.dsa.p_bits/8, &st->private->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
- st->ret = tomerr(cret);
+ st->ret = _ncr_tomerr(cret);
} else
st->ret = 0;
break;
+ case NCR_ALG_DH: {
+ uint8_t * p, *g;
+ size_t p_size, g_size;
+
+ p_size = st->params->params.dh.p_size;
+ g_size = st->params->params.dh.g_size;
+
+ tmp = kmalloc(g_size+p_size, GFP_KERNEL);
+ if (tmp == NULL) {
+ err();
+ st->ret = -ENOMEM;
+ goto fail;
+ }
+
+ p = tmp;
+ g = &tmp[p_size];
+
+ if (unlikely(copy_from_user(p, st->params->params.dh.p, p_size))) {
+ err();
+ st->ret = -EFAULT;
+ goto fail;
+ }
+
+ if (unlikely(copy_from_user(g, st->params->params.dh.g, g_size))) {
+ err();
+ st->ret = -EFAULT;
+ goto fail;
+ }
+
+ ret = dh_import_params(&st->private->key.pk.dh, p, p_size, g, g_size);
+ if (ret < 0) {
+ err();
+ st->ret = ret;
+ goto fail;
+ }
+
+ ret = dh_generate_key(&st->private->key.pk.dh);
+ if (ret < 0) {
+ st->ret = ret;
+ err();
+ goto fail;
+ }
+ st->ret = 0;
+ break;
+ }
default:
err();
st->ret = -EINVAL;
}
+fail:
+ kfree(tmp);
complete(&st->completed);
}
@@ -305,7 +381,9 @@ void ncr_pk_queue_deinit(void)
destroy_workqueue(pk_wq);
}
-const struct algo_properties_st *ncr_key_params_get_sign_hash(const struct algo_properties_st *algo, struct ncr_key_params_st * params)
+const struct algo_properties_st *ncr_key_params_get_sign_hash(
+ const struct algo_properties_st *algo,
+ struct ncr_key_params_st * params)
{
ncr_algorithm_t id;
@@ -413,7 +491,7 @@ void * input, *output;
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
*osg_size = osize;
@@ -475,7 +553,7 @@ void * input, *output;
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
@@ -540,7 +618,7 @@ void * input, *output;
ctx->type, ctx->sign_hash, ctx->salt_len, &ctx->key->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
}
*osg_size = osize;
break;
@@ -550,7 +628,7 @@ void * input, *output;
if (cret != CRYPT_OK) {
err();
- return tomerr(cret);
+ return _ncr_tomerr(cret);
}
*osg_size = osize;
break;
@@ -601,7 +679,7 @@ uint8_t* sig;
ctx->salt_len, &stat, &ctx->key->key.pk.rsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
@@ -616,7 +694,7 @@ uint8_t* sig;
hash, hash_size, &stat, &ctx->key->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
- ret = tomerr(cret);
+ ret = _ncr_tomerr(cret);
goto fail;
}
@@ -637,3 +715,50 @@ fail:
kfree(sig);
return ret;
}
+
+int ncr_pk_derive(struct key_item_st* newkey, struct key_item_st* oldkey,
+ struct ncr_key_derivation_params_st * params)
+{
+int ret;
+void* tmp = NULL;
+size_t size;
+
+ switch(params->derive) {
+ case NCR_DERIVE_DH:
+ if (oldkey->type != NCR_KEY_TYPE_PRIVATE &&
+ oldkey->algorithm->algo != NCR_ALG_DH) {
+ err();
+ return -EINVAL;
+ }
+
+ size = params->params.params.dh.pub_size;
+ tmp = kmalloc(size, GFP_KERNEL);
+ if (tmp == NULL) {
+ err();
+ return -ENOMEM;
+ }
+
+ if (unlikely(copy_from_user(tmp, params->params.params.dh.pub,
+ size))) {
+ err();
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ ret = dh_derive_gxy(newkey, &oldkey->key.pk.dh, tmp, size);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ break;
+ default:
+ err();
+ return -EINVAL;
+ }
+
+ ret = 0;
+fail:
+ kfree(tmp);
+ return ret;
+}
diff --git a/crypto/userspace/ncr-pk.h b/crypto/userspace/ncr-pk.h
index fdc5e1c005b..f234f735b45 100644
--- a/crypto/userspace/ncr-pk.h
+++ b/crypto/userspace/ncr-pk.h
@@ -51,4 +51,9 @@ int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx,
const struct scatterlist* sign_sg, unsigned int sign_sg_cnt, size_t sign_sg_size,
const void* hash, size_t hash_size, ncr_error_t* err);
+int _ncr_tomerr(int err);
+
+int ncr_pk_derive(struct key_item_st* newkey, struct key_item_st* oldkey,
+ struct ncr_key_derivation_params_st * params);
+
#endif
diff --git a/crypto/userspace/ncr-sessions.c b/crypto/userspace/ncr-sessions.c
index 42a352ca62b..ff19bad08fd 100644
--- a/crypto/userspace/ncr-sessions.c
+++ b/crypto/userspace/ncr-sessions.c
@@ -1,22 +1,26 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
+ * Portions Copyright (c) 2010 Phil Sutter
+ *
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
* This file is part of linux cryptodev.
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * cryptodev is distributed in the hope that it will be useful,
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/crypto.h>
@@ -197,6 +201,8 @@ static const struct algo_properties_st algo_properties[] = {
.can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC },
{ .algo = NCR_ALG_DSA, .kstr = NULL, .is_pk = 1,
.can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC },
+ { .algo = NCR_ALG_DH, .kstr = NULL, .is_pk = 1,
+ .can_kx=1, .key_type = NCR_KEY_TYPE_PUBLIC },
{ .algo = NCR_ALG_NONE }
};
@@ -413,7 +419,7 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg)
return ret;
}
-int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt,
+static int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt,
size_t input_size, void *output, unsigned output_cnt, size_t *output_size)
{
int ret;
@@ -427,7 +433,7 @@ int ret;
return ret;
}
/* FIXME: handle ciphers that do not require that */
-
+ *output_size = input_size;
} else { /* public key */
ret = ncr_pk_cipher_encrypt(&sess->pk, input, input_cnt, input_size,
output, output_cnt, output_size);
@@ -441,7 +447,7 @@ int ret;
return 0;
}
-int _ncr_session_decrypt(struct session_item_st* sess, const struct scatterlist* input,
+static int _ncr_session_decrypt(struct session_item_st* sess, const struct scatterlist* input,
unsigned input_cnt, size_t input_size,
struct scatterlist *output, unsigned output_cnt, size_t *output_size)
{
@@ -456,7 +462,7 @@ int ret;
return ret;
}
/* FIXME: handle ciphers that do not require equality */
-
+ *output_size = input_size;
} else { /* public key */
ret = ncr_pk_cipher_decrypt(&sess->pk, input, input_cnt, input_size,
output, output_cnt, output_size);
@@ -470,7 +476,7 @@ int ret;
return 0;
}
-void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
+static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
{
struct session_item_st * item, *tmp;
@@ -489,6 +495,36 @@ void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
return;
}
+static int _ncr_session_grow_pages(struct session_item_st *ses, int pagecount)
+{
+ struct scatterlist *sg;
+ struct page **pages;
+ int array_size;
+
+ if (likely(pagecount < ses->array_size))
+ return 0;
+
+ for (array_size = ses->array_size; array_size < pagecount;
+ array_size *= 2)
+ ;
+
+ dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
+ __func__, array_size);
+ pages = krealloc(ses->pages, array_size * sizeof(struct page *),
+ GFP_KERNEL);
+ if (unlikely(pages == NULL))
+ return -ENOMEM;
+ ses->pages = pages;
+ sg = krealloc(ses->sg, array_size * sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (unlikely(sg == NULL))
+ return -ENOMEM;
+ ses->sg = sg;
+
+ ses->array_size = array_size;
+ return 0;
+}
+
/* Only the output buffer is given as scatterlist */
static int get_userbuf1(struct session_item_st* ses,
void __user * udata, size_t udata_size, struct scatterlist **dst_sg, unsigned *dst_cnt)
@@ -500,28 +536,8 @@ static int get_userbuf1(struct session_item_st* ses,
return -EINVAL;
}
- if (unlikely(ses->sg == NULL || ses->pages == NULL)) {
- err();
- return -ENOMEM;
- }
-
pagecount = PAGECOUNT(udata, udata_size);
-
- if (pagecount > ses->array_size) {
- while (ses->array_size < pagecount)
- ses->array_size *= 2;
-
- dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
- __func__, ses->array_size);
- ses->pages = krealloc(ses->pages, ses->array_size *
- sizeof(struct page *), GFP_KERNEL);
- ses->sg = krealloc(ses->sg, ses->array_size *
- sizeof(struct scatterlist), GFP_KERNEL);
-
- if (unlikely(ses->sg == NULL || ses->pages == NULL)) {
- return -ENOMEM;
- }
- }
+ _ncr_session_grow_pages(ses, pagecount);
if (__get_userbuf(udata, udata_size, 1,
pagecount, ses->pages, ses->sg)) {
@@ -549,11 +565,6 @@ static int get_userbuf2(struct session_item_st* ses,
return -EINVAL;
}
- if (unlikely(ses->sg == NULL || ses->pages == NULL)) {
- err();
- return -ENOMEM;
- }
-
src_pagecount = PAGECOUNT(op->data.udata.input, input_size);
if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */
@@ -570,22 +581,7 @@ static int get_userbuf2(struct session_item_st* ses,
}
pagecount = src_pagecount + dst_pagecount;
-
- if (pagecount > ses->array_size) {
- while (ses->array_size < pagecount)
- ses->array_size *= 2;
-
- dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
- __func__, ses->array_size);
- ses->pages = krealloc(ses->pages, ses->array_size *
- sizeof(struct page *), GFP_KERNEL);
- ses->sg = krealloc(ses->sg, ses->array_size *
- sizeof(struct scatterlist), GFP_KERNEL);
-
- if (ses->sg == NULL || ses->pages == NULL) {
- return -ENOMEM;
- }
- }
+ _ncr_session_grow_pages(ses, pagecount);
if (__get_userbuf(op->data.udata.input, input_size, write_src,
src_pagecount, ses->pages, ses->sg)) {
@@ -622,7 +618,7 @@ static int get_userbuf2(struct session_item_st* ses,
}
/* Called when userspace buffers are used */
-int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
{
int ret;
struct session_item_st* sess;
@@ -659,6 +655,12 @@ int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
goto fail;
}
+ if (osg_size < isg_size) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+
ret = _ncr_session_encrypt(sess, isg, isg_cnt, isg_size,
osg, osg_cnt, &osg_size);
if (ret < 0) {
@@ -731,7 +733,7 @@ static int try_session_update(struct ncr_lists* lists, struct ncr_session_op_st*
return 0;
}
-int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
{
int ret;
struct session_item_st* sess;
diff --git a/crypto/userspace/ncr.c b/crypto/userspace/ncr.c
index f1d22bdf787..87faace90a5 100644
--- a/crypto/userspace/ncr.c
+++ b/crypto/userspace/ncr.c
@@ -1,22 +1,25 @@
/*
* New driver for /dev/crypto device (aka CryptoDev)
-
- * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * This file is part of linux cryptodev.
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * cryptodev is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * cryptodev is distributed in the hope that it will be useful,
+ * This file is part of linux cryptodev.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/crypto.h>
@@ -103,7 +106,7 @@ struct ncr_master_key_st st;
dprintk(0, KERN_DEBUG, "Master key was previously initialized.\n");
}
- dprintk(0, KERN_INFO, "Intializing master key.\n");
+ dprintk(0, KERN_INFO, "Initializing master key.\n");
master_key.type = NCR_KEY_TYPE_SECRET;
@@ -156,10 +159,8 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp,
return ncr_master_key_set(arg);
case NCRIO_KEY_GENERATE_PAIR:
return ncr_key_generate_pair(&lst->key, arg);
-#if 0
case NCRIO_KEY_DERIVE:
return ncr_key_derive(&lst->key, arg);
-#endif
default:
return -EINVAL;
}