summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-08-16 16:18:07 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-08-24 23:44:25 +0200
commit96ec7e16575010e4d48c47ade593ca91690c105b (patch)
tree61366a140136256e28165bd143ef1cc1811a7246
parent3ab6fc7d0d19f62b48ecef310249014192289613 (diff)
downloadcryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.tar.gz
cryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.tar.xz
cryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.zip
Convert *_KEY_UNWRAP
-rw-r--r--examples/ncr.c26
-rw-r--r--examples/pk.c30
-rw-r--r--ncr-int.h3
-rw-r--r--ncr-key-wrap.c89
-rw-r--r--ncr.c23
-rw-r--r--ncr.h26
6 files changed, 128 insertions, 69 deletions
diff --git a/examples/ncr.c b/examples/ncr.c
index 7324c16..d4af05d 100644
--- a/examples/ncr.c
+++ b/examples/ncr.c
@@ -355,7 +355,13 @@ test_ncr_wrap_key(int cfd)
struct nlattr algo_head ALIGN_NL;
uint32_t algo ALIGN_NL;
} kwrap;
- struct ncr_key_wrap_st kunwrap;
+ struct __attribute__((packed)) {
+ struct ncr_key_unwrap f;
+ struct nlattr wrap_algo_head ALIGN_NL;
+ uint32_t wrap_algo ALIGN_NL;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ } kunwrap;
uint8_t data[WRAPPED_KEY_DATA_SIZE];
int data_size;
@@ -483,12 +489,18 @@ test_ncr_wrap_key(int cfd)
return 1;
}
- memset(&kunwrap, 0, sizeof(kunwrap));
- kunwrap.algorithm = NCR_WALG_AES_RFC3394;
- kunwrap.keytowrap = key2;
- kunwrap.key = key;
- kunwrap.io = data;
- kunwrap.io_size = data_size;
+ memset(&kunwrap.f, 0, sizeof(kunwrap.f));
+ kunwrap.f.input_size = sizeof(kunwrap);
+ kunwrap.f.wrapping_key = key;
+ kunwrap.f.dest_key = key2;
+ kunwrap.f.data = data;
+ kunwrap.f.data_size = data_size;
+ kunwrap.wrap_algo_head.nla_len = NLA_HDRLEN + sizeof(kunwrap.wrap_algo);
+ kunwrap.wrap_algo_head.nla_type = NCR_ATTR_WRAPPING_ALGORITHM;
+ kunwrap.wrap_algo = NCR_WALG_AES_RFC3394;
+ kunwrap.algo_head.nla_len = NLA_HDRLEN + sizeof(kunwrap.algo);
+ kunwrap.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ kunwrap.algo = NCR_ALG_AES_CBC;
if (ioctl(cfd, NCRIO_KEY_UNWRAP, &kunwrap)) {
perror("ioctl(NCRIO_KEY_UNWRAP)");
diff --git a/examples/pk.c b/examples/pk.c
index f2a8a68..ac95820 100644
--- a/examples/pk.c
+++ b/examples/pk.c
@@ -613,7 +613,13 @@ test_ncr_wrap_key3(int cfd)
struct nlattr algo_head ALIGN_NL;
uint32_t algo ALIGN_NL;
} kwrap;
- struct ncr_key_wrap_st kunwrap;
+ struct __attribute__((packed)) {
+ struct ncr_key_unwrap f;
+ struct nlattr wrap_algo_head ALIGN_NL;
+ uint32_t wrap_algo ALIGN_NL;
+ struct nlattr algo_head ALIGN_NL;
+ uint32_t algo ALIGN_NL;
+ } kunwrap;
struct __attribute__((packed)) {
struct ncr_key_generate_pair f;
struct nlattr algo_head ALIGN_NL;
@@ -753,13 +759,21 @@ test_ncr_wrap_key3(int cfd)
data_size = ret;
/* try unwrapping */
- memset(&kunwrap, 0, sizeof(kunwrap));
- kunwrap.algorithm = NCR_WALG_AES_RFC5649;
- kunwrap.wrapped_key_algorithm = NCR_ALG_RSA;
- kunwrap.keytowrap = privkey;
- kunwrap.key = key;
- kunwrap.io = data;
- kunwrap.io_size = data_size;
+ memset(&kunwrap.f, 0, sizeof(kunwrap.f));
+ kunwrap.f.input_size = sizeof(kunwrap);
+ kunwrap.f.wrapping_key = key;
+ kunwrap.f.dest_key = privkey;
+ kunwrap.f.data = data;
+ kunwrap.f.data_size = data_size;
+ kunwrap.wrap_algo_head.nla_len
+ = NLA_HDRLEN + sizeof(kunwrap.wrap_algo);
+ kunwrap.wrap_algo_head.nla_type
+ = NCR_ATTR_WRAPPING_ALGORITHM;
+ kunwrap.wrap_algo = NCR_WALG_AES_RFC5649;
+ kunwrap.algo_head.nla_len
+ = NLA_HDRLEN + sizeof(kunwrap.algo);
+ kunwrap.algo_head.nla_type = NCR_ATTR_ALGORITHM;
+ kunwrap.algo = NCR_ALG_RSA;
ret = ioctl(cfd, NCRIO_KEY_UNWRAP, &kunwrap);
if (ret) {
diff --git a/ncr-int.h b/ncr-int.h
index f49f2ef..6f4fb94 100644
--- a/ncr-int.h
+++ b/ncr-int.h
@@ -155,7 +155,8 @@ void ncr_limits_deinit(void);
int ncr_key_wrap(struct ncr_lists *lst, const struct ncr_key_wrap *wrap,
struct nlattr *tb[]);
-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[]);
int ncr_key_storage_wrap(struct ncr_lists *lst, void __user* arg);
int ncr_key_storage_unwrap(struct ncr_lists *lst, void __user* arg);
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c
index 1cac811..725b594 100644
--- a/ncr-key-wrap.c
+++ b/ncr-key-wrap.c
@@ -39,8 +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, 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)
@@ -282,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) {
@@ -295,16 +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_flags,
- output, sdata, sdata_size);
+ ret = key_from_packed_data(tb, output, sdata, sdata_size);
if (ret < 0) {
err();
goto fail;
@@ -399,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;
@@ -460,7 +476,9 @@ const uint8_t * iv = wrap_st->params.params.cipher.iv;
memcpy(&output->key.secret.data[i*8], R[i], sizeof(R[i]));
}
output->key.secret.size = n*8;
- ncr_key_assign_flags(output, wrap_st->wrapped_key_flags);
+ nla = tb[NCR_ATTR_KEY_FLAGS];
+ if (nla != NULL)
+ ncr_key_assign_flags(output, nla_get_u32(nla));
output->type = NCR_KEY_TYPE_SECRET;
ret = 0;
@@ -610,27 +628,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;
@@ -642,7 +656,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();
@@ -650,7 +664,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;
@@ -658,14 +672,20 @@ int ret;
ncr_key_clear(wkey);
- switch(wrap.algorithm) {
+ nla = tb[NCR_ATTR_WRAPPING_ALGORITHM];
+ if (nla == NULL) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ switch (nla_get_u32(nla)) {
case NCR_WALG_AES_RFC3394:
- ret = unwrap_aes_rfc3394(wkey, key, data, data_size,
- &wrap);
+ ret = unwrap_aes_rfc3394(wkey, key, data, data_size,
+ tb);
break;
case NCR_WALG_AES_RFC5649:
- ret = unwrap_aes_rfc5649(wkey, key,
- data, data_size, &wrap);
+ ret = unwrap_aes_rfc5649(wkey, key, data, data_size,
+ tb);
break;
default:
err();
@@ -859,9 +879,10 @@ fail:
return ret;
}
-static int key_from_packed_data(ncr_algorithm_t algorithm, 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) {
@@ -869,14 +890,16 @@ static int key_from_packed_data(ncr_algorithm_t algorithm, unsigned int flags,
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->algorithm->key_type;
- ncr_key_assign_flags(key, flags);
+ nla = tb[NCR_ATTR_KEY_FLAGS];
+ if (nla != NULL)
+ ncr_key_assign_flags(key, nla_get_u32(nla));
if (key->type == NCR_KEY_TYPE_SECRET) {
if (data_size > NCR_CIPHER_MAX_KEY_LEN) {
diff --git a/ncr.c b/ncr.c
index 202ddc9..5913f9d 100644
--- a/ncr.c
+++ b/ncr.c
@@ -179,8 +179,7 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
return ncr_key_deinit(lst, key);
}
CASE_NO_OUTPUT(NCRIO_KEY_WRAP, ncr_key_wrap, ncr_key_wrap);
- case NCRIO_KEY_UNWRAP:
- return ncr_key_unwrap(lst, arg);
+ CASE_NO_OUTPUT(NCRIO_KEY_UNWRAP, ncr_key_unwrap, ncr_key_unwrap);
case NCRIO_KEY_STORAGE_WRAP:
return ncr_key_storage_wrap(lst, arg);
case NCRIO_KEY_STORAGE_UNWRAP:
@@ -258,6 +257,25 @@ static void convert_ncr_key_wrap(struct ncr_key_wrap *new,
new->buffer_size = old->buffer_size;
}
+struct compat_ncr_key_unwrap {
+ __u32 input_size, output_size;
+ ncr_key_t wrapping_key;
+ ncr_key_t dest_key;
+ compat_uptr_t data;
+ __u32 data_size;
+ __NL_ATTRIBUTES;
+};
+#define COMPAT_NCRIO_KEY_UNWRAP _IOWR('c', 251, struct compat_ncr_key_unwrap)
+
+static void convert_ncr_key_unwrap(struct ncr_key_unwrap *new,
+ const struct compat_ncr_key_unwrap *old)
+{
+ new->wrapping_key = old->wrapping_key;
+ new->dest_key = old->dest_key;
+ new->data = compat_ptr(old->data);
+ new->data_size = old->data_size;
+}
+
long
ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
{
@@ -296,6 +314,7 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_)
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_EXPORT, ncr_key_export, ncr_key_export);
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_IMPORT, ncr_key_import, ncr_key_import);
CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_WRAP, ncr_key_wrap, ncr_key_wrap);
+ CASE_NO_OUTPUT(COMPAT_NCRIO_KEY_UNWRAP, ncr_key_unwrap, ncr_key_unwrap);
default:
return -EINVAL;
#undef CASE_NO_OUTPUT
diff --git a/ncr.h b/ncr.h
index 508665c..2b45fe8 100644
--- a/ncr.h
+++ b/ncr.h
@@ -229,27 +229,17 @@ struct ncr_key_wrap {
__NL_ATTRIBUTES;
};
-struct ncr_key_wrap_st {
- ncr_wrap_algorithm_t algorithm;
-
- /* when unwrapping the algorithm of the wrapped key.
- * For symmetric ciphers AES would do.
- */
- ncr_algorithm_t wrapped_key_algorithm;
- unsigned int wrapped_key_flags; /* flags for the newly unwrapped key */
-
- ncr_key_t keytowrap;
-
- ncr_key_t key;
- struct ncr_key_params_st params;
-
- void __user * io; /* encrypted keytowrap */
- /* this will be updated by the actual size on wrap */
- __kernel_size_t io_size;
+struct ncr_key_unwrap {
+ __u32 input_size, output_size;
+ ncr_key_t wrapping_key;
+ ncr_key_t dest_key;
+ const void __user *data;
+ __u32 data_size;
+ __NL_ATTRIBUTES;
};
#define NCRIO_KEY_WRAP _IOWR('c', 250, struct ncr_key_wrap)
-#define NCRIO_KEY_UNWRAP _IOR ('c', 251, struct ncr_key_wrap_st)
+#define NCRIO_KEY_UNWRAP _IOWR('c', 251, struct ncr_key_unwrap)
/* Internal ops */
struct ncr_master_key_st {