diff options
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c | 24 | ||||
-rw-r--r-- | crypto/userspace/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c | 24 | ||||
-rw-r--r-- | crypto/userspace/ncr-int.h | 3 | ||||
-rw-r--r-- | crypto/userspace/ncr-key-wrap.c | 180 | ||||
-rw-r--r-- | crypto/userspace/ncr-key.c | 2 | ||||
-rw-r--r-- | crypto/userspace/ncr-limits.c | 2 | ||||
-rw-r--r-- | crypto/userspace/ncr-sessions.c | 11 | ||||
-rw-r--r-- | crypto/userspace/ncr.c | 10 | ||||
-rw-r--r-- | include/linux/ncr.h | 3 |
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; }; |