summaryrefslogtreecommitdiffstats
path: root/ncr-key.c
diff options
context:
space:
mode:
Diffstat (limited to 'ncr-key.c')
-rw-r--r--ncr-key.c248
1 files changed, 124 insertions, 124 deletions
diff --git a/ncr-key.c b/ncr-key.c
index 35e6871..ca8ab5f 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -27,10 +27,11 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/uaccess.h>
-#include "cryptodev.h"
#include <linux/scatterlist.h>
+#include <net/netlink.h>
#include "ncr.h"
#include "ncr-int.h"
+#include "utils.h"
static int key_list_deinit_fn(int id, void *item, void *unused)
{
@@ -149,7 +150,7 @@ static void _ncr_key_remove(struct ncr_lists *lst, ncr_key_t desc)
_ncr_key_item_put(item);
}
-int ncr_key_init(struct ncr_lists *lst, void __user* arg)
+int ncr_key_init(struct ncr_lists *lst)
{
ncr_key_t desc;
struct key_item_st* key;
@@ -188,49 +189,33 @@ int ncr_key_init(struct ncr_lists *lst, void __user* arg)
desc = key->desc;
mutex_unlock(&lst->key_idr_mutex);
- ret = copy_to_user(arg, &desc, sizeof(desc));
- if (unlikely(ret)) {
- _ncr_key_remove(lst, desc);
- return -EFAULT;
- }
- return ret;
+ return desc;
err_limits:
ncr_limits_remove(current_euid(), task_pid_nr(current), LIMIT_TYPE_KEY);
return ret;
}
-int ncr_key_deinit(struct ncr_lists *lst, void __user* arg)
+int ncr_key_deinit(struct ncr_lists *lst, ncr_key_t desc)
{
- ncr_key_t desc;
-
- if (unlikely(copy_from_user(&desc, arg, sizeof(desc)))) {
- err();
- return -EFAULT;
- }
-
_ncr_key_remove(lst, desc);
-
return 0;
}
-/* "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_export(struct ncr_lists *lst, void __user* arg)
+int ncr_key_export(struct ncr_lists *lst, const struct ncr_key_export *data,
+ struct nlattr *tb[])
{
-struct ncr_key_data_st data;
struct key_item_st* item = NULL;
void* tmp = NULL;
uint32_t tmp_size;
int ret;
- if (unlikely(copy_from_user(&data, arg, sizeof(data)))) {
+ if (data->buffer_size < 0) {
err();
- return -EFAULT;
+ return -EINVAL;
}
- ret = ncr_key_item_get_read( &item, lst, data.key);
+ ret = ncr_key_item_get_read(&item, lst, data->key);
if (ret < 0) {
err();
return ret;
@@ -244,15 +229,15 @@ int ret;
switch (item->type) {
case NCR_KEY_TYPE_SECRET:
- if (item->key.secret.size > data.idata_size) {
+ if (item->key.secret.size > data->buffer_size) {
err();
- ret = -EINVAL;
+ ret = -ERANGE;
goto fail;
}
/* found */
if (item->key.secret.size > 0) {
- ret = copy_to_user(data.idata, item->key.secret.data, item->key.secret.size);
+ ret = copy_to_user(data->buffer, item->key.secret.data, item->key.secret.size);
if (unlikely(ret)) {
err();
ret = -EFAULT;
@@ -260,11 +245,11 @@ int ret;
}
}
- data.idata_size = item->key.secret.size;
+ ret = item->key.secret.size;
break;
case NCR_KEY_TYPE_PUBLIC:
case NCR_KEY_TYPE_PRIVATE:
- tmp_size = data.idata_size;
+ tmp_size = data->buffer_size;
tmp = kmalloc(tmp_size, GFP_KERNEL);
if (tmp == NULL) {
@@ -274,20 +259,19 @@ int ret;
}
ret = ncr_pk_pack(item, tmp, &tmp_size);
- data.idata_size = tmp_size;
-
if (ret < 0) {
err();
goto fail;
}
- ret = copy_to_user(data.idata, tmp, tmp_size);
+ ret = copy_to_user(data->buffer, tmp, tmp_size);
if (unlikely(ret)) {
err();
ret = -EFAULT;
goto fail;
}
+ ret = tmp_size;
break;
default:
err();
@@ -295,12 +279,6 @@ int ret;
goto fail;
}
- if (unlikely(copy_to_user(arg, &data, sizeof(data)))) {
- err();
- ret = -EFAULT;
- } else
- ret = 0;
-
fail:
kfree(tmp);
if (item)
@@ -309,31 +287,29 @@ fail:
}
-int ncr_key_assign_flags(struct key_item_st* item, unsigned int flags)
+int ncr_key_update_flags(struct key_item_st* item, const struct nlattr *nla)
{
+ uint32_t flags;
+
+ if (nla == NULL)
+ return 0;
+ flags = nla_get_u32(nla);
if (!capable(CAP_SYS_ADMIN) && (flags & NCR_KEY_FLAG_WRAPPING) != 0)
return -EPERM;
item->flags = flags;
return 0;
}
-/* "imports" a key from a data item. If the key is not exportable
- * to userspace then the key item will also not be.
- */
-int ncr_key_import(struct ncr_lists *lst, void __user* arg)
+int ncr_key_import(struct ncr_lists *lst, const struct ncr_key_import *data,
+ struct nlattr *tb[])
{
-struct ncr_key_data_st data;
+const struct nlattr *nla;
struct key_item_st* item = NULL;
int ret;
void* tmp = NULL;
size_t tmp_size;
- if (unlikely(copy_from_user(&data, arg, sizeof(data)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_write( &item, lst, data.key);
+ ret = ncr_key_item_get_write( &item, lst, data->key);
if (ret < 0) {
err();
return ret;
@@ -341,42 +317,52 @@ size_t tmp_size;
ncr_key_clear(item);
- tmp = kmalloc(data.idata_size, GFP_KERNEL);
+ tmp = kmalloc(data->data_size, GFP_KERNEL);
if (tmp == NULL) {
err();
ret = -ENOMEM;
goto fail;
}
- if (unlikely(copy_from_user(tmp, data.idata, data.idata_size))) {
+ if (unlikely(copy_from_user(tmp, data->data, data->data_size))) {
err();
ret = -EFAULT;
goto fail;
}
- tmp_size = data.idata_size;
-
- item->type = data.type;
- item->algorithm = _ncr_algo_to_properties(data.algorithm);
- if (item->algorithm == NULL) {
+ tmp_size = data->data_size;
+
+ nla = tb[NCR_ATTR_KEY_TYPE];
+ if (tb == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- ret = ncr_key_assign_flags(item, data.flags);
- if (ret < 0) {
+ item->type = nla_get_u32(nla);
+
+ item->algorithm = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
+ if (item->algorithm == NULL) {
err();
+ ret = -EINVAL;
goto fail;
}
- if (data.key_id_size > MAX_KEY_ID_SIZE) {
+ ret = ncr_key_update_flags(item, tb[NCR_ATTR_KEY_FLAGS]);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
- item->key_id_size = data.key_id_size;
- if (data.key_id_size > 0)
- memcpy(item->key_id, data.key_id, data.key_id_size);
+ nla = tb[NCR_ATTR_KEY_ID];
+ if (nla != NULL) {
+ if (nla_len(nla) > MAX_KEY_ID_SIZE) {
+ err();
+ ret = -EOVERFLOW;
+ goto fail;
+ }
+
+ item->key_id_size = nla_len(nla);
+ memcpy(item->key_id, nla_data(nla), item->key_id_size);
+ }
switch(item->type) {
case NCR_KEY_TYPE_SECRET:
@@ -432,20 +418,16 @@ void ncr_key_clear(struct key_item_st* item)
/* Generate a secret key
*/
-int ncr_key_generate(struct ncr_lists *lst, void __user* arg)
+int ncr_key_generate(struct ncr_lists *lst, const struct ncr_key_generate *gen,
+ struct nlattr *tb[])
{
-struct ncr_key_generate_st gen;
+const struct nlattr *nla;
struct key_item_st* item = NULL;
const struct algo_properties_st *algo;
int ret;
size_t size;
- if (unlikely(copy_from_user(&gen, arg, sizeof(gen)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_write( &item, lst, gen.desc);
+ ret = ncr_key_item_get_write(&item, lst, gen->key);
if (ret < 0) {
err();
return ret;
@@ -454,13 +436,13 @@ size_t size;
ncr_key_clear(item);
/* we generate only secret keys */
- ret = ncr_key_assign_flags(item, gen.params.keyflags);
+ ret = ncr_key_update_flags(item, tb[NCR_ATTR_KEY_FLAGS]);
if (ret < 0) {
err();
goto fail;
}
- algo = _ncr_algo_to_properties(gen.params.algorithm);
+ algo = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
if (algo == NULL) {
err();
ret = -EINVAL;
@@ -468,11 +450,19 @@ size_t size;
}
item->type = algo->key_type;
if (item->type == NCR_KEY_TYPE_SECRET) {
+ u32 key_bits;
+
item->algorithm = algo;
- size = gen.params.params.secret.bits/8;
- if ((gen.params.params.secret.bits % 8 != 0) ||
- (size > NCR_CIPHER_MAX_KEY_LEN)) {
+ nla = tb[NCR_ATTR_SECRET_KEY_BITS];
+ if (nla == NULL) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ key_bits = nla_get_u32(nla);
+ size = key_bits / 8;
+ if (key_bits % 8 != 0 || size > NCR_CIPHER_MAX_KEY_LEN) {
err();
ret = -EINVAL;
goto fail;
@@ -605,18 +595,15 @@ int bits;
}
}
-int ncr_key_info(struct ncr_lists *lst, void __user* arg)
+int ncr_key_get_info(struct ncr_lists *lst, struct ncr_out *out,
+ const struct ncr_key_get_info *info, struct nlattr *tb[])
{
-struct ncr_key_info_st info;
+const struct nlattr *nla;
+const u16 *attr, *attr_end;
struct key_item_st* item = NULL;
int ret;
- if (unlikely(copy_from_user(&info, arg, sizeof(info)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_read(&item, lst, info.key);
+ ret = ncr_key_item_get_read(&item, lst, info->key);
if (ret < 0) {
err();
return ret;
@@ -628,11 +615,41 @@ int ret;
goto fail;
}
- info.flags = item->flags;
- info.type = item->type;
- info.algorithm = item->algorithm->algo;
-
- ret = 0;
+ nla = tb[NCR_ATTR_WANTED_ATTRS];
+ if (nla == NULL || nla_len(nla) % sizeof(u16) != 0) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ attr = nla_data(nla);
+ attr_end = attr + nla_len(nla) / sizeof(u16);
+ while (attr < attr_end) {
+ switch (*attr) {
+ case NCR_ATTR_KEY_FLAGS:
+ ret = ncr_out_put_u32(out, *attr, item->flags);
+ break;
+ case NCR_ATTR_KEY_TYPE:
+ ret = ncr_out_put_u32(out, *attr, item->type);
+ break;
+ case NCR_ATTR_ALGORITHM:
+ ret = ncr_out_put_string(out, *attr,
+ item->algorithm->kstr);
+ break;
+ default:
+ break; /* Silently ignore */
+ }
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
+ attr++;
+ }
+
+ ret = ncr_out_finish(out);
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
fail:
_ncr_key_item_put( item);
@@ -640,25 +657,21 @@ fail:
return ret;
}
-int ncr_key_generate_pair(struct ncr_lists *lst, void __user* arg)
+int ncr_key_generate_pair(struct ncr_lists *lst,
+ const struct ncr_key_generate_pair *gen,
+ struct nlattr *tb[])
{
-struct ncr_key_generate_st gen;
struct key_item_st* private = NULL;
struct key_item_st* public = NULL;
int ret;
- if (unlikely(copy_from_user(&gen, arg, sizeof(gen)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_write( &private, lst, gen.desc);
+ ret = ncr_key_item_get_write(&private, lst, gen->private_key);
if (ret < 0) {
err();
goto fail;
}
- ret = ncr_key_item_get_write( &public, lst, gen.desc2);
+ ret = ncr_key_item_get_write(&public, lst, gen->public_key);
if (ret < 0) {
err();
goto fail;
@@ -668,7 +681,8 @@ int ret;
ncr_key_clear(private);
/* we generate only secret keys */
- private->algorithm = public->algorithm = _ncr_algo_to_properties(gen.params.algorithm);
+ private->algorithm = public->algorithm
+ = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
if (private->algorithm == NULL) {
err();
ret = -EINVAL;
@@ -676,12 +690,12 @@ int ret;
}
public->type = public->algorithm->key_type;
private->type = NCR_KEY_TYPE_PRIVATE;
- ret = ncr_key_assign_flags(private, gen.params.keyflags);
+ ret = ncr_key_update_flags(private, tb[NCR_ATTR_KEY_FLAGS]);
if (ret < 0) {
err();
goto fail;
}
- ret = ncr_key_assign_flags(public, gen.params.keyflags);
+ ret = ncr_key_update_flags(public, tb[NCR_ATTR_KEY_FLAGS]);
if (ret < 0) {
err();
goto fail;
@@ -690,7 +704,7 @@ int ret;
public->flags |= (NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE);
if (public->type == NCR_KEY_TYPE_PUBLIC) {
- ret = ncr_pk_generate(public->algorithm, &gen.params, private, public);
+ ret = ncr_pk_generate(public->algorithm, tb, private, public);
if (ret < 0) {
err();
goto fail;
@@ -714,22 +728,14 @@ fail:
return ret;
}
-/* "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 ncr_lists *lst, void __user* arg)
+int ncr_key_derive(struct ncr_lists *lst, const struct ncr_key_derive *data,
+ struct nlattr *tb[])
{
-struct ncr_key_derivation_params_st data;
int ret;
struct key_item_st* key = NULL;
struct key_item_st* newkey = NULL;
- if (unlikely(copy_from_user(&data, arg, sizeof(data)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_read( &key, lst, data.key);
+ ret = ncr_key_item_get_read(&key, lst, data->input_key);
if (ret < 0) {
err();
return ret;
@@ -743,7 +749,7 @@ struct key_item_st* newkey = NULL;
goto fail;
}
- ret = ncr_key_item_get_write( &newkey, lst, data.newkey);
+ ret = ncr_key_item_get_write(&newkey, lst, data->new_key);
if (ret < 0) {
err();
goto fail;
@@ -751,7 +757,7 @@ struct key_item_st* newkey = NULL;
ncr_key_clear(newkey);
- ret = ncr_key_assign_flags(newkey, data.keyflags);
+ ret = ncr_key_update_flags(newkey, tb[NCR_ATTR_KEY_FLAGS]);
if (ret < 0) {
err();
goto fail;
@@ -760,7 +766,7 @@ struct key_item_st* newkey = NULL;
switch (key->type) {
case NCR_KEY_TYPE_PUBLIC:
case NCR_KEY_TYPE_PRIVATE:
- ret = ncr_pk_derive(newkey, key, &data);
+ ret = ncr_pk_derive(newkey, key, tb);
if (ret < 0) {
err();
goto fail;
@@ -772,12 +778,6 @@ struct key_item_st* newkey = NULL;
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);