diff mbox

[v5,6/6] crypto: AF_ALG - add support for key_id

Message ID 20160415202317.29343.93424.stgit@tstruk-mobl1 (mailing list archive)
State RFC
Delegated to: Herbert Xu
Headers show

Commit Message

Tadeusz Struk April 15, 2016, 8:23 p.m. UTC
This patch adds support for asymmetric key type to AF_ALG.
It will work as follows: A new PF_ALG socket options are
added on top of existing ALG_SET_KEY and ALG_SET_PUBKEY, namely
ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID for setting public and
private keys respectively. When these new options will be used
the user, instead of providing the key material, will provide a
key id and the key itself will be obtained from kernel keyring
subsystem. The user will use the standard tools (keyctl tool
or the keyctl syscall) for key instantiation and to obtain the
key id. The key id can also be obtained by reading the
/proc/keys file.

When a key corresponding to the given keyid is found, it is stored
in the socket context and subsequent crypto operation invoked by the
user will use the new asymmetric accessor functions instead of akcipher
api. The asymmetric subtype can internally use akcipher api or
invoke operations defined by a given subtype, depending on the
key type.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/af_alg.c             |   10 ++
 crypto/algif_akcipher.c     |  207 ++++++++++++++++++++++++++++++++++++++++++-
 include/crypto/if_alg.h     |    1 
 include/uapi/linux/if_alg.h |    2 
 4 files changed, 215 insertions(+), 5 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Tadeusz Struk April 15, 2016, 9:32 p.m. UTC | #1
On 04/15/2016 02:32 PM, kbuild test robot wrote:
> Hi Tadeusz,
> 
> [auto build test ERROR on cryptodev/master]
> [also build test ERROR on v4.6-rc3 next-20160415]
> [if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Tadeusz-Struk/crypto-algif-add-akcipher/20160416-043207
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
> config: i386-allmodconfig (attached as .config)
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386 

Hi,
It's is for https://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-next
plus this:
https://patchwork.kernel.org/patch/8843381/
Thanks,
kernel test robot April 15, 2016, 9:32 p.m. UTC | #2
Hi Tadeusz,

[auto build test ERROR on cryptodev/master]
[also build test ERROR on v4.6-rc3 next-20160415]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Tadeusz-Struk/crypto-algif-add-akcipher/20160416-043207
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: i386-allmodconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   crypto/algif_akcipher.c: In function 'asym_key_encrypt':
>> crypto/algif_akcipher.c:331:9: error: variable 'params' has initializer but incomplete type
     struct kernel_pkey_params params = {0};
            ^
>> crypto/algif_akcipher.c:331:38: warning: excess elements in struct initializer
     struct kernel_pkey_params params = {0};
                                         ^
   crypto/algif_akcipher.c:331:38: note: (near initialization for 'params')
>> crypto/algif_akcipher.c:331:28: error: storage size of 'params' isn't known
     struct kernel_pkey_params params = {0};
                               ^
>> crypto/algif_akcipher.c:357:8: error: implicit declaration of function 'encrypt_blob' [-Werror=implicit-function-declaration]
     ret = encrypt_blob(&params, in, out);
           ^
>> crypto/algif_akcipher.c:331:28: warning: unused variable 'params' [-Wunused-variable]
     struct kernel_pkey_params params = {0};
                               ^
   crypto/algif_akcipher.c: In function 'asym_key_decrypt':
   crypto/algif_akcipher.c:371:9: error: variable 'params' has initializer but incomplete type
     struct kernel_pkey_params params = {0};
            ^
   crypto/algif_akcipher.c:371:38: warning: excess elements in struct initializer
     struct kernel_pkey_params params = {0};
                                         ^
   crypto/algif_akcipher.c:371:38: note: (near initialization for 'params')
   crypto/algif_akcipher.c:371:28: error: storage size of 'params' isn't known
     struct kernel_pkey_params params = {0};
                               ^
>> crypto/algif_akcipher.c:397:8: error: implicit declaration of function 'decrypt_blob' [-Werror=implicit-function-declaration]
     ret = decrypt_blob(&params, in, out);
           ^
   crypto/algif_akcipher.c:371:28: warning: unused variable 'params' [-Wunused-variable]
     struct kernel_pkey_params params = {0};
                               ^
   crypto/algif_akcipher.c: In function 'asym_key_sign':
   crypto/algif_akcipher.c:411:9: error: variable 'params' has initializer but incomplete type
     struct kernel_pkey_params params = {0};
            ^
   crypto/algif_akcipher.c:411:38: warning: excess elements in struct initializer
     struct kernel_pkey_params params = {0};
                                         ^
   crypto/algif_akcipher.c:411:38: note: (near initialization for 'params')
   crypto/algif_akcipher.c:411:28: error: storage size of 'params' isn't known
     struct kernel_pkey_params params = {0};
                               ^
>> crypto/algif_akcipher.c:437:8: error: implicit declaration of function 'create_signature' [-Werror=implicit-function-declaration]
     ret = create_signature(&params, in, out);
           ^
   crypto/algif_akcipher.c:411:28: warning: unused variable 'params' [-Wunused-variable]
     struct kernel_pkey_params params = {0};
                               ^
   crypto/algif_akcipher.c: In function 'asym_key_verify':
>> crypto/algif_akcipher.c:465:5: error: 'struct public_key_signature' has no member named 'encoding'
     sig.encoding = "pkcs1";
        ^
   cc1: some warnings being treated as errors

vim +/params +331 crypto/algif_akcipher.c

   325	
   326		return err ? err : size;
   327	}
   328	
   329	static int asym_key_encrypt(const struct key *key, struct akcipher_request *req)
   330	{
 > 331		struct kernel_pkey_params params = {0};
   332		char *src = NULL, *dst = NULL, *in, *out;
   333		int ret;
   334	
   335		if (!sg_is_last(req->src)) {
   336			src = kmalloc(req->src_len, GFP_KERNEL);
   337			if (!src)
   338				return -ENOMEM;
   339			scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
   340			in = src;
   341		} else {
   342			in = sg_virt(req->src);
   343		}
   344		if (!sg_is_last(req->dst)) {
   345			dst = kmalloc(req->dst_len, GFP_KERNEL);
   346			if (!dst) {
   347				kfree(src);
   348				return -ENOMEM;
   349			}
   350			out = dst;
   351		} else {
   352			out = sg_virt(req->dst);
   353		}
   354		params.key = (struct key *)key;
   355		params.data_len = req->src_len;
   356		params.enc_len = req->dst_len;
 > 357		ret = encrypt_blob(&params, in, out);
   358		if (ret)
   359			goto free;
   360	
   361		if (dst)
   362			scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
   363	free:
   364		kfree(src);
   365		kfree(dst);
   366		return ret;
   367	}
   368	
   369	static int asym_key_decrypt(const struct key *key, struct akcipher_request *req)
   370	{
 > 371		struct kernel_pkey_params params = {0};
   372		char *src = NULL, *dst = NULL, *in, *out;
   373		int ret;
   374	
   375		if (!sg_is_last(req->src)) {
   376			src = kmalloc(req->src_len, GFP_KERNEL);
   377			if (!src)
   378				return -ENOMEM;
   379			scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
   380			in = src;
   381		} else {
   382			in = sg_virt(req->src);
   383		}
   384		if (!sg_is_last(req->dst)) {
   385			dst = kmalloc(req->dst_len, GFP_KERNEL);
   386			if (!dst) {
   387				kfree(src);
   388				return -ENOMEM;
   389			}
   390			out = dst;
   391		} else {
   392			out = sg_virt(req->dst);
   393		}
   394		params.key = (struct key *)key;
   395		params.data_len = req->src_len;
   396		params.enc_len = req->dst_len;
 > 397		ret = decrypt_blob(&params, in, out);
   398		if (ret)
   399			goto free;
   400	
   401		if (dst)
   402			scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
   403	free:
   404		kfree(src);
   405		kfree(dst);
   406		return ret;
   407	}
   408	
   409	static int asym_key_sign(const struct key *key, struct akcipher_request *req)
   410	{
 > 411		struct kernel_pkey_params params = {0};
   412		char *src = NULL, *dst = NULL, *in, *out;
   413		int ret;
   414	
   415		if (!sg_is_last(req->src)) {
   416			src = kmalloc(req->src_len, GFP_KERNEL);
   417			if (!src)
   418				return -ENOMEM;
   419			scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
   420			in = src;
   421		} else {
   422			in = sg_virt(req->src);
   423		}
   424		if (!sg_is_last(req->dst)) {
   425			dst = kmalloc(req->dst_len, GFP_KERNEL);
   426			if (!dst) {
   427				kfree(src);
   428				return -ENOMEM;
   429			}
   430			out = dst;
   431		} else {
   432			out = sg_virt(req->dst);
   433		}
   434		params.key = (struct key *)key;
   435		params.data_len = req->src_len;
   436		params.enc_len = req->dst_len;
 > 437		ret = create_signature(&params, in, out);
   438		if (ret)
   439			goto free;
   440	
   441		if (dst)
   442			scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
   443	free:
   444		kfree(src);
   445		kfree(dst);
   446		return ret;
   447	}
   448	
   449	static int asym_key_verify(const struct key *key, struct akcipher_request *req)
   450	{
   451		struct public_key_signature sig;
   452		char *src = NULL, *in;
   453		int ret;
   454	
   455		if (!sg_is_last(req->src)) {
   456			src = kmalloc(req->src_len, GFP_KERNEL);
   457			if (!src)
   458				return -ENOMEM;
   459			scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
   460			in = src;
   461		} else {
   462			in = sg_virt(req->src);
   463		}
   464		sig.pkey_algo = "rsa";
 > 465		sig.encoding = "pkcs1";
   466		/* Need to find a way to pass the hash param */
   467		sig.hash_algo = "sha1";
   468		sig.digest_size = 20;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Philip Li April 19, 2016, 10:25 a.m. UTC | #3
On Fri, Apr 15, 2016 at 02:32:47PM -0700, Tadeusz Struk wrote:
> On 04/15/2016 02:32 PM, kbuild test robot wrote:
> > Hi Tadeusz,
> > 
> > [auto build test ERROR on cryptodev/master]
> > [also build test ERROR on v4.6-rc3 next-20160415]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Tadeusz-Struk/crypto-algif-add-akcipher/20160416-043207
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
> > config: i386-allmodconfig (attached as .config)
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=i386 
> 
> Hi,
> It's is for https://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-next
> plus this:
> https://patchwork.kernel.org/patch/8843381/

Thanks Tadeusz for the feedback.

hi Xiaolong, anything we can do in 0day side to detect the base for this case?

> Thanks,
> -- 
> TS
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 24dc082..59c8244 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -260,6 +260,16 @@  static int alg_setsockopt(struct socket *sock, int level, int optname,
 
 		err = alg_setkey(sk, optval, optlen, type->setpubkey);
 		break;
+
+	case ALG_SET_KEY_ID:
+	case ALG_SET_PUBKEY_ID:
+		/* ALG_SET_KEY_ID is only for akcipher */
+		if (!strcmp(type->name, "akcipher") ||
+		    sock->state == SS_CONNECTED)
+			goto unlock;
+
+		err = alg_setkey(sk, optval, optlen, type->setkeyid);
+		break;
 	case ALG_SET_AEAD_AUTHSIZE:
 		if (sock->state == SS_CONNECTED)
 			goto unlock;
diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
index e00793d..863866d 100644
--- a/crypto/algif_akcipher.c
+++ b/crypto/algif_akcipher.c
@@ -14,6 +14,8 @@ 
 #include <crypto/akcipher.h>
 #include <crypto/scatterwalk.h>
 #include <crypto/if_alg.h>
+#include <crypto/public_key.h>
+#include <keys/asymmetric-type.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/kernel.h>
@@ -29,6 +31,7 @@  struct akcipher_sg_list {
 
 struct akcipher_tfm {
 	struct crypto_akcipher *akcipher;
+	char keyid[12];
 	bool has_key;
 };
 
@@ -37,6 +40,7 @@  struct akcipher_ctx {
 	struct af_alg_sgl rsgl[ALG_MAX_PAGES];
 
 	struct af_alg_completion completion;
+	struct key *key;
 
 	unsigned long used;
 
@@ -322,6 +326,153 @@  unlock:
 	return err ? err : size;
 }
 
+static int asym_key_encrypt(const struct key *key, struct akcipher_request *req)
+{
+	struct kernel_pkey_params params = {0};
+	char *src = NULL, *dst = NULL, *in, *out;
+	int ret;
+
+	if (!sg_is_last(req->src)) {
+		src = kmalloc(req->src_len, GFP_KERNEL);
+		if (!src)
+			return -ENOMEM;
+		scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+		in = src;
+	} else {
+		in = sg_virt(req->src);
+	}
+	if (!sg_is_last(req->dst)) {
+		dst = kmalloc(req->dst_len, GFP_KERNEL);
+		if (!dst) {
+			kfree(src);
+			return -ENOMEM;
+		}
+		out = dst;
+	} else {
+		out = sg_virt(req->dst);
+	}
+	params.key = (struct key *)key;
+	params.data_len = req->src_len;
+	params.enc_len = req->dst_len;
+	ret = encrypt_blob(&params, in, out);
+	if (ret)
+		goto free;
+
+	if (dst)
+		scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+	kfree(src);
+	kfree(dst);
+	return ret;
+}
+
+static int asym_key_decrypt(const struct key *key, struct akcipher_request *req)
+{
+	struct kernel_pkey_params params = {0};
+	char *src = NULL, *dst = NULL, *in, *out;
+	int ret;
+
+	if (!sg_is_last(req->src)) {
+		src = kmalloc(req->src_len, GFP_KERNEL);
+		if (!src)
+			return -ENOMEM;
+		scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+		in = src;
+	} else {
+		in = sg_virt(req->src);
+	}
+	if (!sg_is_last(req->dst)) {
+		dst = kmalloc(req->dst_len, GFP_KERNEL);
+		if (!dst) {
+			kfree(src);
+			return -ENOMEM;
+		}
+		out = dst;
+	} else {
+		out = sg_virt(req->dst);
+	}
+	params.key = (struct key *)key;
+	params.data_len = req->src_len;
+	params.enc_len = req->dst_len;
+	ret = decrypt_blob(&params, in, out);
+	if (ret)
+		goto free;
+
+	if (dst)
+		scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+	kfree(src);
+	kfree(dst);
+	return ret;
+}
+
+static int asym_key_sign(const struct key *key, struct akcipher_request *req)
+{
+	struct kernel_pkey_params params = {0};
+	char *src = NULL, *dst = NULL, *in, *out;
+	int ret;
+
+	if (!sg_is_last(req->src)) {
+		src = kmalloc(req->src_len, GFP_KERNEL);
+		if (!src)
+			return -ENOMEM;
+		scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+		in = src;
+	} else {
+		in = sg_virt(req->src);
+	}
+	if (!sg_is_last(req->dst)) {
+		dst = kmalloc(req->dst_len, GFP_KERNEL);
+		if (!dst) {
+			kfree(src);
+			return -ENOMEM;
+		}
+		out = dst;
+	} else {
+		out = sg_virt(req->dst);
+	}
+	params.key = (struct key *)key;
+	params.data_len = req->src_len;
+	params.enc_len = req->dst_len;
+	ret = create_signature(&params, in, out);
+	if (ret)
+		goto free;
+
+	if (dst)
+		scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+	kfree(src);
+	kfree(dst);
+	return ret;
+}
+
+static int asym_key_verify(const struct key *key, struct akcipher_request *req)
+{
+	struct public_key_signature sig;
+	char *src = NULL, *in;
+	int ret;
+
+	if (!sg_is_last(req->src)) {
+		src = kmalloc(req->src_len, GFP_KERNEL);
+		if (!src)
+			return -ENOMEM;
+		scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+		in = src;
+	} else {
+		in = sg_virt(req->src);
+	}
+	sig.pkey_algo = "rsa";
+	sig.encoding = "pkcs1";
+	/* Need to find a way to pass the hash param */
+	sig.hash_algo = "sha1";
+	sig.digest_size = 20;
+	sig.s_size = req->src_len;
+	sig.s = src;
+	ret = verify_signature(key, &sig);
+	kfree(src);
+	return ret;
+}
+
 static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
 			    size_t ignored, int flags)
 {
@@ -377,16 +528,28 @@  static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
 				   usedpages);
 	switch (ctx->op) {
 	case ALG_OP_VERIFY:
-		err = crypto_akcipher_verify(&ctx->req);
+		if (ctx->key)
+			err = asym_key_verify(ctx->key, &ctx->req);
+		else
+			err = crypto_akcipher_verify(&ctx->req);
 		break;
 	case ALG_OP_SIGN:
-		err = crypto_akcipher_sign(&ctx->req);
+		if (ctx->key)
+			err = asym_key_sign(ctx->key, &ctx->req);
+		else
+			err = crypto_akcipher_sign(&ctx->req);
 		break;
 	case ALG_OP_ENCRYPT:
-		err = crypto_akcipher_encrypt(&ctx->req);
+		if (ctx->key)
+			err = asym_key_encrypt(ctx->key, &ctx->req);
+		else
+			err = crypto_akcipher_encrypt(&ctx->req);
 		break;
 	case ALG_OP_DECRYPT:
-		err = crypto_akcipher_decrypt(&ctx->req);
+		if (ctx->key)
+			err = asym_key_decrypt(ctx->key, &ctx->req);
+		else
+			err = crypto_akcipher_decrypt(&ctx->req);
 		break;
 	default:
 		err = -EFAULT;
@@ -579,6 +742,27 @@  static void akcipher_release(void *private)
 	kfree(tfm);
 }
 
+static int akcipher_setkeyid(void *private, const u8 *key, unsigned int keylen)
+{
+	struct akcipher_tfm *tfm = private;
+	struct key *akey;
+	u32 keyid = *((u32 *)key);
+	int err = -ENOKEY;
+
+	/* Store the key id and verify that a key with the given id is present.
+	 * The actual key will be acquired in the accept_parent function
+	 */
+	sprintf(tfm->keyid, "id:%08x", keyid);
+	akey = request_key(&key_type_asymmetric, tfm->keyid, NULL);
+	if (IS_ERR(key))
+		goto out;
+
+	tfm->has_key = true;
+	key_put(akey);
+out:
+	return err;
+}
+
 static int akcipher_setprivkey(void *private, const u8 *key,
 			       unsigned int keylen)
 {
@@ -610,6 +794,8 @@  static void akcipher_sock_destruct(struct sock *sk)
 	akcipher_put_sgl(sk);
 	sock_kfree_s(sk, ctx, ctx->len);
 	af_alg_release_parent(sk);
+	if (ctx->key)
+		key_put(ctx->key);
 }
 
 static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
@@ -618,6 +804,7 @@  static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
 	struct alg_sock *ask = alg_sk(sk);
 	struct akcipher_tfm *tfm = private;
 	struct crypto_akcipher *akcipher = tfm->akcipher;
+	struct key *key;
 	unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(akcipher);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
@@ -634,11 +821,20 @@  static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
 	af_alg_init_completion(&ctx->completion);
 	sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
 
-	ask->private = ctx;
+	if (strlen(tfm->keyid)) {
+		key = request_key(&key_type_asymmetric, tfm->keyid, NULL);
+		if (IS_ERR(key)) {
+			sock_kfree_s(sk, ctx, len);
+			return -ENOKEY;
+		}
 
+		ctx->key = key;
+		memset(tfm->keyid, '\0', sizeof(tfm->keyid));
+	}
 	akcipher_request_set_tfm(&ctx->req, akcipher);
 	akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				      af_alg_complete, &ctx->completion);
+	ask->private = ctx;
 
 	sk->sk_destruct = akcipher_sock_destruct;
 
@@ -660,6 +856,7 @@  static const struct af_alg_type algif_type_akcipher = {
 	.release	=	akcipher_release,
 	.setkey		=	akcipher_setprivkey,
 	.setpubkey	=	akcipher_setpubkey,
+	.setkeyid	=	akcipher_setkeyid,
 	.accept		=	akcipher_accept_parent,
 	.accept_nokey	=	akcipher_accept_parent_nokey,
 	.ops		=	&algif_akcipher_ops,
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 6c3e6e7..09c99ab 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -53,6 +53,7 @@  struct af_alg_type {
 	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 (*setkeyid)(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 02e6162..0379766 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
@@ -35,6 +35,8 @@  struct af_alg_iv {
 #define ALG_SET_AEAD_ASSOCLEN		4
 #define ALG_SET_AEAD_AUTHSIZE		5
 #define ALG_SET_PUBKEY			6
+#define ALG_SET_PUBKEY_ID		7
+#define ALG_SET_KEY_ID			8
 
 /* Operations */
 #define ALG_OP_DECRYPT			0