diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-08-18 03:28:31 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-08-24 22:58:02 +0200 |
commit | d6e4385206d32171d63abe33ee11a349dc9d6e3a (patch) | |
tree | 279ce2bdb969803cc815c5d11470003497d3f220 | |
parent | b327f41fefe390d6db4832fe44f3cf37d86514c0 (diff) | |
download | kernel-crypto-d6e4385206d32171d63abe33ee11a349dc9d6e3a.tar.gz kernel-crypto-d6e4385206d32171d63abe33ee11a349dc9d6e3a.tar.xz kernel-crypto-d6e4385206d32171d63abe33ee11a349dc9d6e3a.zip |
Convert *_KEY_DERIVE
-rw-r--r-- | examples/pk.c | 60 | ||||
-rw-r--r-- | ncr-int.h | 3 | ||||
-rw-r--r-- | ncr-key.c | 29 | ||||
-rw-r--r-- | ncr-pk.c | 39 | ||||
-rw-r--r-- | ncr-pk.h | 2 | ||||
-rw-r--r-- | ncr.c | 4 | ||||
-rw-r--r-- | ncr.h | 24 | ||||
-rw-r--r-- | utils.c | 2 |
8 files changed, 86 insertions, 77 deletions
diff --git a/examples/pk.c b/examples/pk.c index bb73f289103..84373226004 100644 --- a/examples/pk.c +++ b/examples/pk.c @@ -329,7 +329,15 @@ gnutls_dh_params_t dhp; unsigned char y1[1024], y2[1024]; size_t y1_size, y2_size; struct ncr_key_data_st keydata; -struct ncr_key_derivation_params_st kderive; +struct __attribute__((packed)) { + struct ncr_key_derive f; + struct nlattr algo_head ALIGN_NL; + uint32_t algo ALIGN_NL; + struct nlattr flags_head ALIGN_NL; + uint32_t flags ALIGN_NL; + struct nlattr public_head ALIGN_NL; + unsigned char public[DATA_SIZE] ALIGN_NL; +} kderive; fprintf(stdout, "Tests on DH key exchange:"); fflush(stdout); @@ -478,17 +486,26 @@ struct ncr_key_derivation_params_st kderive; return 1; } - memset(&kderive, 0, sizeof(kderive)); - kderive.derive = NCR_DERIVE_DH; - kderive.newkey = z1; - kderive.keyflags = NCR_KEY_FLAG_EXPORTABLE; - kderive.key = private1; - kderive.params.params.dh.pub = y2; - kderive.params.params.dh.pub_size = y2_size; + memset(&kderive.f, 0, sizeof(kderive.f)); + kderive.f.input_key = private1; + kderive.f.new_key = z1; + kderive.algo_head.nla_len = NLA_HDRLEN + sizeof(kderive.algo); + kderive.algo_head.nla_type = NCR_ATTR_DERIVATION_ALGORITHM; + kderive.algo = NCR_DERIVE_DH; + kderive.flags_head.nla_len = NLA_HDRLEN + sizeof(kderive.flags); + kderive.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; + kderive.flags = NCR_KEY_FLAG_EXPORTABLE; + kderive.public_head.nla_len = NLA_HDRLEN + y2_size; + kderive.public_head.nla_type = NCR_ATTR_DH_PUBLIC; + memcpy(kderive.public, y2, y2_size); + nla = (struct nlattr *)((char *)&kderive.public_head + + NLA_ALIGN(kderive.public_head.nla_len)); + kderive.f.input_size = (char *)nla - (char *)&kderive; + assert(kderive.f.input_size <= sizeof(kderive)); if (ioctl(cfd, NCRIO_KEY_DERIVE, &kderive)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_INIT)"); + perror("ioctl(NCRIO_KEY_DERIVE)"); return 1; } @@ -500,17 +517,26 @@ struct ncr_key_derivation_params_st kderive; return 1; } - memset(&kderive, 0, sizeof(kderive)); - kderive.derive = NCR_DERIVE_DH; - kderive.newkey = z2; - kderive.keyflags = NCR_KEY_FLAG_EXPORTABLE; - kderive.key = private2; - kderive.params.params.dh.pub = y1; - kderive.params.params.dh.pub_size = y1_size; + memset(&kderive.f, 0, sizeof(kderive.f)); + kderive.f.input_key = private2; + kderive.f.new_key = z2; + kderive.algo_head.nla_len = NLA_HDRLEN + sizeof(kderive.algo); + kderive.algo_head.nla_type = NCR_ATTR_DERIVATION_ALGORITHM; + kderive.algo = NCR_DERIVE_DH; + kderive.flags_head.nla_len = NLA_HDRLEN + sizeof(kderive.flags); + kderive.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; + kderive.flags = NCR_KEY_FLAG_EXPORTABLE; + kderive.public_head.nla_len = NLA_HDRLEN + y2_size; + kderive.public_head.nla_type = NCR_ATTR_DH_PUBLIC; + memcpy(kderive.public, y1, y1_size); + nla = (struct nlattr *)((char *)&kderive.public_head + + NLA_ALIGN(kderive.public_head.nla_len)); + kderive.f.input_size = (char *)nla - (char *)&kderive; + assert(kderive.f.input_size <= sizeof(kderive)); if (ioctl(cfd, NCRIO_KEY_DERIVE, &kderive)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_INIT)"); + perror("ioctl(NCRIO_KEY_DERIVE)"); return 1; } diff --git a/ncr-int.h b/ncr-int.h index 172c51ce600..0ae042b148c 100644 --- a/ncr-int.h +++ b/ncr-int.h @@ -111,7 +111,8 @@ long ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg); /* key derivation */ -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[]); void ncr_key_clear(struct key_item_st* item); void ncr_key_assign_flags(struct key_item_st* item, unsigned int flags); diff --git a/ncr-key.c b/ncr-key.c index 90ba45ea020..15e90fee10c 100644 --- a/ncr-key.c +++ b/ncr-key.c @@ -701,22 +701,15 @@ 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; +const struct nlattr *nla; 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; @@ -730,7 +723,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; @@ -738,12 +731,14 @@ struct key_item_st* newkey = NULL; ncr_key_clear(newkey); - ncr_key_assign_flags(newkey, data.keyflags); + nla = tb[NCR_ATTR_KEY_FLAGS]; + if (nla != NULL) + ncr_key_assign_flags(newkey, nla_get_u32(nla)); 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; @@ -755,12 +750,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); @@ -681,38 +681,34 @@ fail: } int ncr_pk_derive(struct key_item_st* newkey, struct key_item_st* oldkey, - struct ncr_key_derivation_params_st * params) + struct nlattr *tb[]) { +const struct nlattr *nla; int ret; -void* tmp = NULL; -size_t size; - switch(params->derive) { + nla = tb[NCR_ATTR_DERIVATION_ALGORITHM]; + if (nla == NULL) { + err(); + return -EINVAL; + } + switch(nla_get_u32(nla)) { case NCR_DERIVE_DH: if (oldkey->type != NCR_KEY_TYPE_PRIVATE && oldkey->algorithm->algo != NCR_ALG_DH) { err(); return -EINVAL; } - - size = params->params.params.dh.pub_size; - tmp = kmalloc(size, GFP_KERNEL); - if (tmp == NULL) { + + nla = tb[NCR_ATTR_DH_PUBLIC]; + if (nla == NULL) { err(); - return -ENOMEM; - } - - if (unlikely(copy_from_user(tmp, params->params.params.dh.pub, - size))) { - err(); - ret = -EFAULT; - goto fail; + return -EINVAL; } - - ret = dh_derive_gxy(newkey, &oldkey->key.pk.dh, tmp, size); + ret = dh_derive_gxy(newkey, &oldkey->key.pk.dh, + nla_data(nla), nla_len(nla)); if (ret < 0) { err(); - goto fail; + return ret; } break; @@ -721,10 +717,7 @@ size_t size; return -EINVAL; } - ret = 0; -fail: - kfree(tmp); - return ret; + return 0; } int ncr_pk_get_rsa_size( rsa_key* key) @@ -51,7 +51,7 @@ int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx, int _ncr_tomerr(int err); int ncr_pk_derive(struct key_item_st* newkey, struct key_item_st* oldkey, - struct ncr_key_derivation_params_st * params); + struct nlattr *tb[]); int ncr_pk_get_rsa_size( rsa_key* key); int ncr_pk_get_dsa_size( dsa_key* key); @@ -147,6 +147,7 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) CASE_NO_OUTPUT(NCRIO_KEY_GENERATE, ncr_key_generate, ncr_key_generate); 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_DEINIT: return ncr_key_deinit(lst, arg); case NCRIO_KEY_EXPORT: @@ -174,8 +175,6 @@ ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) case NCRIO_MASTER_KEY_SET: return ncr_master_key_set(arg); - case NCRIO_KEY_DERIVE: - return ncr_key_derive(lst, arg); default: return -EINVAL; #undef CASE_NO_OUTPUT @@ -195,6 +194,7 @@ ncr_compat_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) case NCRIO_KEY_INIT: case NCRIO_KEY_GENERATE: case NCRIO_KEY_GENERATE_PAIR: + case NCRIO_KEY_DERIVE: return ncr_ioctl(lst, cmd, arg_); default: return -EINVAL; @@ -26,10 +26,13 @@ space for output attributes is available, and is not updated. */ /* FIXME: better names for algorithm parameters? */ +/* FIXME: Split key generation/derivation attributes to decrease the number + of attributes used for the frequent operations? */ enum { NCR_ATTR_UNSPEC, /* 0 is special in lib/nlattr.c. */ /* FIXME: Use NLA_STRING for this, later */ 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_SECRET_KEY_BITS, /* NLA_U32 */ NCR_ATTR_RSA_MODULUS_BITS, /* NLA_U32 */ @@ -38,6 +41,7 @@ enum { NCR_ATTR_DSA_Q_BITS, /* NLA_U32 */ NCR_ATTR_DH_PRIME, /* NLA_BINARY */ NCR_ATTR_DH_BASE, /* NLA_BINARY */ + NCR_ATTR_DH_PUBLIC, /* NLA_BINARY */ /* Add new attributes here */ @@ -133,7 +137,7 @@ typedef enum { RSA_PKCS1_PSS, /* for signatures only */ } ncr_rsa_type_t; -/* used in derivation/encryption +/* used in encryption */ struct ncr_key_params_st { /* this structure always corresponds to a key. Hence the @@ -145,10 +149,6 @@ struct ncr_key_params_st { __kernel_size_t iv_size; } cipher; struct { - __u8 __user *pub; - __kernel_size_t pub_size; - } dh; - struct { ncr_rsa_type_t type; ncr_algorithm_t oaep_hash; /* for OAEP */ ncr_algorithm_t sign_hash; /* for signatures */ @@ -164,14 +164,12 @@ typedef enum { NCR_DERIVE_DH=1, } ncr_derive_t; -struct ncr_key_derivation_params_st { - ncr_derive_t derive; /* the derivation algorithm */ - ncr_key_t newkey; - unsigned int keyflags; /* for new key */ - - ncr_key_t key; - struct ncr_key_params_st params; +struct ncr_key_derive { + __u32 input_size, output_size; + ncr_key_t input_key; + ncr_key_t new_key; + __NL_ATTRIBUTES; }; #define MAX_KEY_ID_SIZE 20 @@ -207,7 +205,7 @@ struct ncr_key_data_st { /* generate a public key pair */ #define NCRIO_KEY_GENERATE_PAIR _IOWR('c', 206, struct ncr_key_generate_pair) /* derive a new key from an old one */ -#define NCRIO_KEY_DERIVE _IOR ('c', 207, struct ncr_key_derivation_params_st) +#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) @@ -30,6 +30,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_SECRET_KEY_BITS] = { NLA_U32, 0 }, [NCR_ATTR_RSA_MODULUS_BITS] = { NLA_U32, 0 }, @@ -38,6 +39,7 @@ static const struct nla_policy ncr_attr_policy[NCR_ATTR_MAX + 1] = { [NCR_ATTR_DSA_Q_BITS] = { NLA_U32, 0 }, [NCR_ATTR_DH_PRIME] = { NLA_BINARY, 0 }, [NCR_ATTR_DH_BASE] = { NLA_BINARY, 0 }, + [NCR_ATTR_DH_PUBLIC] = { NLA_BINARY, 0 }, }; void *__ncr_get_input_args(void *fixed, struct nlattr *tb[], size_t fixed_size, |