summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-05-28 13:55:45 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-06-17 20:47:38 +0200
commitc3695ab5f06af533deaf1de75cdd4631a9d77d00 (patch)
tree89a2c59d982accae5760d86fc5ae4dfa6b55c087
parentbda013fbafabd0d0826441cb40c93a46d4dc2301 (diff)
downloadkernel-crypto-c3695ab5f06af533deaf1de75cdd4631a9d77d00.tar.gz
kernel-crypto-c3695ab5f06af533deaf1de75cdd4631a9d77d00.tar.xz
kernel-crypto-c3695ab5f06af533deaf1de75cdd4631a9d77d00.zip
Added some initial for of key. Added helper functions to enforce per user and per process limits.
-rw-r--r--Makefile2
-rw-r--r--cryptodev_main.c9
-rw-r--r--examples/new.c20
-rw-r--r--ncr-data.c75
-rw-r--r--ncr-key.c154
-rw-r--r--ncr-limits.c176
-rw-r--r--ncr.c40
-rw-r--r--ncr_int.h70
8 files changed, 477 insertions, 69 deletions
diff --git a/Makefile b/Makefile
index 909baaf38ce..94f0bf1d75a 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
VERSION = 0.1
cryptodev-objs = cryptodev_main.o cryptodev_cipher.o ncr.o \
- ncr-data.o
+ ncr-data.o ncr-key.o ncr-limits.o
obj-m += cryptodev.o
diff --git a/cryptodev_main.c b/cryptodev_main.c
index 50e5a2749fd..da7ef2b3c8c 100644
--- a/cryptodev_main.c
+++ b/cryptodev_main.c
@@ -562,13 +562,6 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
struct fcrypt * fcr;
uint32_t ses;
int ret, fd;
- unsigned int uid;
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
- uid = filp->f_uid;
-#else
- uid = filp->f_cred->fsuid;
-#endif
if (unlikely(!pcr))
BUG();
@@ -601,7 +594,7 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
return copy_to_user((void*)arg, &cop, sizeof(cop));
default:
- return ncr_ioctl(uid, pcr->ncr, cmd, arg);
+ return ncr_ioctl(pcr->ncr, filp, cmd, arg);
}
}
diff --git a/examples/new.c b/examples/new.c
index db46927c28c..8d0adb5bee1 100644
--- a/examples/new.c
+++ b/examples/new.c
@@ -130,12 +130,24 @@ test_ncr_data(int cfd)
if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) {
perror("ioctl");
fprintf(stderr, "Verified that unexportable data cannot be exported\n");
- return 0;
+ } else {
+ fprintf(stderr, "Unexportable data were exported!?\n");
+ return 1; /* ok */
}
- fprintf(stderr, "Unexportable data were exported!?\n");
-
- return 1; /* ok */
+ for (i=0;i<512;i++ ) {
+ init.max_object_size = DATA_SIZE;
+ init.flags = 0;
+ init.initial_data = data;
+ init.initial_data_size = sizeof(data);
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &init)) {
+ perror("ioctl(NCRIO_DATA_INIT)");
+ fprintf(stderr, "Reached maximum limit at: %d data\n", i);
+ }
+ }
+
+ return 0;
}
int
diff --git a/ncr-data.c b/ncr-data.c
index ea10f8b10ee..90986bca21d 100644
--- a/ncr-data.c
+++ b/ncr-data.c
@@ -34,30 +34,30 @@
static void _ncr_data_item_put( struct data_item* item);
-void ncr_data_list_deinit(struct ncr_lists *lst)
+void ncr_data_list_deinit(struct list_sem_st* lst)
{
if(lst) {
struct data_item * item, *tmp;
- down(&lst->data_sem);
+ down(&lst->sem);
- list_for_each_entry_safe(item, tmp, &lst->data_list, list) {
+ list_for_each_entry_safe(item, tmp, &lst->list, list) {
list_del(&item->list);
_ncr_data_item_put( item); /* decrement ref count */
}
- up(&lst->data_sem);
+ up(&lst->sem);
}
}
/* must be called with data semaphore down
*/
-static ncr_data_t _ncr_data_get_new_desc( struct ncr_lists* lst)
+static ncr_data_t _ncr_data_get_new_desc( struct list_sem_st* lst)
{
struct data_item* item;
int mx = 0;
- list_for_each_entry(item, &lst->data_list, list) {
+ list_for_each_entry(item, &lst->list, list) {
mx = max(mx, item->desc);
}
mx++;
@@ -66,27 +66,27 @@ int mx = 0;
}
/* returns the data item corresponding to desc */
-static struct data_item* ncr_data_item_get( struct ncr_lists* lst, ncr_data_t desc)
+static struct data_item* ncr_data_item_get( struct list_sem_st* lst, ncr_data_t desc)
{
struct data_item* item;
- down(&lst->data_sem);
- list_for_each_entry(item, &lst->data_list, list) {
+ down(&lst->sem);
+ list_for_each_entry(item, &lst->list, list) {
if (item->desc == desc) {
atomic_inc(&item->refcnt);
- up(&lst->data_sem);
+ up(&lst->sem);
return item;
}
}
- up(&lst->data_sem);
+ up(&lst->sem);
err();
return NULL;
}
-static void* data_alloc(unsigned int uid, size_t size)
+static void* data_alloc(size_t size)
{
- /* FIXME: enforce a maximum memory limit per user */
+ /* FIXME: enforce a maximum memory limit per process and per user */
if (size > 64*1024) {
err();
return NULL;
@@ -94,25 +94,27 @@ static void* data_alloc(unsigned int uid, size_t size)
return kmalloc(size, GFP_KERNEL);
}
-static void data_free(struct data_item * data)
-{
- /* FIXME: enforce a maximum memory limit per user */
- kfree(data->data);
-}
-
static void _ncr_data_item_put( struct data_item* item)
{
if (atomic_dec_and_test(&item->refcnt)) {
- data_free(item);
+ ncr_limits_remove(item->filp, LIMIT_TYPE_DATA);
+ kfree(item->data);
kfree(item);
}
}
-int ncr_data_new(unsigned int uid, struct ncr_lists* lst, void __user* arg)
+int ncr_data_init(struct file *filp, struct list_sem_st* lst, void __user* arg)
{
struct ncr_data_init_st init;
struct data_item* data;
-
+ int ret;
+
+ ret = ncr_limits_add_and_check(filp, LIMIT_TYPE_DATA);
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+
copy_from_user( &init, arg, sizeof(init));
data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -124,9 +126,10 @@ int ncr_data_new(unsigned int uid, struct ncr_lists* lst, void __user* arg)
memset(data, 0, sizeof(*data));
data->flags = init.flags;
+ data->filp = filp;
atomic_set(&data->refcnt, 1);
- data->data = data_alloc(uid, init.max_object_size);
+ data->data = data_alloc(init.max_object_size);
if (data->data == NULL) {
kfree(data);
err();
@@ -134,19 +137,19 @@ int ncr_data_new(unsigned int uid, struct ncr_lists* lst, void __user* arg)
}
data->max_data_size = init.max_object_size;
- down(&lst->data_sem);
-
- data->desc = _ncr_data_get_new_desc(lst);
- data->uid = uid;
-
if (init.initial_data != NULL) {
copy_from_user(data->data, init.initial_data, init.initial_data_size);
data->data_size = init.initial_data_size;
}
- list_add(&data->list, &lst->data_list);
+ down(&lst->sem);
+
+ data->desc = _ncr_data_get_new_desc(lst);
+ data->filp = filp;
+
+ list_add(&data->list, &lst->list);
- up(&lst->data_sem);
+ up(&lst->sem);
init.desc = data->desc;
copy_to_user(arg, &init, sizeof(init));
@@ -155,16 +158,16 @@ int ncr_data_new(unsigned int uid, struct ncr_lists* lst, void __user* arg)
}
-int ncr_data_deinit(struct ncr_lists* lst, void __user* arg)
+int ncr_data_deinit(struct list_sem_st* lst, void __user* arg)
{
ncr_data_t desc;
struct data_item * item, *tmp;
copy_from_user( &desc, arg, sizeof(desc));
- down(&lst->data_sem);
+ down(&lst->sem);
- list_for_each_entry_safe(item, tmp, &lst->data_list, list) {
+ list_for_each_entry_safe(item, tmp, &lst->list, list) {
if(item->desc == desc) {
list_del(&item->list);
_ncr_data_item_put( item); /* decrement ref count */
@@ -172,12 +175,12 @@ int ncr_data_deinit(struct ncr_lists* lst, void __user* arg)
}
}
- up(&lst->data_sem);
+ up(&lst->sem);
return 0;
}
-int ncr_data_get(struct ncr_lists* lst, void __user* arg)
+int ncr_data_get(struct list_sem_st* lst, void __user* arg)
{
struct ncr_data_st get;
struct data_item * data;
@@ -211,7 +214,7 @@ int ncr_data_get(struct ncr_lists* lst, void __user* arg)
return 0;
}
-int ncr_data_set(struct ncr_lists* lst, void __user* arg)
+int ncr_data_set(struct list_sem_st* lst, void __user* arg)
{
struct ncr_data_st get;
struct data_item * data;
diff --git a/ncr-key.c b/ncr-key.c
new file mode 100644
index 00000000000..65a5525894b
--- /dev/null
+++ b/ncr-key.c
@@ -0,0 +1,154 @@
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 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,
+ * 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/>.
+ */
+
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/random.h>
+#include "cryptodev.h"
+#include <asm/uaccess.h>
+#include <asm/ioctl.h>
+#include <linux/scatterlist.h>
+#include "ncr.h"
+#include "ncr_int.h"
+
+#define err() printk(KERN_DEBUG"ncr: %s: %d\n", __func__, __LINE__)
+
+static void _ncr_key_item_put( struct key_item* item);
+
+void ncr_key_list_deinit(struct list_sem_st* lst)
+{
+ if(lst) {
+ struct key_item * item, *tmp;
+
+ down(&lst->sem);
+
+ list_for_each_entry_safe(item, tmp, &lst->list, list) {
+ list_del(&item->list);
+ _ncr_key_item_put( item); /* decrement ref count */
+ }
+ up(&lst->sem);
+ }
+}
+
+/* must be called with data semaphore down
+ */
+static ncr_key_t _ncr_key_get_new_desc( struct list_sem_st* lst)
+{
+struct key_item* item;
+int mx = 0;
+
+ list_for_each_entry(item, &lst->list, list) {
+ mx = max(mx, item->desc);
+ }
+ mx++;
+
+ return mx;
+}
+
+/* returns the data item corresponding to desc */
+static struct key_item* ncr_key_item_get( struct list_sem_st* lst, ncr_key_t desc)
+{
+struct key_item* item;
+
+ down(&lst->sem);
+ list_for_each_entry(item, &lst->list, list) {
+ if (item->desc == desc) {
+ atomic_inc(&item->refcnt);
+ up(&lst->sem);
+ return item;
+ }
+ }
+ up(&lst->sem);
+
+ err();
+ return NULL;
+}
+
+static void _ncr_key_item_put( struct key_item* item)
+{
+ if (atomic_dec_and_test(&item->refcnt)) {
+ ncr_limits_remove(item->filp, LIMIT_TYPE_KEY);
+ kfree(item);
+ }
+}
+
+int ncr_key_init(struct file *filp, struct list_sem_st* lst, void __user* arg)
+{
+ ncr_key_t desc;
+ struct key_item* key;
+ int ret;
+
+ ret = ncr_limits_add_and_check(filp, LIMIT_TYPE_KEY);
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+
+ copy_from_user( &desc, arg, sizeof(desc));
+
+ key = kmalloc(sizeof(*key), GFP_KERNEL);
+ if (key == NULL) {
+ err();
+ return -ENOMEM;
+ }
+
+ memset(key, 0, sizeof(*key));
+
+ atomic_set(&key->refcnt, 1);
+
+ down(&lst->sem);
+
+ key->desc = _ncr_key_get_new_desc(lst);
+ key->filp = filp;
+
+ list_add(&key->list, &lst->list);
+
+ up(&lst->sem);
+
+ desc = key->desc;
+ copy_to_user(arg, &desc, sizeof(desc));
+
+ return 0;
+}
+
+
+int ncr_key_deinit(struct list_sem_st* lst, void __user* arg)
+{
+ ncr_key_t desc;
+ struct key_item * item, *tmp;
+
+ copy_from_user( &desc, arg, sizeof(desc));
+
+ down(&lst->sem);
+
+ list_for_each_entry_safe(item, tmp, &lst->list, list) {
+ if(item->desc == desc) {
+ list_del(&item->list);
+ _ncr_key_item_put( item); /* decrement ref count */
+ break;
+ }
+ }
+
+ up(&lst->sem);
+
+ return 0;
+}
diff --git a/ncr-limits.c b/ncr-limits.c
new file mode 100644
index 00000000000..c65b7b333d7
--- /dev/null
+++ b/ncr-limits.c
@@ -0,0 +1,176 @@
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 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,
+ * 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/>.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/random.h>
+#include "cryptodev.h"
+#include <asm/atomic.h>
+#include <linux/version.h>
+#include "ncr.h"
+#include "ncr_int.h"
+
+/* arbitrary now */
+unsigned int max_per_user[] = {
+ [LIMIT_TYPE_KEY] = 128,
+ [LIMIT_TYPE_DATA] = 128,
+};
+
+unsigned int max_per_process[] = {
+ [LIMIT_TYPE_KEY] = 64,
+ [LIMIT_TYPE_DATA] = 64,
+};
+
+struct limit_user_item_st {
+ struct list_head list;
+ uid_t uid;
+ limits_type_t type;
+ atomic_t cnt;
+};
+
+struct limit_process_item_st {
+ struct list_head list;
+ struct pid * pid;
+ limits_type_t type;
+ atomic_t cnt;
+};
+
+struct limit_st {
+ struct list_sem_st users;
+ struct list_sem_st processes;
+} limits;
+
+void ncr_limits_init(void)
+{
+ init_MUTEX(&limits.users.sem);
+ INIT_LIST_HEAD(&limits.users.list);
+
+ init_MUTEX(&limits.processes.sem);
+ INIT_LIST_HEAD(&limits.processes.list);
+}
+
+int ncr_limits_add_and_check(struct file *filp, limits_type_t type)
+{
+struct limit_process_item_st* pitem;
+struct limit_user_item_st* uitem;
+uid_t uid;
+int add = 1;
+
+/* FIXME: is this uid ok?
+ */
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
+ uid = filp->f_uid;
+#else
+ uid = filp->f_cred->fsuid;
+#endif
+
+ down(&limits.users.sem);
+ list_for_each_entry(uitem, &limits.users.list, list) {
+ if (uitem->uid == uid && uitem->type == type) {
+ add = 0;
+ if (atomic_add_unless(&uitem->cnt, 1, max_per_user[type])==0) {
+ err();
+ up(&limits.users.sem);
+ return -EPERM;
+ }
+ }
+ }
+
+ if (add) {
+ uitem = kmalloc(GFP_KERNEL, sizeof(*uitem));
+ if (uitem == NULL) {
+ err();
+ return -ENOMEM;
+ }
+ uitem->uid = uid;
+ uitem->type = type;
+ atomic_set(&uitem->cnt, 1);
+
+ list_add(&uitem->list, &limits.users.list);
+ }
+ up(&limits.users.sem);
+
+ add = 1;
+ /* check process limits */
+ down(&limits.processes.sem);
+ list_for_each_entry(pitem, &limits.processes.list, list) {
+ if (pitem->pid == filp->f_owner.pid && pitem->type == type) {
+ add = 0;
+ if (atomic_add_unless(&pitem->cnt, 1, max_per_process[type])==0) {
+ err();
+ up(&limits.processes.sem);
+ return -EPERM;
+ }
+ }
+ }
+
+
+ if (add) {
+ pitem = kmalloc(GFP_KERNEL, sizeof(*pitem));
+ if (uitem == NULL) {
+ err();
+ return -ENOMEM;
+ }
+ pitem->pid = filp->f_owner.pid;
+ pitem->type = type;
+ atomic_set(&pitem->cnt, 1);
+
+ list_add(&pitem->list, &limits.processes.list);
+ }
+ up(&limits.processes.sem);
+
+ return 0;
+}
+
+void ncr_limits_remove(struct file *filp, limits_type_t type)
+{
+struct limit_process_item_st* pitem;
+struct limit_user_item_st* uitem;
+uid_t uid;
+
+/* FIXME: is this uid ok?
+ */
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
+ uid = filp->f_uid;
+#else
+ uid = filp->f_cred->fsuid;
+#endif
+
+ down(&limits.users.sem);
+ list_for_each_entry(uitem, &limits.users.list, list) {
+ if (uitem->uid == uid && uitem->type == type) {
+ atomic_dec(&uitem->cnt);
+ }
+ }
+ up(&limits.users.sem);
+
+ /* check process limits */
+ down(&limits.processes.sem);
+ list_for_each_entry(pitem, &limits.processes.list, list) {
+ if (pitem->pid == filp->f_owner.pid && pitem->type == type) {
+ atomic_dec(&pitem->cnt);
+ }
+ }
+ up(&limits.processes.sem);
+
+ return;
+}
diff --git a/ncr.c b/ncr.c
index b91e7dc41ec..9e40ac05330 100644
--- a/ncr.c
+++ b/ncr.c
@@ -44,8 +44,11 @@ void* ncr_init_lists(void)
memset(lst, 0, sizeof(*lst));
- init_MUTEX(&lst->data_sem);
- INIT_LIST_HEAD(&lst->data_list);
+ init_MUTEX(&lst->data.sem);
+ INIT_LIST_HEAD(&lst->data.list);
+
+ init_MUTEX(&lst->key.sem);
+ INIT_LIST_HEAD(&lst->key.list);
return lst;
}
@@ -53,15 +56,16 @@ void* ncr_init_lists(void)
void ncr_deinit_lists(struct ncr_lists *lst)
{
if(lst) {
- ncr_data_list_deinit(lst);
+ ncr_data_list_deinit(&lst->data);
+ ncr_key_list_deinit(&lst->key);
kfree(lst);
}
}
int
-ncr_ioctl(unsigned int uid, struct ncr_lists* lst,
- unsigned int cmd, unsigned long __user arg)
+ncr_ioctl(struct ncr_lists* lst, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
if (unlikely(!lst))
@@ -69,13 +73,31 @@ ncr_ioctl(unsigned int uid, struct ncr_lists* lst,
switch (cmd) {
case NCRIO_DATA_INIT:
- return ncr_data_new(uid, lst, (void*)arg);
+ return ncr_data_init(filp, &lst->data, (void*)arg);
case NCRIO_DATA_GET:
- return ncr_data_get(lst, (void*)arg);
+ return ncr_data_get(&lst->data, (void*)arg);
case NCRIO_DATA_SET:
- return ncr_data_set(lst, (void*)arg);
+ return ncr_data_set(&lst->data, (void*)arg);
case NCRIO_DATA_DEINIT:
- return ncr_data_deinit(lst, (void*)arg);
+ return ncr_data_deinit(&lst->data, (void*)arg);
+ case NCRIO_KEY_INIT:
+ return ncr_key_init(filp, &lst->key, (void*)arg);
+ case NCRIO_KEY_DEINIT:
+ return ncr_key_deinit(&lst->key, (void*)arg);
+#if 0
+ case NCRIO_KEY_GENERATE:
+ return ncr_key_generate(&lst->key, (void*)arg);
+ case NCRIO_KEY_GENERATE_PAIR:
+ return ncr_key_generate_pair(&lst->key, (void*)arg);
+ case NCRIO_KEY_DERIVE:
+ return ncr_key_derive(&lst->key, (void*)arg);
+ case NCRIO_KEY_EXPORT:
+ return ncr_key_export(&lst->key, (void*)arg);
+ case NCRIO_KEY_IMPORT:
+ return ncr_key_import(&lst->key, (void*)arg);
+ case NCRIO_KEY_GET_PUBLIC:
+ return ncr_key_get_public(&lst->key, (void*)arg);
+#endif
default:
return -EINVAL;
}
diff --git a/ncr_int.h b/ncr_int.h
index 7d78ac8a1e9..82141ac6112 100644
--- a/ncr_int.h
+++ b/ncr_int.h
@@ -4,6 +4,8 @@
#include "ncr.h"
#include <asm/atomic.h>
+#define err() printk(KERN_DEBUG"ncr: %s: %d\n", __func__, __LINE__)
+
struct data_item {
struct list_head list;
/* This object is not protected from concurrent access.
@@ -15,33 +17,79 @@ struct data_item {
size_t max_data_size;
unsigned int flags;
atomic_t refcnt;
- unsigned int uid;
+ struct file *filp; /* who has it */
ncr_data_t desc;
};
+#define MAX_KEY_SIZE 32 /* in bytes */
+
+struct key_item {
+ struct list_head list;
+ /* This object is also not protected from concurrent access.
+ */
+ ncr_key_type_t type;
+ unsigned int flags;
+ ncr_algorithm_t algorithm; /* valid for public/private keys */
+ uint8_t key_id[MAX_KEY_ID_SIZE];
+ size_t key_id_size;
+
+ union {
+ struct {
+ uint8_t data[MAX_KEY_SIZE];
+ size_t size;
+ } secret;
+ } key;
+
+ atomic_t refcnt;
+
+ struct file *filp; /* who has it */
+ ncr_key_t desc;
+};
+
+struct list_sem_st {
+ struct list_head list;
+ struct semaphore sem;
+};
+
/* all the data associated with the open descriptor
* are here.
*/
struct ncr_lists {
- struct list_head data_list;
- struct semaphore data_sem;
+ struct list_sem_st data;
+ struct list_sem_st key;
/* sessions */
- /* keys */
};
void* ncr_init_lists(void);
void ncr_deinit_lists(struct ncr_lists *lst);
-int
-ncr_ioctl(unsigned int uid, struct ncr_lists* lst,
+int ncr_ioctl(struct ncr_lists*, struct file *filp,
unsigned int cmd, unsigned long arg);
+
+int ncr_data_set(struct list_sem_st*, void __user* arg);
+int ncr_data_get(struct list_sem_st*, void __user* arg);
+int ncr_data_deinit(struct list_sem_st*, void __user* arg);
+int ncr_data_init(struct file* filp, struct list_sem_st*, void __user* arg);
+void ncr_data_list_deinit(struct list_sem_st*);
+
+int ncr_key_init(struct file* filp, struct list_sem_st*, void __user* arg);
+int ncr_key_generate(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_export(struct list_sem_st*, void __user* arg);
+int ncr_key_import(struct list_sem_st*, void __user* arg);
+int ncr_key_get_public(struct list_sem_st* lst, void __user* arg);
+int ncr_key_deinit(struct list_sem_st*, void __user* arg);
+void ncr_key_list_deinit(struct list_sem_st* lst);
+
+typedef enum {
+ LIMIT_TYPE_KEY,
+ LIMIT_TYPE_DATA
+} limits_type_t;
-int ncr_data_set(struct ncr_lists* lst, void __user* arg);
-int ncr_data_get(struct ncr_lists* lst, void __user* arg);
-int ncr_data_deinit(struct ncr_lists* lst, void __user* arg);
-int ncr_data_new(unsigned int uid, struct ncr_lists* lst, void __user* arg);
-void ncr_data_list_deinit(struct ncr_lists *lst);
+void ncr_limits_remove(struct file *filp, limits_type_t type);
+int ncr_limits_add_and_check(struct file *filp, limits_type_t type);
#endif