diff options
-rw-r--r-- | examples/ncr.c | 85 | ||||
-rw-r--r-- | ncr-int.h | 4 | ||||
-rw-r--r-- | ncr-key.c | 54 | ||||
-rw-r--r-- | ncr.c | 21 | ||||
-rw-r--r-- | ncr.h | 17 | ||||
-rw-r--r-- | utils.c | 2 |
6 files changed, 157 insertions, 26 deletions
diff --git a/examples/ncr.c b/examples/ncr.c index 568b63c..b999003 100644 --- a/examples/ncr.c +++ b/examples/ncr.c @@ -46,10 +46,22 @@ test_ncr_key(int cfd) struct nlattr bits_head ALIGN_NL; uint32_t bits ALIGN_NL; } kgen; + struct __attribute__((packed)) { + struct ncr_key_get_info f; + /* This union is only here to stop gcc from complaining about + aliasing. */ + union { + unsigned char __reserve[DATA_SIZE]; + struct nlattr first_header; + } u ALIGN_NL; + } kinfo; + struct nlattr *nla; ncr_key_t key; struct ncr_key_data_st keydata; uint8_t data[KEY_DATA_SIZE]; uint8_t data_bak[KEY_DATA_SIZE]; + uint16_t *attr_p; + int got_algo, got_flags, got_type; fprintf(stdout, "Tests on Keys:\n"); @@ -174,6 +186,79 @@ test_ncr_key(int cfd) return 1; } + memset(&kinfo.f, 0, sizeof(kinfo.f)); + kinfo.f.output_size = sizeof(kinfo); + kinfo.f.key = key; + nla = &kinfo.u.first_header; + nla->nla_type = NCR_ATTR_WANTED_ATTRS; + attr_p = (uint16_t *)((char *)nla + NLA_HDRLEN); + *attr_p++ = NCR_ATTR_ALGORITHM; + *attr_p++ = NCR_ATTR_KEY_FLAGS; + *attr_p++ = NCR_ATTR_KEY_TYPE; + nla->nla_len = (char *)attr_p - (char *)nla; + kinfo.f.input_size = (char *)attr_p - (char *)&kinfo; + + if (ioctl(cfd, NCRIO_KEY_GET_INFO, &kinfo)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_GET_INFO)"); + return 1; + } + + got_algo = got_flags = got_type = 0; + if (kinfo.f.output_size < + (char *)&kinfo.u.first_header - (char *)&kinfo) { + fprintf(stderr, "No nlattr returned\n"); + return 1; + } + nla = &kinfo.u.first_header; + for (;;) { + void *data; + + if (nla->nla_len < NLA_HDRLEN + sizeof(uint32_t)) { + fprintf(stderr, "Attribute too small\n"); + return 1; + } + if (nla->nla_len > + kinfo.f.output_size - ((char *)nla - (char *)&kinfo)) { + fprintf(stderr, "Attributes overflow\n"); + return 1; + } + data = (char *)nla + NLA_HDRLEN; + switch (nla->nla_type) { + case NCR_ATTR_ALGORITHM: + if (*(uint32_t *)data != NCR_ALG_AES_CBC) { + fprintf(stderr, "Unexpected algorithm\n"); + return 1; + } + got_algo++; + break; + case NCR_ATTR_KEY_FLAGS: + if (*(uint32_t *)data != NCR_KEY_FLAG_EXPORTABLE) { + fprintf(stderr, "Unexpected key flags\n"); + return 1; + } + got_flags++; + break; + case NCR_ATTR_KEY_TYPE: + if (*(uint32_t *)data != NCR_KEY_TYPE_SECRET) { + fprintf(stderr, "Unexpected key type\n"); + return 1; + } + got_type++; + break; + } + + if (NLA_ALIGN(nla->nla_len) + NLA_HDRLEN > + kinfo.f.output_size - ((char *)nla - (char *)&kinfo)) + break; + nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len)); + } + if (got_algo != 1 || got_flags != 1 || got_type != 1) { + fprintf(stderr, "Unexpected attrs - %d, %d, %d\n", got_algo, + got_flags, got_type); + return 1; + } + if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_DEINIT)"); @@ -15,6 +15,7 @@ #define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__) struct nlattr; +struct ncr_out; struct algo_properties_st { ncr_algorithm_t algo; @@ -125,7 +126,8 @@ int ncr_key_import(struct ncr_lists *lst, void __user* arg); void ncr_key_list_deinit(struct ncr_lists *lst); int ncr_key_generate(struct ncr_lists *lst, const struct ncr_key_generate *gen, struct nlattr *tb[]); -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[]); int ncr_key_generate_pair(struct ncr_lists *lst, const struct ncr_key_generate_pair *gen, @@ -31,6 +31,7 @@ #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) { @@ -599,18 +600,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; @@ -622,11 +620,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_u32(out, *attr, + item->algorithm->algo); + 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); @@ -148,14 +148,30 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) CASE_NO_OUTPUT(NCRIO_KEY_GENERATE_PAIR, ncr_key_generate_pair, ncr_key_generate_pair); CASE_NO_OUTPUT(NCRIO_KEY_DERIVE, ncr_key_derive, ncr_key_derive); + case NCRIO_KEY_GET_INFO: { + struct ncr_key_get_info data; + struct ncr_out out; + + attr_buf = NCR_GET_INPUT_ARGS(&data, tb, arg); + if (IS_ERR(attr_buf)) { + err(); + return PTR_ERR(attr_buf); + } + ret = NCR_OUT_INIT(&out, &data, arg); + if (ret != 0) { + err(); + break; + } + ret = ncr_key_get_info(lst, &out, &data, tb); + ncr_out_free(&out); + break; + } case NCRIO_KEY_DEINIT: return ncr_key_deinit(lst, arg); case NCRIO_KEY_EXPORT: return ncr_key_export(lst, arg); case NCRIO_KEY_IMPORT: return ncr_key_import(lst, arg); - case NCRIO_KEY_GET_INFO: - return ncr_key_info(lst, arg); case NCRIO_KEY_WRAP: return ncr_key_wrap(lst, arg); case NCRIO_KEY_UNWRAP: @@ -195,6 +211,7 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) case NCRIO_KEY_GENERATE: case NCRIO_KEY_GENERATE_PAIR: case NCRIO_KEY_DERIVE: + case NCRIO_KEY_GET_INFO: return ncr_ioctl(lst, cmd, arg_); default: return -EINVAL; @@ -34,6 +34,7 @@ enum { NCR_ATTR_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */ NCR_ATTR_DERIVATION_ALGORITHM, /* NLA_U32 - ncr_algorithm_t */ NCR_ATTR_KEY_FLAGS, /* NLA_U32 - NCR_KEY_FLAG_* */ + NCR_ATTR_KEY_TYPE, /* NLA_U32 - ncr_key_type_t */ NCR_ATTR_SECRET_KEY_BITS, /* NLA_U32 */ NCR_ATTR_RSA_MODULUS_BITS, /* NLA_U32 */ NCR_ATTR_RSA_E, /* NLA_BINARY */ @@ -42,6 +43,7 @@ enum { NCR_ATTR_DH_PRIME, /* NLA_BINARY */ NCR_ATTR_DH_BASE, /* NLA_BINARY */ NCR_ATTR_DH_PUBLIC, /* NLA_BINARY */ + NCR_ATTR_WANTED_ATTRS, /* NLA_BINARY - array of u16 IDs */ /* Add new attributes here */ @@ -174,15 +176,10 @@ struct ncr_key_derive { #define MAX_KEY_ID_SIZE 20 -struct ncr_key_info_st { - ncr_key_t key; /* input */ - - unsigned int flags; - ncr_key_type_t type; - ncr_algorithm_t algorithm; /* valid for public/private keys */ - - __u8 key_id[MAX_KEY_ID_SIZE]; - __kernel_size_t key_id_size; +struct ncr_key_get_info { + __u32 input_size, output_size; + ncr_key_t key; + __NL_ATTRIBUTES; }; struct ncr_key_data_st { @@ -207,7 +204,7 @@ struct ncr_key_data_st { /* derive a new key from an old one */ #define NCRIO_KEY_DERIVE _IOWR('c', 207, struct ncr_key_derive) /* return information on a key */ -#define NCRIO_KEY_GET_INFO _IOWR('c', 208, struct ncr_key_info_st) +#define NCRIO_KEY_GET_INFO _IOWR('c', 208, struct ncr_key_get_info) /* export a secret key */ #define NCRIO_KEY_EXPORT _IOWR('c', 209, struct ncr_key_data_st) @@ -32,6 +32,7 @@ static const struct nla_policy ncr_attr_policy[NCR_ATTR_MAX + 1] = { [NCR_ATTR_ALGORITHM] = { NLA_U32, 0 }, [NCR_ATTR_DERIVATION_ALGORITHM] = { NLA_U32, 0 }, [NCR_ATTR_KEY_FLAGS] = { NLA_U32, 0 }, + [NCR_ATTR_KEY_TYPE] = { NLA_U32, 0 }, [NCR_ATTR_SECRET_KEY_BITS] = { NLA_U32, 0 }, [NCR_ATTR_RSA_MODULUS_BITS] = { NLA_U32, 0 }, [NCR_ATTR_RSA_E] = { NLA_BINARY, 0 }, @@ -40,6 +41,7 @@ static const struct nla_policy ncr_attr_policy[NCR_ATTR_MAX + 1] = { [NCR_ATTR_DH_PRIME] = { NLA_BINARY, 0 }, [NCR_ATTR_DH_BASE] = { NLA_BINARY, 0 }, [NCR_ATTR_DH_PUBLIC] = { NLA_BINARY, 0 }, + [NCR_ATTR_WANTED_ATTRS] = { NLA_BINARY, 0 }, }; void *__ncr_get_input_args(void *fixed, struct nlattr *tb[], size_t fixed_size, |