summaryrefslogtreecommitdiffstats
path: root/ncr-key-wrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ncr-key-wrap.c')
-rw-r--r--ncr-key-wrap.c233
1 files changed, 125 insertions, 108 deletions
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c
index 0f9f0fe..c409bb9 100644
--- a/ncr-key-wrap.c
+++ b/ncr-key-wrap.c
@@ -28,8 +28,8 @@
#include <linux/highmem.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 "cryptodev_int.h"
@@ -39,10 +39,8 @@ typedef uint8_t val64_t[8];
static const val64_t initA = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6";
static int key_to_packed_data( uint8_t** sdata, size_t * sdata_size, const struct key_item_st *key);
-static int key_from_packed_data(ncr_algorithm_t algorithm,
- ncr_key_type_t key_type, unsigned int flags,
- struct key_item_st* key, const void* data,
- size_t data_size);
+static int key_from_packed_data(struct nlattr *tb[], struct key_item_st* key,
+ const void* data, size_t data_size);
static void val64_xor( val64_t val, uint32_t x)
@@ -62,7 +60,7 @@ int i,j;
if (*output_size < (n+1)*8) {
err();
- return -EINVAL;
+ return -ERANGE;
}
memcpy(A, iv, 8);
@@ -284,12 +282,13 @@ size_t sdata_size = 0;
}
static int unwrap_aes_rfc5649(struct key_item_st* output, struct key_item_st *kek,
- void* wrapped, size_t wrapped_size,
- struct ncr_key_wrap_st* wrap_st)
+ void *wrapped, size_t wrapped_size, struct nlattr *tb[])
{
-int ret;
+const struct nlattr *nla;
+int ret, iv_size;
void * sdata;
size_t sdata_size = KEY_DATA_MAX_SIZE;
+const uint8_t *iv;
sdata = kmalloc(sdata_size, GFP_KERNEL);
if (sdata == NULL) {
@@ -297,18 +296,23 @@ size_t sdata_size = KEY_DATA_MAX_SIZE;
return -ENOMEM;
}
+ nla = tb[NCR_ATTR_IV];
+ if (nla != NULL) {
+ iv = nla_data(nla);
+ iv_size = nla_len(nla);
+ } else {
+ iv = NULL;
+ iv_size = 0;
+ }
+
ret = _unwrap_aes_rfc5649(sdata, &sdata_size, kek,
- wrapped, wrapped_size,
- wrap_st->params.params.cipher.iv, wrap_st->params.params.cipher.iv_size);
+ wrapped, wrapped_size, iv, iv_size);
if (ret < 0) {
err();
goto fail;
}
- ret = key_from_packed_data(wrap_st->wrapped_key_algorithm,
- wrap_st->wrapped_key_type,
- wrap_st->wrapped_key_flags, output, sdata,
- sdata_size);
+ ret = key_from_packed_data(tb, output, sdata, sdata_size);
if (ret < 0) {
err();
goto fail;
@@ -403,16 +407,24 @@ void print_val64(char* str, val64_t val)
#endif
static int unwrap_aes_rfc3394(struct key_item_st* output, struct key_item_st *kek,
- void* wrapped_key, size_t wrapped_key_size, struct ncr_key_wrap_st *wrap_st)
+ void* wrapped_key, size_t wrapped_key_size,
+ struct nlattr *tb[])
{
+const struct nlattr *nla;
size_t n;
val64_t A;
int i, ret;
struct cipher_data ctx;
val64_t * R = NULL;
-int iv_size = wrap_st->params.params.cipher.iv_size;
-const uint8_t * iv = wrap_st->params.params.cipher.iv;
-
+int iv_size;
+const uint8_t *iv;
+
+ nla = tb[NCR_ATTR_IV];
+ if (nla != NULL) {
+ iv = nla_data(nla);
+ iv_size = nla_len(nla);
+ } else
+ iv_size = 0;
if (iv_size < sizeof(initA)) {
iv_size = sizeof(initA);
iv = initA;
@@ -459,10 +471,13 @@ const uint8_t * iv = wrap_st->params.params.cipher.iv;
goto cleanup;
}
- ret = ncr_key_assign_flags(output, wrap_st->wrapped_key_flags);
- if (ret != 0) {
- err();
- goto cleanup;
+ nla = tb[NCR_ATTR_KEY_FLAGS];
+ if (nla != NULL) {
+ ret = ncr_key_assign_flags(output, nla_get_u32(nla));
+ if (ret != 0) {
+ err();
+ goto cleanup;
+ }
}
memset(&output->key, 0, sizeof(output->key));
@@ -512,21 +527,23 @@ int kek_level, wkey_level;
return 0;
}
-int ncr_key_wrap(struct ncr_lists *lst, void __user* arg)
+int ncr_key_wrap(struct ncr_lists *lst, const struct ncr_key_wrap *wrap,
+ struct nlattr *tb[])
{
-struct ncr_key_wrap_st wrap;
+const struct nlattr *nla;
struct key_item_st* wkey = NULL;
struct key_item_st* key = NULL;
void* data = NULL;
-size_t data_size;
+const void *iv;
+size_t data_size, iv_size;
int ret;
- if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) {
+ if (wrap->buffer_size < 0) {
err();
- return -EFAULT;
+ return -EINVAL;
}
- ret = ncr_key_item_get_read( &wkey, lst, wrap.keytowrap);
+ ret = ncr_key_item_get_read(&wkey, lst, wrap->source_key);
if (ret < 0) {
err();
return ret;
@@ -538,7 +555,7 @@ int ret;
goto fail;
}
- ret = ncr_key_item_get_read( &key, lst, wrap.key);
+ ret = ncr_key_item_get_read(&key, lst, wrap->wrapping_key);
if (ret < 0) {
err();
goto fail;
@@ -556,7 +573,7 @@ int ret;
goto fail;
}
- data_size = wrap.io_size;
+ data_size = wrap->buffer_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
err();
@@ -564,18 +581,29 @@ int ret;
goto fail;
}
- switch(wrap.algorithm) {
- case NCR_WALG_AES_RFC3394:
- ret = wrap_aes(wkey, key, data, &data_size,
- wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size);
- break;
- case NCR_WALG_AES_RFC5649:
- ret = wrap_aes_rfc5649(wkey, key, data, &data_size,
- wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size);
- break;
- default:
- err();
- ret = -EINVAL;
+ nla = tb[NCR_ATTR_IV];
+ if (nla != NULL) {
+ iv = nla_data(nla);
+ iv_size = nla_len(nla);
+ } else {
+ iv = NULL;
+ iv_size = 0;
+ }
+
+ nla = tb[NCR_ATTR_WRAPPING_ALGORITHM];
+ if (nla == NULL) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (nla_strcmp(nla, NCR_WALG_AES_RFC3394) == 0)
+ ret = wrap_aes(wkey, key, data, &data_size, iv, iv_size);
+ else if (nla_strcmp(nla, NCR_WALG_AES_RFC5649) == 0)
+ ret = wrap_aes_rfc5649(wkey, key, data, &data_size, iv,
+ iv_size);
+ else {
+ err();
+ ret = -EINVAL;
}
if (ret < 0) {
@@ -583,18 +611,13 @@ int ret;
goto fail;
}
- ret = copy_to_user(wrap.io, data, data_size);
+ ret = copy_to_user(wrap->buffer, data, data_size);
if (unlikely(ret)) {
ret = -EFAULT;
goto fail;
}
- wrap.io_size = data_size;
-
- ret = copy_to_user(arg, &wrap, sizeof(wrap));
- if (unlikely(ret)) {
- ret = -EFAULT;
- }
+ ret = data_size;
fail:
if (wkey != NULL) _ncr_key_item_put(wkey);
@@ -607,27 +630,23 @@ fail:
/* Unwraps keys. All keys unwrapped are not accessible by
* userspace.
*/
-int ncr_key_unwrap(struct ncr_lists *lst, void __user* arg)
+int ncr_key_unwrap(struct ncr_lists *lst, const struct ncr_key_unwrap *wrap,
+ struct nlattr *tb[])
{
-struct ncr_key_wrap_st wrap;
+const struct nlattr *nla;
struct key_item_st* wkey = NULL;
struct key_item_st* key = NULL;
void* data = NULL;
size_t data_size;
int ret;
- if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_write( &wkey, lst, wrap.keytowrap);
+ ret = ncr_key_item_get_write(&wkey, lst, wrap->dest_key);
if (ret < 0) {
err();
return ret;
}
- ret = ncr_key_item_get_read( &key, lst, wrap.key);
+ ret = ncr_key_item_get_read(&key, lst, wrap->wrapping_key);
if (ret < 0) {
err();
goto fail;
@@ -639,7 +658,7 @@ int ret;
goto fail;
}
- data_size = wrap.io_size;
+ data_size = wrap->data_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
err();
@@ -647,7 +666,7 @@ int ret;
goto fail;
}
- if (unlikely(copy_from_user(data, wrap.io, data_size))) {
+ if (unlikely(copy_from_user(data, wrap->data, data_size))) {
err();
ret = -EFAULT;
goto fail;
@@ -655,18 +674,19 @@ int ret;
ncr_key_clear(wkey);
- switch(wrap.algorithm) {
- case NCR_WALG_AES_RFC3394:
- ret = unwrap_aes_rfc3394(wkey, key, data, data_size,
- &wrap);
- break;
- case NCR_WALG_AES_RFC5649:
- ret = unwrap_aes_rfc5649(wkey, key,
- data, data_size, &wrap);
- break;
- default:
- err();
- ret = -EINVAL;
+ nla = tb[NCR_ATTR_WRAPPING_ALGORITHM];
+ if (nla == NULL) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (nla_strcmp(nla, NCR_WALG_AES_RFC3394) == 0)
+ ret = unwrap_aes_rfc3394(wkey, key, data, data_size, tb);
+ else if (nla_strcmp(nla, NCR_WALG_AES_RFC5649) == 0)
+ ret = unwrap_aes_rfc5649(wkey, key, data, data_size, tb);
+ else {
+ err();
+ ret = -EINVAL;
}
fail:
@@ -677,9 +697,10 @@ fail:
return ret;
}
-int ncr_key_storage_wrap(struct ncr_lists *lst, void __user* arg)
+int ncr_key_storage_wrap(struct ncr_lists *lst,
+ const struct ncr_key_storage_wrap *wrap,
+ struct nlattr *tb[])
{
-struct ncr_key_storage_wrap_st wrap;
struct key_item_st* wkey = NULL;
void* data = NULL;
size_t data_size;
@@ -692,18 +713,18 @@ int ret;
return -ENOKEY;
}
- if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) {
+ if (wrap->buffer_size < 0) {
err();
- return -EFAULT;
+ return -EINVAL;
}
- ret = ncr_key_item_get_read( &wkey, lst, wrap.keytowrap);
+ ret = ncr_key_item_get_read(&wkey, lst, wrap->key);
if (ret < 0) {
err();
return ret;
}
- data_size = wrap.io_size;
+ data_size = wrap->buffer_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
err();
@@ -723,18 +744,13 @@ int ret;
goto fail;
}
- ret = copy_to_user(wrap.io, data, data_size);
+ ret = copy_to_user(wrap->buffer, data, data_size);
if (unlikely(ret)) {
ret = -EFAULT;
goto fail;
}
- wrap.io_size = data_size;
-
- ret = copy_to_user(arg, &wrap, sizeof(wrap));
- if (unlikely(ret)) {
- ret = -EFAULT;
- }
+ ret = data_size;
fail:
if (wkey != NULL) _ncr_key_item_put(wkey);
@@ -744,12 +760,10 @@ fail:
return ret;
}
-/* Unwraps keys. All keys unwrapped are not accessible by
- * userspace.
- */
-int ncr_key_storage_unwrap(struct ncr_lists *lst, void __user* arg)
+int ncr_key_storage_unwrap(struct ncr_lists *lst,
+ const struct ncr_key_storage_unwrap *wrap,
+ struct nlattr *tb[])
{
-struct ncr_key_storage_wrap_st wrap;
struct key_item_st* wkey = NULL;
void* data = NULL;
uint8_t * sdata = NULL;
@@ -761,18 +775,13 @@ int ret;
return -ENOKEY;
}
- if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) {
- err();
- return -EFAULT;
- }
-
- ret = ncr_key_item_get_write( &wkey, lst, wrap.keytowrap);
+ ret = ncr_key_item_get_write(&wkey, lst, wrap->key);
if (ret < 0) {
err();
return ret;
}
- data_size = wrap.io_size;
+ data_size = wrap->data_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
err();
@@ -780,7 +789,7 @@ int ret;
goto fail;
}
- if (unlikely(copy_from_user(data, wrap.io, data_size))) {
+ if (unlikely(copy_from_user(data, wrap->data, data_size))) {
err();
ret = -EFAULT;
goto fail;
@@ -856,11 +865,10 @@ fail:
return ret;
}
-static int key_from_packed_data(ncr_algorithm_t algorithm,
- ncr_key_type_t key_type, unsigned int flags,
- struct key_item_st* key, const void* data,
- size_t data_size)
+static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key,
+ const void *data, size_t data_size)
{
+ const struct nlattr *nla;
int ret;
if (data_size > KEY_DATA_MAX_SIZE) {
@@ -868,17 +876,26 @@ static int key_from_packed_data(ncr_algorithm_t algorithm,
return -EINVAL;
}
- key->algorithm = _ncr_algo_to_properties(algorithm);
+ key->algorithm = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
if (key->algorithm == NULL) {
err();
return -EINVAL;
}
- key->type = key_type;
- ret = ncr_key_assign_flags(key, flags);
- if (ret != 0) {
+ nla = tb[NCR_ATTR_KEY_TYPE];
+ if (tb == NULL) {
err();
- return ret;
+ return -EINVAL;
+ }
+ key->type = nla_get_u32(nla);
+
+ nla = tb[NCR_ATTR_KEY_FLAGS];
+ if (nla != NULL) {
+ ret = ncr_key_assign_flags(key, nla_get_u32(nla));
+ if (ret != 0) {
+ err();
+ return ret;
+ }
}
if (key->type == NCR_KEY_TYPE_SECRET) {