diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-08-16 16:18:07 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-08-24 23:44:25 +0200 |
commit | 96ec7e16575010e4d48c47ade593ca91690c105b (patch) | |
tree | 61366a140136256e28165bd143ef1cc1811a7246 | |
parent | 3ab6fc7d0d19f62b48ecef310249014192289613 (diff) | |
download | cryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.tar.gz cryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.tar.xz cryptodev-linux-96ec7e16575010e4d48c47ade593ca91690c105b.zip |
Convert *_KEY_UNWRAP
-rw-r--r-- | examples/ncr.c | 26 | ||||
-rw-r--r-- | examples/pk.c | 30 | ||||
-rw-r--r-- | ncr-int.h | 3 | ||||
-rw-r--r-- | ncr-key-wrap.c | 89 | ||||
-rw-r--r-- | ncr.c | 23 | ||||
-rw-r--r-- | ncr.h | 26 |
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) { @@ -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) { @@ -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 @@ -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 { |