[PATCH v8 2/4] crypto: AF_ALG -- add setpubkey setsockopt call
From: Stephan Müller <hidden>
Date: 2017-08-10 06:40:47
Subsystem:
crypto api, networking drivers, the rest · Maintainers:
Herbert Xu, "David S. Miller", Andrew Lunn, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
For supporting asymmetric ciphers, user space must be able to set the public key. The patch adds a new setsockopt call for setting the public key. Signed-off-by: Stephan Mueller <redacted> --- crypto/af_alg.c | 18 +++++++++++++----- include/crypto/if_alg.h | 1 + include/uapi/linux/if_alg.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index a35a9f854a04..176921d7593a 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c@@ -203,13 +203,17 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } static int alg_setkey(struct sock *sk, char __user *ukey, - unsigned int keylen) + unsigned int keylen, + int (*setkey)(void *private, const u8 *key, + unsigned int keylen)) { struct alg_sock *ask = alg_sk(sk); - const struct af_alg_type *type = ask->type; u8 *key; int err; + if (!setkey) + return -ENOPROTOOPT; + key = sock_kmalloc(sk, keylen, GFP_KERNEL); if (!key) return -ENOMEM;
@@ -218,7 +222,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey, if (copy_from_user(key, ukey, keylen)) goto out; - err = type->setkey(ask->private, key, keylen); + err = setkey(ask->private, key, keylen); out: sock_kzfree_s(sk, key, keylen);
@@ -248,10 +252,14 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, case ALG_SET_KEY: if (sock->state == SS_CONNECTED) goto unlock; - if (!type->setkey) + + err = alg_setkey(sk, optval, optlen, type->setkey); + break; + case ALG_SET_PUBKEY: + if (sock->state == SS_CONNECTED) goto unlock; - err = alg_setkey(sk, optval, optlen); + err = alg_setkey(sk, optval, optlen, type->setpubkey); break; case ALG_SET_AEAD_AUTHSIZE: if (sock->state == SS_CONNECTED)
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 50a21488f3ba..d1de8ed3e77b 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h@@ -55,6 +55,7 @@ struct af_alg_type { void *(*bind)(const char *name, u32 type, u32 mask); void (*release)(void *private); int (*setkey)(void *private, const u8 *key, unsigned int keylen); + int (*setpubkey)(void *private, const u8 *key, unsigned int keylen); int (*accept)(void *private, struct sock *sk); int (*accept_nokey)(void *private, struct sock *sk); int (*setauthsize)(void *private, unsigned int authsize);
diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h
index d81dcca5bdd7..02e61627e089 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h@@ -34,6 +34,7 @@ struct af_alg_iv { #define ALG_SET_OP 3 #define ALG_SET_AEAD_ASSOCLEN 4 #define ALG_SET_AEAD_AUTHSIZE 5 +#define ALG_SET_PUBKEY 6 /* Operations */ #define ALG_OP_DECRYPT 0
--
2.13.4