summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c24
-rw-r--r--crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c24
-rw-r--r--crypto/userspace/ncr-int.h3
-rw-r--r--crypto/userspace/ncr-key-wrap.c180
-rw-r--r--crypto/userspace/ncr-key.c2
-rw-r--r--crypto/userspace/ncr-limits.c2
-rw-r--r--crypto/userspace/ncr-sessions.c11
-rw-r--r--crypto/userspace/ncr.c10
-rw-r--r--include/linux/ncr.h3
9 files changed, 145 insertions, 114 deletions
diff --git a/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c b/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c
index 6c97e965e36..c0a2e2214c4 100644
--- a/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c
+++ b/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c
@@ -1,11 +1,25 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * The library is free for all purposes without any express
- * guarantee it works.
+ * 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 "tomcrypt.h"
/**
diff --git a/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c b/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c
index e37c4b40a0d..4c7e966491d 100644
--- a/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c
+++ b/crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c
@@ -1,11 +1,25 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 Katholieke Universiteit Leuven
*
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
+ * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org>
*
- * The library is free for all purposes without any express
- * guarantee it works.
+ * 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 "tomcrypt.h"
diff --git a/crypto/userspace/ncr-int.h b/crypto/userspace/ncr-int.h
index 2af794f41d3..e79747c12ca 100644
--- a/crypto/userspace/ncr-int.h
+++ b/crypto/userspace/ncr-int.h
@@ -8,6 +8,7 @@
#include <ncr-dh.h>
#define KEY_DATA_MAX_SIZE 3*1024
+#define NCR_CIPHER_MAX_KEY_LEN 1024
#define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__)
@@ -98,7 +99,6 @@ struct list_sem_st {
* are here.
*/
struct ncr_lists {
- struct list_sem_st data;
struct list_sem_st key;
/* sessions */
@@ -124,7 +124,6 @@ int ncr_key_generate(struct list_sem_st* data_lst, void __user* arg);
int ncr_key_info(struct list_sem_st*, void __user* arg);
int ncr_key_generate_pair(struct list_sem_st* lst, void __user* arg);
-int ncr_key_derive(struct list_sem_st*, void __user* arg);
int ncr_key_get_public(struct list_sem_st* lst, void __user* arg);
int ncr_key_item_get_read(struct key_item_st**st, struct list_sem_st* lst,
diff --git a/crypto/userspace/ncr-key-wrap.c b/crypto/userspace/ncr-key-wrap.c
index 5d3ec675b6c..cb431c9b5aa 100644
--- a/crypto/userspace/ncr-key-wrap.c
+++ b/crypto/userspace/ncr-key-wrap.c
@@ -46,7 +46,7 @@ static void val64_xor( val64_t val, uint32_t x)
val[4] ^= (x >> 24) & 0xff;
}
-static int rfc3394_wrap(val64_t R[], unsigned int n, struct cipher_data* ctx,
+static int rfc3394_wrap(val64_t *R, unsigned int n, struct cipher_data* ctx,
uint8_t* output, size_t *output_size, const uint8_t iv[8])
{
val64_t A;
@@ -120,6 +120,7 @@ size_t n;
int i, ret;
struct cipher_data ctx;
uint8_t iv[8];
+val64_t *R = NULL;
if (iv_size != 4) {
memcpy(iv, RFC5649_IV, 4);
@@ -144,33 +145,32 @@ uint8_t iv[8];
return ret;
}
- {
- val64_t *R;
+ R = kmalloc(n * sizeof (*R), GFP_KERNEL);
+ if (R == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto cleanup;
+ }
- R = kmalloc(n * sizeof (*R), GFP_KERNEL);
- if (R == NULL) {
- err();
- ret = -ENOMEM;
- goto cleanup;
- }
- /* R = P */
- for (i=0;i<kdata_size;i++) {
- R[i/8][i%8] = ((uint8_t*)kdata)[i];
- }
- for (;i<n*8;i++) {
- R[i/8][i%8] = 0;
- }
- ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv);
- kfree(R);
- if (ret < 0) {
- err();
- goto cleanup;
- }
+ /* R = P */
+ for (i=0;i<kdata_size;i++) {
+ R[i/8][i%8] = ((uint8_t*)kdata)[i];
+ }
+
+ for (;i<n*8;i++) {
+ R[i/8][i%8] = 0;
+ }
+
+ ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv);
+ if (ret < 0) {
+ err();
+ goto cleanup;
}
ret = 0;
cleanup:
+ kfree(R);
cryptodev_cipher_deinit(&ctx);
return ret;
@@ -184,6 +184,7 @@ int i, ret;
struct cipher_data ctx;
uint8_t iv[4];
size_t size;
+val64_t *R = NULL, A;
if (iv_size != 4) {
memcpy(iv, RFC5649_IV, 4);
@@ -212,49 +213,42 @@ size_t size;
goto cleanup;
}
- {
- val64_t *R, A;
-
- R = kmalloc(n * sizeof (*R), GFP_KERNEL);
- if (R == NULL) {
- err();
- ret = -ENOMEM;
- goto cleanup;
- }
- ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx);
- if (ret < 0) {
- err();
- kfree(R);
- goto cleanup;
- }
+ R = kmalloc(n * sizeof (*R), GFP_KERNEL);
+ if (R == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto cleanup;
+ }
- if (memcmp(A, iv, 4)!= 0) {
- err();
- kfree(R);
- ret = -EINVAL;
- goto cleanup;
- }
+ ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx);
+ if (ret < 0) {
+ err();
+ goto cleanup;
+ }
- size = (A[4] << 24) | (A[5] << 16) | (A[6] << 8) | A[7];
- if (size > n*8 || size < (n-1)*8 || *kdata_size < size) {
- err();
- kfree(R);
- ret = -EINVAL;
- goto cleanup;
- }
+ if (memcmp(A, iv, 4)!= 0) {
+ err();
+ ret = -EINVAL;
+ goto cleanup;
+ }
- memset(kdata, 0, size);
- *kdata_size = size;
- for (i=0;i<size;i++) {
- ((uint8_t*)kdata)[i] = R[i/8][i%8];
- }
- kfree(R);
+ size = (A[4] << 24) | (A[5] << 16) | (A[6] << 8) | A[7];
+ if (size > n*8 || size < (n-1)*8 || *kdata_size < size) {
+ err();
+ ret = -EINVAL;
+ goto cleanup;
}
+ memset(kdata, 0, size);
+ *kdata_size = size;
+ for (i=0;i<size;i++) {
+ ((uint8_t*)kdata)[i] = R[i/8][i%8];
+ }
ret = 0;
cleanup:
+ kfree(R);
cryptodev_cipher_deinit(&ctx);
return ret;
@@ -293,6 +287,7 @@ size_t key_size, n;
uint8_t *raw_key;
int i, ret;
struct cipher_data ctx;
+val64_t *R = NULL;
if (tobewrapped->type != NCR_KEY_TYPE_SECRET) {
err();
@@ -322,24 +317,28 @@ struct cipher_data ctx;
n = key_size/8;
- {
- val64_t R[(NCR_CIPHER_MAX_KEY_LEN + 7) / 8];
+ R = kmalloc(sizeof(*R)*n, GFP_KERNEL);
+ if (R == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto cleanup;
+ }
- /* R = P */
- for (i=0;i<n;i++) {
- memcpy(R[i], &raw_key[i*8], 8);
- }
+ /* R = P */
+ for (i=0;i<n;i++) {
+ memcpy(R[i], &raw_key[i*8], 8);
+ }
- ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv);
- if (ret < 0) {
- err();
- goto cleanup;
- }
+ ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv);
+ if (ret < 0) {
+ err();
+ goto cleanup;
}
ret = 0;
cleanup:
+ kfree(R);
cryptodev_cipher_deinit(&ctx);
return ret;
@@ -365,6 +364,7 @@ size_t n;
val64_t A;
int i, ret;
struct cipher_data ctx;
+val64_t * R = NULL;
if (iv_size < sizeof(initA)) {
iv_size = sizeof(initA);
@@ -387,41 +387,43 @@ struct cipher_data ctx;
n = wrapped_key_size/8 - 1;
- if (sizeof(output->key.secret.data) < (n-1)*8) {
+ if (NCR_CIPHER_MAX_KEY_LEN < (n-1)*8) {
err();
ret = -EINVAL;
goto cleanup;
}
- {
- val64_t R[sizeof(output->key.secret.data)/8 + 1];
-
- ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx);
- if (ret < 0) {
- err();
- return ret;
- }
-
- if (memcmp(A, iv, 8)!= 0) {
- err();
- ret = -EINVAL;
- goto cleanup;
- }
+ R = kmalloc(sizeof(*R)*n, GFP_KERNEL);
+ if (R == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto cleanup;
+ }
- memset(&output->key, 0, sizeof(output->key));
- for (i=0;i<n;i++) {
- memcpy(&output->key.secret.data[i*8], R[i], sizeof(R[i]));
- }
- output->key.secret.size = n*8;
- output->flags = NCR_KEY_FLAG_WRAPPABLE;
- output->type = NCR_KEY_TYPE_SECRET;
+ ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx);
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+ if (memcmp(A, iv, 8)!= 0) {
+ err();
+ ret = -EINVAL;
+ goto cleanup;
}
+ memset(&output->key, 0, sizeof(output->key));
+ for (i=0;i<n;i++) {
+ memcpy(&output->key.secret.data[i*8], R[i], sizeof(R[i]));
+ }
+ output->key.secret.size = n*8;
+ output->flags = NCR_KEY_FLAG_WRAPPABLE;
+ output->type = NCR_KEY_TYPE_SECRET;
ret = 0;
cleanup:
+ kfree(R);
cryptodev_cipher_deinit(&ctx);
return ret;
diff --git a/crypto/userspace/ncr-key.c b/crypto/userspace/ncr-key.c
index e0361bc8f83..4ea933cd591 100644
--- a/crypto/userspace/ncr-key.c
+++ b/crypto/userspace/ncr-key.c
@@ -189,9 +189,9 @@ int ncr_key_init(struct list_sem_st* lst, void __user* arg)
list_add(&key->list, &lst->list);
+ desc = key->desc;
up(&lst->sem);
- desc = key->desc;
ret = copy_to_user(arg, &desc, sizeof(desc));
if (unlikely(ret)) {
down(&lst->sem);
diff --git a/crypto/userspace/ncr-limits.c b/crypto/userspace/ncr-limits.c
index bbcd1e95e6e..a1ad7e36411 100644
--- a/crypto/userspace/ncr-limits.c
+++ b/crypto/userspace/ncr-limits.c
@@ -148,7 +148,7 @@ int ret;
if (add) {
pitem = kmalloc(sizeof(*pitem), GFP_KERNEL);
- if (uitem == NULL) {
+ if (pitem == NULL) {
err();
up(&limits.processes.sem);
ret = -ENOMEM;
diff --git a/crypto/userspace/ncr-sessions.c b/crypto/userspace/ncr-sessions.c
index c5b31ac8f27..365935fe2bf 100644
--- a/crypto/userspace/ncr-sessions.c
+++ b/crypto/userspace/ncr-sessions.c
@@ -121,7 +121,7 @@ struct session_item_st* ncr_session_new(struct list_sem_st* lst)
}
init_MUTEX(&sess->mem_mutex);
- atomic_set(&sess->refcnt, 1);
+ atomic_set(&sess->refcnt, 2); /* One for lst->list, one for "sess" */
down(&lst->sem);
@@ -229,7 +229,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
ns = ncr_session_new(&lists->sessions);
if (ns == NULL) {
err();
- return -EINVAL;
+ return -ENOMEM;
}
ns->op = session->op;
@@ -263,7 +263,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
if (ns->algorithm->kstr == NULL) {
err();
- return -EINVAL;
+ ret = -EINVAL;
+ goto fail;
}
ret = cryptodev_cipher_init(&ns->cipher, ns->algorithm->kstr,
@@ -342,7 +343,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params);
if (IS_ERR(sign_hash)) {
err();
- return PTR_ERR(sign_hash);
+ ret = PTR_ERR(sign_hash);
+ goto fail;
}
if (!sign_hash->can_digest) {
@@ -390,6 +392,7 @@ fail:
if (ret < 0) {
_ncr_session_remove(&lists->sessions, ns->desc);
}
+ _ncr_sessions_item_put(ns);
return ret;
}
diff --git a/crypto/userspace/ncr.c b/crypto/userspace/ncr.c
index 87bd05204a9..7608312ed7b 100644
--- a/crypto/userspace/ncr.c
+++ b/crypto/userspace/ncr.c
@@ -52,9 +52,6 @@ void* ncr_init_lists(void)
memset(lst, 0, sizeof(*lst));
- init_MUTEX(&lst->data.sem);
- INIT_LIST_HEAD(&lst->data.list);
-
init_MUTEX(&lst->key.sem);
INIT_LIST_HEAD(&lst->key.list);
@@ -106,11 +103,14 @@ struct ncr_master_key_st st;
dprintk(0, KERN_DEBUG, "Master key was previously initialized.\n");
}
+ if (unlikely(copy_from_user(master_key.key.secret.data, st.key, st.key_size))) {
+ err();
+ return -EFAULT;
+ }
+
dprintk(0, KERN_INFO, "Initializing master key.\n");
master_key.type = NCR_KEY_TYPE_SECRET;
-
- memcpy(master_key.key.secret.data, st.key, st.key_size);
master_key.key.secret.size = st.key_size;
return 0;
diff --git a/include/linux/ncr.h b/include/linux/ncr.h
index 01fd4131187..53c77be865f 100644
--- a/include/linux/ncr.h
+++ b/include/linux/ncr.h
@@ -7,7 +7,6 @@
#endif
#define NCR_CIPHER_MAX_BLOCK_LEN 32
-#define NCR_CIPHER_MAX_KEY_LEN 512
#define NCR_HASH_MAX_OUTPUT_SIZE 64
typedef enum {
@@ -221,7 +220,7 @@ struct ncr_key_wrap_st {
/* Internal ops */
struct ncr_master_key_st {
- uint8_t key[NCR_CIPHER_MAX_KEY_LEN];
+ uint8_t __user * key;
uint16_t key_size;
};