linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org, kexec@lists.infradead.org
Cc: akpm@linux-foundation.org, zohar@linux.vnet.ibm.com,
	d.kasatkin@samsung.com, ebiederm@xmission.com, hpa@zytor.com,
	matthew.garrett@nebula.com, vgoyal@redhat.com
Subject: [PATCH 10/16] keyctl: Introduce a new operation KEYCTL_VERIFY_SIGNATURE
Date: Tue, 10 Sep 2013 17:44:25 -0400	[thread overview]
Message-ID: <1378849471-10521-11-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1378849471-10521-1-git-send-email-vgoyal@redhat.com>

This is based on a patch david howells sent me. I have modified that
patch to meet my needs.

Extend kecytl() to add an option to verify signature of a user buffer.
One needs to pass in the signature type also so that respective handler
can be called. Currently I have defined a new signature type
KEYCTL_SIG_TYPE_IMA_DIGSIG, which sinifies signatures generated by IMA
subsystem.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 include/uapi/linux/keyctl.h | 16 +++++++++
 security/keys/compat.c      | 28 ++++++++++++++++
 security/keys/internal.h    |  2 ++
 security/keys/keyctl.c      | 79 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 125 insertions(+)

diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
index 840cb99..d7c7471 100644
--- a/include/uapi/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
@@ -12,6 +12,17 @@
 #ifndef _LINUX_KEYCTL_H
 #define _LINUX_KEYCTL_H
 
+/* Data required to verify signature of a user buffer */
+struct keyctl_sig_data {
+	void *data;
+	size_t datalen;
+	void *sig;
+	size_t siglen;
+	unsigned long sig_type;
+	unsigned long keyring_id;
+	unsigned long flags;
+};
+
 /* special process keyring shortcut IDs */
 #define KEY_SPEC_THREAD_KEYRING		-1	/* - key ID for thread-specific keyring */
 #define KEY_SPEC_PROCESS_KEYRING	-2	/* - key ID for process-specific keyring */
@@ -57,5 +68,10 @@
 #define KEYCTL_INSTANTIATE_IOV		20	/* instantiate a partially constructed key */
 #define KEYCTL_INVALIDATE		21	/* invalidate a key */
 #define KEYCTL_GET_PERSISTENT		22	/* get a user's persistent keyring */
+#define KEYCTL_VERIFY_SIGNATURE		23	/* use a key to verify a signature */
+
+/* Type of signatures */
+#define KEYCTL_SIG_TYPE_UNKNOWN			0
+#define KEYCTL_SIG_TYPE_INTEGRITY_DIGSIG	1 	/* Digital Signature generated by integrity subsystem utilities */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/security/keys/compat.c b/security/keys/compat.c
index bbd32c7..3af2cf2 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -15,6 +15,31 @@
 #include <linux/slab.h>
 #include "internal.h"
 
+struct compat_keyctl_sig_data {
+	compat_uptr_t data;
+	compat_size_t datalen;
+	compat_uptr_t sig;
+	compat_size_t siglen;
+	compat_ulong_t sig_type;
+	compat_ulong_t keyring_id;
+	compat_ulong_t flags;
+};
+
+static long compat_keyctl_verify_signature(const void __user *_sig_data)
+{
+	struct compat_keyctl_sig_data csig_data;
+	int result;
+
+	result = copy_from_user(&csig_data, _sig_data, sizeof(csig_data));
+	if (result)
+		return -EFAULT;
+
+	return __keyctl_verify_signature(csig_data.keyring_id,
+			compat_ptr(csig_data.data), csig_data.datalen,
+			compat_ptr(csig_data.sig), csig_data.siglen,
+			csig_data.sig_type, csig_data.flags);
+}
+
 /*
  * Instantiate a key with the specified compatibility multipart payload and
  * link the key into the destination keyring if one is given.
@@ -141,6 +166,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
 	case KEYCTL_GET_PERSISTENT:
 		return keyctl_get_persistent(arg2, arg3);
 
+	case KEYCTL_VERIFY_SIGNATURE:
+		return compat_keyctl_verify_signature(compat_ptr(arg2));
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 80b2aac..f15acee 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -255,6 +255,8 @@ extern long keyctl_invalidate_key(key_serial_t);
 extern long keyctl_instantiate_key_common(key_serial_t,
 					  const struct iovec *,
 					  unsigned, size_t, key_serial_t);
+extern long keyctl_verify_signature(const void __user *_sig_data);
+extern long __keyctl_verify_signature(key_serial_t keyring_id, void __user *_data, size_t dlen, void __user *_sig, size_t siglen, unsigned long sig_type, unsigned long flags);
 #ifdef CONFIG_PERSISTENT_KEYRINGS
 extern long keyctl_get_persistent(uid_t, key_serial_t);
 extern unsigned persistent_keyring_expiry;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cee72ce..84b7c3d 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -23,6 +23,8 @@
 #include <linux/vmalloc.h>
 #include <linux/security.h>
 #include <linux/uio.h>
+#include <linux/ima.h>
+#include <keys/system_keyring.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -1564,6 +1566,80 @@ error_keyring:
 	return ret;
 }
 
+long __keyctl_verify_signature(key_serial_t keyring_id, void __user *_data,
+				size_t dlen, void __user *_sig, size_t siglen,
+				unsigned long sig_type, unsigned long flags)
+{
+	void *sig;
+	long ret;
+	key_ref_t keyring_ref;
+
+	pr_devel("-->keyctl_verify_signature(,%zu,,%zu,%lu)\n",
+			dlen, siglen, sig_type);
+
+	if (!_data || !dlen || !_sig || !siglen || !keyring_id)
+		return -EINVAL;
+	/*
+	 * Possibly various signature handlers could scan signature and
+	 * claim it belongs to them and verify.
+	 */
+	if (sig_type == KEYCTL_SIG_TYPE_UNKNOWN)
+		return -EOPNOTSUPP;
+
+	/* Get the keyring which should be used */
+	keyring_ref = lookup_user_key(keyring_id, 0, KEY_SEARCH);
+	if (IS_ERR(keyring_ref))
+		return PTR_ERR(keyring_ref);
+
+
+	ret = -ENOMEM;
+	sig = kmalloc(siglen, GFP_KERNEL);
+	if (!sig)
+		goto error_keyref_put;
+
+	ret = -EFAULT;
+	if (copy_from_user(sig, _sig, siglen) != 0)
+		goto error_free_sig;
+
+	switch(sig_type) {
+	case KEYCTL_SIG_TYPE_INTEGRITY_DIGSIG:
+		ret = integrity_verify_user_buffer_digsig(
+					key_ref_to_ptr(keyring_ref),
+					_data, dlen, sig, siglen);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+error_free_sig:
+	kfree(sig);
+error_keyref_put:
+	key_ref_put(keyring_ref);
+	return ret;
+}
+
+/*
+ * Use a key to verify a signature.
+ *
+ * The key argument gives a key to use or a keyring in which a suitable key
+ * might be found.  The signature will be examined and an attempt will be made
+ * to determine the key to use from the information contained therein.
+ */
+long keyctl_verify_signature(const void __user *_sig_data)
+{
+	struct keyctl_sig_data sig_data;
+	int result;
+
+	result = copy_from_user(&sig_data, _sig_data, sizeof(sig_data));
+	if (result)
+		return -EFAULT;
+
+	return __keyctl_verify_signature(sig_data.keyring_id, sig_data.data,
+				sig_data.datalen, sig_data.sig, sig_data.siglen,
+				sig_data.sig_type, sig_data.flags);
+
+}
+
 /*
  * The key control system call
  */
@@ -1670,6 +1746,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case KEYCTL_GET_PERSISTENT:
 		return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3);
 
+	case KEYCTL_VERIFY_SIGNATURE:
+		return keyctl_verify_signature((const void __user *)arg2);
+
 	default:
 		return -EOPNOTSUPP;
 	}
-- 
1.8.3.1


  parent reply	other threads:[~2013-09-10 21:45 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-10 21:44 [PATCH 00/16] [RFC PATCH] Signed kexec support Vivek Goyal
2013-09-10 21:44 ` [PATCH 01/16] mm: vm_brk(), align the length to page boundary Vivek Goyal
2013-09-10 21:44 ` [PATCH 02/16] integrity: Add a function to determine digital signature length Vivek Goyal
2013-09-10 21:44 ` [PATCH 03/16] ima: Allow adding more memory locking metadata after digital signature v2 Vivek Goyal
2013-09-10 21:44 ` [PATCH 04/16] integrity: Allow digital signature verification with a given keyring ptr Vivek Goyal
2013-09-11 17:34   ` Mimi Zohar
2013-09-10 21:44 ` [PATCH 05/16] integrity: Export a function to retrieve hash algo used in digital signature Vivek Goyal
2013-09-10 21:44 ` [PATCH 06/16] ima: export new IMA functions for signature verification Vivek Goyal
2013-09-10 21:44 ` [PATCH 07/16] mm: Define a task flag MMF_VM_LOCKED for memlocked tasks and don't allow munlock Vivek Goyal
2013-09-10 21:44 ` [PATCH 08/16] binfmt_elf: Elf executable signature verification Vivek Goyal
2013-09-10 21:44 ` [PATCH 09/16] ima: define functions to appraise memory buffer contents Vivek Goyal
2013-09-10 21:44 ` Vivek Goyal [this message]
2013-09-10 21:44 ` [PATCH 11/16] ptrace: Do not allow ptrace() from unsigned process to signed one Vivek Goyal
2013-09-10 21:44 ` [PATCH 12/16] binfmt_elf: Do not mark process signed if binary has elf interpreter Vivek Goyal
2013-09-10 21:44 ` [PATCH 13/16] kexec: Allow only signed processes to call sys_kexec() in secureboot mode Vivek Goyal
2013-09-10 21:44 ` [PATCH 14/16] kexec: Export sysfs attributes for secureboot and secure modules to user space Vivek Goyal
2013-09-10 22:40   ` Greg KH
2013-09-11 13:44     ` Vivek Goyal
2013-09-10 22:57   ` Josh Boyer
2013-09-11 13:51     ` Vivek Goyal
2013-09-10 21:44 ` [PATCH 15/16] bootparam: Pass acpi_rsdp pointer in bootparam Vivek Goyal
2013-09-10 22:52   ` H. Peter Anvin
2013-09-11 11:44     ` Borislav Petkov
2013-09-11 13:45       ` Vivek Goyal
2013-09-11 14:32         ` Borislav Petkov
2013-09-12  7:34           ` Dave Young
2013-09-12 12:53             ` Borislav Petkov
     [not found]               ` <20130912131930.GC28500@redhat.com>
2013-09-12 14:25                 ` Borislav Petkov
2013-09-12 14:34               ` Matthew Garrett
2013-09-12 14:42                 ` Borislav Petkov
2013-09-13  7:12               ` Dave Young
2013-09-13 11:26                 ` Borislav Petkov
2013-09-10 21:44 ` [PATCH 16/16] mount: Add a flag to not follow symlink at the end of mount point Vivek Goyal
2013-09-12  3:40 ` [PATCH 00/16] [RFC PATCH] Signed kexec support Greg KH
2013-09-12 11:43   ` Vivek Goyal
2013-09-12 16:17     ` Greg KH
2013-09-12 18:24       ` Mimi Zohar
     [not found]         ` <20130916142852.GB20753@redhat.com>
2013-09-18 14:51           ` Andrea Adami
2013-09-23 17:15             ` Vivek Goyal
2013-09-16 14:24       ` Vivek Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1378849471-10521-11-git-send-email-vgoyal@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=d.kasatkin@samsung.com \
    --cc=ebiederm@xmission.com \
    --cc=hpa@zytor.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=matthew.garrett@nebula.com \
    --cc=zohar@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).