The following four patches add support for DSA keys to the in-kernel key
management system.
In-kernel dsa keys allows a process to use the request_key mechanism to
request such keys on demand. One such example is a backup script that,
when done, could issue a request for an appropriate ssh key. The request
would then be forwarded by /sbin/request-key to the appropriate user who
could supply the key which is in turn used by the backup script to transfer
the results to a backup server. This allows for much more flexible and
interesting solutions than passwordless ssh key files or shared ssh
agents would ever be able to support. (I have a separate patch for
openssh which allows ssh-add and ssh to work with in-kernel keys).
In addition, the in-kernel keys have the advantage of being non-ptraceable,
will not be swapped out to disk, and does not run the risk of being included
in coredumps. The functionality added by these patches should also be
interesting to some other security features (such as signed modules, signed
binaries and possibly some encrypted filesystems).
The patch is split into four sub-patches:
1) Adds a multi-precision-integer maths library
2) Adds dsa cryptographic operations. Since a dsa signature is always two
160-bit integer, I've modeled the dsa crypto as a hash algorithm.
3) Adds encryption as one of the supported ops for in-kernel keys.
4) Adds the dsa in-kernel key type.
This is the second version of these patches with the following changes from
the first version:
* Make sure all functions have proper dsa_ prefixes
* Use kenter/kleave/kdebug in dsa_key.c instead of duplicated versions
* Let key type decide which locking to use for encrypt ops (semaphore or rcu)
* Add KERN_XXX levels for printk's
* Merge newer mpilib from Fedora kernel 2.6.15-1.1871_FC5
* Change some non-tab whitespace to tabs
* Change mpilib exports from EXPORT_SYMBOL to EXPORT_SYMBOL_GPL
* Change crypto/dsa.c to copy key instead of referencing it
* Add documentation
Regards,
David Härdeman
--
Documentation/keys.txt | 77 +
crypto/Kconfig | 15
crypto/Makefile | 2
crypto/dsa.c | 265 ++++++
crypto/mpi/Makefile | 31
crypto/mpi/generic_mpi-asm-defs.h | 10
crypto/mpi/generic_mpih-add1.c | 64 +
crypto/mpi/generic_mpih-lshift.c | 66 +
crypto/mpi/generic_mpih-mul1.c | 60 +
crypto/mpi/generic_mpih-mul2.c | 63 +
crypto/mpi/generic_mpih-mul3.c | 64 +
crypto/mpi/generic_mpih-rshift.c | 66 +
crypto/mpi/generic_mpih-sub1.c | 63 +
crypto/mpi/generic_udiv-w-sdiv.c | 108 ++
crypto/mpi/longlong.h | 1502 ++++++++++++++++++++++++++++++++++++++
crypto/mpi/mpi-add.c | 241 ++++++
crypto/mpi/mpi-bit.c | 240 ++++++
crypto/mpi/mpi-cmp.c | 70 +
crypto/mpi/mpi-div.c | 342 ++++++++
crypto/mpi/mpi-gcd.c | 62 +
crypto/mpi/mpi-inline.c | 32
crypto/mpi/mpi-inline.h | 128 +++
crypto/mpi/mpi-internal.h | 265 ++++++
crypto/mpi/mpi-inv.c | 189 ++++
crypto/mpi/mpi-mpow.c | 136 +++
crypto/mpi/mpi-mul.c | 199 +++++
crypto/mpi/mpi-pow.c | 324 ++++++++
crypto/mpi/mpi-scan.c | 127 +++
crypto/mpi/mpicoder.c | 388 +++++++++
crypto/mpi/mpih-cmp.c | 58 +
crypto/mpi/mpih-div.c | 545 +++++++++++++
crypto/mpi/mpih-mul.c | 537 +++++++++++++
crypto/mpi/mpiutil.c | 224 +++++
include/linux/compat.h | 4
include/linux/dsa.h | 33
include/linux/key.h | 10
include/linux/keyctl.h | 1
include/linux/mpi.h | 154 +++
include/linux/syscalls.h | 5
security/Kconfig | 8
security/keys/Makefile | 1
security/keys/compat.c | 9
security/keys/dsa_key.c | 376 +++++++++
security/keys/keyctl.c | 67 +
44 files changed, 7221 insertions(+), 10 deletions(-)
Adds the multi-precision-integer maths library which was originally taken
from GnuPG and ported to the kernel by (among others) David Howells.
This version is taken from Fedora kernel 2.6.15-1.1871_FC5.
Signed-off-by: David Härdeman <[email protected]>
The patch is too large for LKML, so it's available at:
http://www.hardeman.nu/~david/lkml/01-add-mpilib
Adds the dsa in-kernel key type.
Signed-off-by: David Härdeman <[email protected]>
--
Index: dsa-kernel/security/Kconfig
===================================================================
--- dsa-kernel.orig/security/Kconfig 2006-01-25 23:39:10.000000000 +0100
+++ dsa-kernel/security/Kconfig 2006-01-25 23:42:31.000000000 +0100
@@ -21,6 +21,14 @@
If you are unsure as to whether this is required, answer N.
+config KEYS_DSA_KEYS
+ tristate "Support DSA keys (EXPERIMENTAL)"
+ depends on KEYS && EXPERIMENTAL
+ select CRYPTO_MPILIB
+ select CRYPTO_DSA
+ help
+ This option provides support for retaining DSA keys in the kernel.
+
config KEYS_DEBUG_PROC_KEYS
bool "Enable the /proc/keys file by which all keys may be viewed"
depends on KEYS
Index: dsa-kernel/security/keys/Makefile
===================================================================
--- dsa-kernel.orig/security/keys/Makefile 2006-01-25 23:39:10.000000000 +0100
+++ dsa-kernel/security/keys/Makefile 2006-01-25 23:42:31.000000000 +0100
@@ -13,4 +13,5 @@
user_defined.o
obj-$(CONFIG_KEYS_COMPAT) += compat.o
+obj-$(CONFIG_KEYS_DSA_KEYS) += dsa_key.o
obj-$(CONFIG_PROC_FS) += proc.o
Index: dsa-kernel/security/keys/dsa_key.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dsa-kernel/security/keys/dsa_key.c 2006-01-25 23:49:20.000000000 +0100
@@ -0,0 +1,376 @@
+/* dsa_key.c: DSA key
+ *
+ * Copyright (C) 2005 David Härdeman ([email protected]). All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+#include <asm/uaccess.h>
+#include <linux/mpi.h>
+#include <linux/dsa.h>
+#include <linux/random.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <keys/user-type.h>
+#include "internal.h"
+
+static int dsa_instantiate(struct key *key, const void *data, size_t datalen);
+static int dsa_update(struct key *key, const void *data, size_t datalen);
+static void dsa_destroy(struct key *key);
+static long dsa_read(const struct key *key,
+ char __user *buffer, size_t buflen);
+static long dsa_encrypt(struct key *key,
+ const char __user *data, size_t dlen,
+ char __user *result, size_t rlen);
+
+static struct key_type key_type_dsa = {
+ .name = "dsa",
+ .instantiate = dsa_instantiate,
+ .update = dsa_update,
+ .destroy = dsa_destroy,
+ .read = dsa_read,
+ .encrypt = dsa_encrypt,
+ .match = user_match,
+ .describe = user_describe,
+};
+
+/*****************************************************************************/
+/*
+ * Signs a chunk of data using key.
+ * Returns: signature.
+ */
+static char *
+dsa_sign(const struct key_payload_dsa *skey,
+ const void *data, size_t datalen, unsigned int *rlen)
+{
+ struct crypto_tfm *tfm;
+ char *ret = NULL;
+ u8 *sig;
+ unsigned int sigsize;
+ int i;
+ struct scatterlist sg[1];
+
+ kenter("%p, %p, %zu", skey, data, datalen);
+ tfm = crypto_alloc_tfm("dsa", 0);
+ if (!tfm)
+ goto out;
+
+ sigsize = crypto_tfm_alg_digestsize(tfm);
+ sig = kmalloc(sigsize, GFP_KERNEL);
+ if (!sig)
+ goto out_tfm;
+
+ crypto_digest_init(tfm);
+ i = crypto_digest_setkey(tfm, (const u8 *)skey, sizeof(skey));
+ if (i) {
+ printk(KERN_ERR "dsa-key: crypto_digest_setkey failed with error %i\n", i);
+ goto out_sig;
+ }
+
+ sg_init_one(sg, (u8 *)data, datalen);
+ crypto_digest_update(tfm, sg, 1);
+ crypto_digest_final(tfm, sig);
+ ret = sig;
+ *rlen = sigsize;
+ goto out_tfm;
+
+out_sig:
+ kfree(sig);
+out_tfm:
+ crypto_free_tfm(tfm);
+out:
+ return ret;
+} /* end dsa_sign() */
+
+/*****************************************************************************/
+/*
+ * Test whether the secret key is valid.
+ * Returns: if this is a valid key.
+ */
+static int dsa_check_secret_key(struct key_payload_dsa *skey)
+{
+ int rc;
+ MPI y;
+
+ /* y = g^x mod p */
+ kenter("%p", skey);
+ y = mpi_alloc(mpi_get_nlimbs(skey->part[DSA_PART_Y]));
+ rc = mpi_powm(y, skey->part[DSA_PART_G], skey->part[DSA_PART_X], skey->part[DSA_PART_P]);
+ rc = !mpi_cmp(y, skey->part[DSA_PART_Y]);
+
+ mpi_free(y);
+ return rc;
+} /* end dsa_check_secret_key() */
+
+/*****************************************************************************/
+/*
+ * create a dsa key payload
+ */
+static int dsa_create_payload(struct key_payload_dsa **payload, struct key *key,
+ const void *data, size_t datalen)
+{
+ int ret, i;
+ unsigned int remain, read;
+ const unsigned char *ptr;
+
+ kenter("%p, %p, %p, %zu", *payload, key, data, datalen);
+ ret = -EINVAL;
+ if (datalen <= 0 || datalen > 32767 || !data)
+ goto out1;
+
+ ret = -ENOMEM;
+ *payload = kmalloc(sizeof(struct key_payload_dsa), GFP_KERNEL);
+ if (!(*payload))
+ goto out1;
+
+ ret = key_payload_reserve(key, datalen);
+ if (ret < 0)
+ goto out2;
+
+ /* read each mpi number from buffer */
+ remain = read = (unsigned int)datalen;
+ ptr = data;
+ ret = 0;
+ for (i = 0; i < DSA_PARTS; i++) {
+ kdebug("dsa-key: in loop %i, remain is %u\n", i, remain);
+ (*payload)->part[i] = mpi_read_from_buffer(ptr, &read);
+ if (!((*payload)->part[i]))
+ ret = -EINVAL;
+ ptr += read;
+ remain -= read;
+ read = remain;
+ kdebug("dsa-key: end loop\n");
+ }
+
+ if (ret < 0)
+ goto out3;
+
+ /* check validity */
+ ret = -EINVAL;
+ if(dsa_check_secret_key(*payload)) {
+ ret = 0;
+ kdebug("dsa-key: valid\n");
+ goto out1;
+ }
+
+out3:
+ printk(KERN_ERR "dsa-key: attempt to add invalid key\n");
+ for (i = 0; i < DSA_PARTS; i++)
+ mpi_free((*payload)->part[i]);
+out2:
+ kfree(*payload);
+out1:
+ return ret;
+
+} /* end dsa_instantiate() */
+
+/*****************************************************************************/
+/*
+ * instantiate a dsa key
+ */
+static int dsa_instantiate(struct key *key, const void *data, size_t datalen)
+{
+ struct key_payload_dsa *dsa_key;
+ int ret;
+
+ kenter("%p, %p, %zu", key, data, datalen);
+ ret = dsa_create_payload(&dsa_key, key, data, datalen);
+ if (ret == 0)
+ key->payload.data = dsa_key;
+
+ return ret;
+
+} /* end dsa_instantiate() */
+
+/*****************************************************************************/
+/*
+ * update a user defined key
+ */
+static int dsa_update(struct key *key, const void *data, size_t datalen)
+{
+ struct key_payload_dsa *new_payload;
+ int ret;
+
+ kenter("%p, %p, %zu", key, data, datalen);
+ ret = dsa_create_payload(&new_payload, key, data, datalen);
+ if (ret == 0) {
+ kdebug("dsa: dsa_create_payload success\n");
+ down_write(&key->sem);
+ /* this destroys the old payload, not the entire key */
+ dsa_destroy(key);
+ key->payload.data = new_payload;
+ key->expiry = 0;
+ up_write(&key->sem);
+ }
+
+ return ret;
+
+} /* end dsa_update() */
+
+/*****************************************************************************/
+/*
+ * dispose of the key payload
+ */
+static void dsa_destroy(struct key *key)
+{
+ struct key_payload_dsa *dsa_key;
+ int i;
+
+ kenter("%p", key);
+ dsa_key = key->payload.data;
+ if (dsa_key) {
+ for (i = 0; i < DSA_PARTS; i++)
+ mpi_free(dsa_key->part[i]);
+ kfree(dsa_key);
+ }
+
+} /* end dsa_destroy() */
+
+/*****************************************************************************/
+/*
+ * read the key data
+ */
+static long dsa_read(const struct key *key, char __user *buffer, size_t buflen)
+{
+ unsigned char *xbuffer[DSA_PUBLIC_PARTS];
+ unsigned nbytes[DSA_PUBLIC_PARTS];
+ unsigned nbits[DSA_PUBLIC_PARTS];
+ struct key_payload_dsa *dsa_key;
+ int i;
+ char *result, *tmp;
+ size_t reslen;
+ long ret;
+
+ kenter("%p, %p, %zu", key, buffer, buflen);
+ ret = -EINVAL;
+ dsa_key = (struct key_payload_dsa *)key->payload.data;
+ if (!dsa_key)
+ goto out1;
+
+ /* 4 x 2 bytes to store mpi sizes */
+ reslen = 8;
+ memset(xbuffer, 0, sizeof(xbuffer));
+ ret = -ENOMEM;
+
+ for (i = 0; i < DSA_PUBLIC_PARTS; i++) {
+ xbuffer[i] = mpi_get_buffer(dsa_key->part[i], &nbytes[i], NULL);
+ if (!xbuffer[i]) {
+ printk(KERN_ERR "dsa-key: failed to get mpi from buffer\n");
+ goto out2;
+ }
+ reslen += nbytes[i];
+ nbits[i] = mpi_get_nbits(dsa_key->part[i]);
+ }
+
+ result = kmalloc(reslen, GFP_KERNEL);
+ if (!result)
+ goto out2;
+
+ tmp = result;
+ for (i = 0; i < DSA_PUBLIC_PARTS; i++) {
+ kdebug("dsa-key: checking part %i\n", i);
+ kdebug("dsa-key: nbytes is %i, nbits is %i, topbyte is %2hx, botbyte is %2hx\n",
+ nbytes[i], nbits[i], ((nbits[i] >> 8) & 0xff), ((nbits[i]) & 0xff));
+ MPI_WSIZE(tmp, nbits[i]);
+ memcpy(tmp, xbuffer[i], nbytes[i]);
+ tmp += nbytes[i];
+ }
+
+ ret = -EFAULT;
+ if (copy_to_user(buffer, result, min(reslen, buflen)) == 0)
+ ret = reslen;
+
+ memset(result, 0, reslen);
+ kfree(result);
+
+out2:
+ for (i = 0; i < DSA_PUBLIC_PARTS; i++) {
+ memset(xbuffer[i], 0, nbytes[i]);
+ kfree(xbuffer[i]);
+ }
+out1:
+ return ret;
+
+} /* end dsa_read() */
+
+/*****************************************************************************/
+/*
+ * encrypt data using a key
+ */
+static long dsa_encrypt(struct key *key,
+ const char __user *data, size_t dlen,
+ char __user *result, size_t rlen)
+{
+ char *signature;
+ char *inbuf;
+ long ret;
+ size_t siglen = 0;
+
+ kenter("%p, %p, %zu, %p, %zu", key, data, dlen, result, rlen);
+ down_read(&key->sem);
+ ret = -ENOMEM;
+ inbuf = kmalloc(dlen, GFP_KERNEL);
+ if (!inbuf)
+ goto out1;
+
+ ret = -EFAULT;
+ /* pull the data to sign into kernel space */
+ if (copy_from_user(inbuf, data, dlen))
+ goto out2;
+
+ /* sign it */
+ signature = dsa_sign((struct key_payload_dsa *)key->payload.data,
+ inbuf, dlen, &siglen);
+ if (!signature)
+ goto out2;
+
+ /* push the result to userspace */
+ if(copy_to_user(result, signature, min(rlen, siglen)) == 0)
+ ret = siglen;
+
+ memset(signature, 0, siglen);
+ kfree(signature);
+out2:
+ memset(inbuf, 0, dlen);
+ kfree(inbuf);
+out1:
+ up_read(&key->sem);
+ return ret;
+} /* end dsa_encrypt() */
+
+static int __init dsa_init(void)
+{
+ int ret;
+
+ ret = register_key_type(&key_type_dsa);
+ if (ret < 0)
+ printk(KERN_ERR "dsa-key: failed to register key type\n");
+ else
+ printk(KERN_INFO "dsa-key: new key type registered\n");
+
+ return ret;
+}
+
+static void __exit dsa_exit (void)
+{
+ printk(KERN_INFO "dsa-key: unregistering key type\n");
+ unregister_key_type(&key_type_dsa);
+}
+
+module_init(dsa_init);
+module_exit(dsa_exit);
+
+MODULE_AUTHOR("David Härdeman");
+MODULE_DESCRIPTION("DSA key support");
+MODULE_LICENSE("GPL");
Adds encryption as one of the supported ops for in-kernel keys.
Signed-off-by: David Härdeman <[email protected]>
--
Index: dsa-kernel/include/linux/compat.h
===================================================================
--- dsa-kernel.orig/include/linux/compat.h 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/include/linux/compat.h 2006-01-25 23:26:51.000000000 +0100
@@ -132,8 +132,8 @@
long compat_sys_shmctl(int first, int second, void __user *uptr);
long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
unsigned nsems, const struct compat_timespec __user *timeout);
-asmlinkage long compat_sys_keyctl(u32 option,
- u32 arg2, u32 arg3, u32 arg4, u32 arg5);
+asmlinkage long compat_sys_keyctl(u32 option, u32 arg2, u32 arg3,
+ u32 arg4, u32 arg5, u32 arg6);
asmlinkage ssize_t compat_sys_readv(unsigned long fd,
const struct compat_iovec __user *vec, unsigned long vlen);
Index: dsa-kernel/include/linux/key.h
===================================================================
--- dsa-kernel.orig/include/linux/key.h 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/include/linux/key.h 2006-01-25 23:40:12.000000000 +0100
@@ -220,6 +220,16 @@
*/
long (*read)(const struct key *key, char __user *buffer, size_t buflen);
+ /* encrypt/sign/etc data using a key (optional)
+ * - permission checks will be done by the caller
+ * - the key must be readlocked while encryption is performed
+ * - should return the amount of data that would be returned from the
+ * encryption even if the buffer is too small or NULL
+ */
+ long (*encrypt)(struct key *key,
+ const char __user *inbuffer, size_t inbuflen,
+ char __user *outbuffer, size_t outbuflen);
+
/* handle request_key() for this type instead of invoking
* /sbin/request-key (optional)
* - key is the key to instantiate
Index: dsa-kernel/include/linux/keyctl.h
===================================================================
--- dsa-kernel.orig/include/linux/keyctl.h 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/include/linux/keyctl.h 2006-01-25 23:26:51.000000000 +0100
@@ -49,5 +49,6 @@
#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */
#define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */
+#define KEYCTL_ENCRYPT 17 /* encrypt a chunk of data using key */
#endif /* _LINUX_KEYCTL_H */
Index: dsa-kernel/include/linux/syscalls.h
===================================================================
--- dsa-kernel.orig/include/linux/syscalls.h 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/include/linux/syscalls.h 2006-01-25 23:26:51.000000000 +0100
@@ -504,8 +504,9 @@
const char __user *_callout_info,
key_serial_t destringid);
-asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5);
+asmlinkage long sys_keyctl(int cmd, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5, unsigned long arg6);
asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
asmlinkage long sys_ioprio_get(int which, int who);
Index: dsa-kernel/security/keys/compat.c
===================================================================
--- dsa-kernel.orig/security/keys/compat.c 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/security/keys/compat.c 2006-01-25 23:26:51.000000000 +0100
@@ -23,8 +23,8 @@
* registers on taking a 32-bit syscall are zero
* - if you can, you should call sys_keyctl directly
*/
-asmlinkage long compat_sys_keyctl(u32 option,
- u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+asmlinkage long compat_sys_keyctl(u32 option, u32 arg2, u32 arg3,
+ u32 arg4, u32 arg5, u32 arg6)
{
switch (option) {
case KEYCTL_GET_KEYRING_ID:
@@ -80,6 +80,11 @@
case KEYCTL_ASSUME_AUTHORITY:
return keyctl_assume_authority(arg2);
+ case KEYCTL_ENCRYPT:
+ return keyctl_encrypt_with_key(arg2,
+ compat_ptr(arg3), arg4,
+ compat_ptr(arg5), arg6);
+
default:
return -EOPNOTSUPP;
}
Index: dsa-kernel/security/keys/keyctl.c
===================================================================
--- dsa-kernel.orig/security/keys/keyctl.c 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/security/keys/keyctl.c 2006-01-25 23:42:11.000000000 +0100
@@ -1066,10 +1066,66 @@
/*****************************************************************************/
/*
+ * encrypt a chunk of data using a specified key
+ * - implements keyctl(KEYCTL_ENCRYPT)
+ */
+long keyctl_encrypt_with_key(key_serial_t keyid,
+ const void __user *data,
+ size_t dlen,
+ void __user *result,
+ size_t rlen)
+{
+ struct key *key;
+ key_ref_t key_ref;
+ long ret;
+
+ /* find the key first */
+ key_ref = lookup_user_key(NULL, keyid, 0, 0, 0);
+ if (IS_ERR(key_ref)) {
+ ret = -ENOKEY;
+ goto error;
+ }
+
+ key = key_ref_to_ptr(key_ref);
+
+ /* see if we can read it directly */
+ ret = key_permission(key_ref, KEY_READ);
+ if (ret == 0)
+ goto can_read_key;
+ if (ret != -EACCES)
+ goto error;
+
+ /* we can't; see if it's searchable from this process's keyrings
+ * - we automatically take account of the fact that it may be
+ * dangling off an instantiation key
+ */
+ if (!is_key_possessed(key_ref)) {
+ ret = -EACCES;
+ goto error2;
+ }
+
+ /* the key is probably readable - now try to read it */
+ can_read_key:
+ ret = key_validate(key);
+ if (ret == 0) {
+ ret = -EOPNOTSUPP;
+ if (key->type->encrypt)
+ ret = key->type->encrypt(key, data, dlen, result, rlen);
+ }
+
+ error2:
+ key_put(key);
+ error:
+ return ret;
+} /* end keyctl_encrypt_with_key() */
+
+/*****************************************************************************/
+/*
* the key control system call
*/
-asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5)
+asmlinkage long sys_keyctl(int option, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5, unsigned long arg6)
{
switch (option) {
case KEYCTL_GET_KEYRING_ID:
@@ -1144,6 +1200,13 @@
case KEYCTL_ASSUME_AUTHORITY:
return keyctl_assume_authority((key_serial_t) arg2);
+ case KEYCTL_ENCRYPT:
+ return keyctl_encrypt_with_key((key_serial_t) arg2,
+ (const char __user *) arg3,
+ (size_t) arg4,
+ (char __user *) arg5,
+ (size_t) arg6);
+
default:
return -EOPNOTSUPP;
}
Index: dsa-kernel/Documentation/keys.txt
===================================================================
--- dsa-kernel.orig/Documentation/keys.txt 2006-01-25 23:26:43.000000000 +0100
+++ dsa-kernel/Documentation/keys.txt 2006-01-25 23:26:51.000000000 +0100
@@ -90,6 +90,9 @@
permitted, another key type operation will be called to convert the key's
attached payload back into a blob of data.
+ Additionally, if supported by the key type, an arbitrary blob of data can
+ be encrypted/signed using the key payload.
+
(*) Each key can be in one of a number of basic states:
(*) Uninstantiated. The key exists, but does not have any data attached.
@@ -206,7 +209,8 @@
(*) Read
This permits a key's payload to be viewed or a keyring's list of linked
- keys.
+ keys. It also allows a blob of data to be encrypted/signed using the key's
+ payload if implemented for the given key type.
(*) Write
@@ -669,6 +673,27 @@
The assumed authorititive key is inherited across fork and exec.
+ (*) Encrypt/sign some arbitrary data using a key:
+
+ long keyctl(KEYCTL_READ, key_serial_t key,
+ char *inputbuf, size_t inputbuflen,
+ char *outputbuf, size_t outputbuflen);
+
+ This function attempts to read the data in inputbuf from userspace
+ and then performs a key-type specific operation on that data using
+ the payload from the specified key. Normally the operation would be
+ to encrypt or sign the data and to return the result in outputbuf.
+
+ If a key type does not implement this function, error EOPNOTSUPP
+ will result.
+
+ As much of the data as can be fitted into the buffer will be copied to
+ userspace if the buffer pointer is not NULL.
+
+ On a successful return, the function will always return the amount of data
+ available rather than the amount copied to outputbuf.
+
+
===============
KERNEL SERVICES
===============
@@ -979,6 +1004,20 @@
as might happen when the userspace buffer is accessed.
+ (*) long (*encrypt)(const struct key *key,
+ char __user *inbuffer, size_t inbuflen,
+ char __user *outbuffer, size_t outbuflen);
+
+ This method is optional. It is called by KEYCTL_ENCRYPT to perform some
+ kind of cryptographic operation (usually encrypt or sign) on the data
+ in inbuffer using the key's payload. The result is returned to outbuffer.
+
+ If successful, the blob size that could be produced should be returned
+ rather than the size copied.
+
+ It is safe to sleep in this method.
+
+
============================
REQUEST-KEY CALLBACK SERVICE
============================
@@ -1027,3 +1066,39 @@
In this case, the program isn't required to actually attach the key to a ring;
the rings are provided for reference.
+
+=============================
+KEY-TYPE SPECIFIC INFORMATION
+=============================
+
+ (*) DSA keys
+
+ The blob used to instantiate a DSA key is expected to be in a certain
+ format:
+
+ Each multi-precision integer (MPI) is preceeded by a 2-byte,
+ most-significant-byte-first, integer which defines the number of bits
+ (nbits) of the MPI which follows. The MPI is then written, also in msb
+ order, with the lowest number of bytes which can contain the entire number
+ (i.e, the MPI is coded in the following (nbits + 7) / 8 bytes).
+
+ For example, the integer 0xf865349f would be coded as
+ char buf[] = {'0x00', '0x20', '0xf8', '0x65', '0x34', '0x9f'};
+
+ This is the same encoding used by the MPI library in GnuPG for passing
+ large integers via buffers.
+
+ When a key is instantiated, the DSA key type expects to find five MPI's
+ coded according to the above scheme in the buffer. These must be in the
+ order: P,Q,G,Y,X (see the DSA specification, FIPS-186, for details).
+
+ When a key is read, only the public part of the key is written to the buf
+ i.e: P,Q,G,Y.
+
+ When some data is signed using a key (via the encrypt method), the two
+ 160-bit integers r and s (the two integers which make up the signature
+ in FIPS-186 terms) are written to the output buffer using the above
+ encoding yielding 44 bytes of data.
+
+ (2 * 20 bytes + 2 * 2 bytes of header data = 44 byte)
+
Adds dsa cryptographic operations. Since a dsa signature is always two
160-bit integer, the dsa crypto has been modeled as a hash algorithm.
Signed-off-by: David Härdeman <[email protected]>
--
Index: dsa-kernel/crypto/Kconfig
===================================================================
--- dsa-kernel.orig/crypto/Kconfig 2006-01-25 20:40:03.000000000 +0100
+++ dsa-kernel/crypto/Kconfig 2006-01-25 20:46:45.000000000 +0100
@@ -342,6 +342,13 @@
Multiprecision maths library from GnuPG. Used for some
crypto algorithms.
+config CRYPTO_DSA
+ tristate "Digital Signature Algorithm (EXPERIMENTAL)"
+ depends on CRYPTO && CRYPTO_MPILIB && EXPERIMENTAL
+ help
+ Digital Signature Algorithm is used in a number of applications
+ such as ssh and gpg.
+
config CRYPTO_TEST
tristate "Testing module"
depends on CRYPTO
Index: dsa-kernel/crypto/Makefile
===================================================================
--- dsa-kernel.orig/crypto/Makefile 2006-01-25 20:40:03.000000000 +0100
+++ dsa-kernel/crypto/Makefile 2006-01-25 20:46:45.000000000 +0100
@@ -30,6 +30,7 @@
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
+obj-$(CONFIG_CRYPTO_DSA) += dsa.o
obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
Index: dsa-kernel/crypto/dsa.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dsa-kernel/crypto/dsa.c 2006-01-25 23:26:19.000000000 +0100
@@ -0,0 +1,265 @@
+/*
+ * DSA Digital Signature Algorithm (FIPS-186).
+ *
+ * Copyright (c) 2005 David Härdeman <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mpi.h>
+#include <linux/dsa.h>
+#include <linux/random.h>
+#include "../security/keys/internal.h"
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+
+#if 0
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...) do { } while(0)
+#endif
+
+/****************
+ * Generate a random secret exponent k less than q
+ */
+static MPI
+dsa_gen_k(MPI q)
+{
+ MPI k = mpi_alloc(mpi_get_nlimbs(q));
+ unsigned int nbits = mpi_get_nbits(q);
+ unsigned int nbytes = (nbits + 7)/8;
+ char *rndbuf = NULL;
+
+ dprintk("dsa: choosing a random k\n");
+
+ while(1) {
+ if (!rndbuf) {
+ rndbuf = kmalloc(nbytes, GFP_KERNEL);
+ if (!rndbuf) {
+ printk(KERN_ERR "dsa: failed to create buffer\n");
+ return NULL;
+ }
+ get_random_bytes(rndbuf, nbytes);
+ } else {
+ /* change only some of the higher bits */
+ get_random_bytes(rndbuf, min(nbytes, (unsigned int)4));
+ }
+
+ mpi_set_buffer(k, rndbuf, nbytes, 0);
+ if(mpi_test_bit( k, nbits - 1)) {
+ mpi_set_highbit(k, nbits - 1);
+ } else {
+ mpi_set_highbit(k, nbits - 1);
+ mpi_clear_bit(k, nbits - 1);
+ }
+
+ /* check: k < q */
+ if(!(mpi_cmp(k, q) < 0))
+ continue;
+
+ /* check: k > 0 */
+ if(!(mpi_cmp_ui(k, 0) > 0))
+ continue;
+
+ /* okay */
+ break;
+ }
+
+ kfree(rndbuf);
+ return k;
+}
+
+static void
+dsa_sign_hash(MPI r, MPI s, MPI hash, struct key_payload_dsa *skey)
+{
+ MPI k, kinv, tmp;
+
+ /* select a random k with 0 < k < q */
+ k = dsa_gen_k(skey->part[DSA_PART_Q]);
+ if (!k) {
+ printk(KERN_ERR "dsa: failed to create buffer\n");
+ return;
+ }
+
+ /* r = (g^k mod p) mod q */
+ mpi_powm(r, skey->part[DSA_PART_G], k, skey->part[DSA_PART_P]);
+ mpi_fdiv_r(r, r, skey->part[DSA_PART_Q]);
+
+ /* kinv = k^(-1) mod q */
+ kinv = mpi_alloc(mpi_get_nlimbs(k));
+ mpi_invm(kinv, k, skey->part[DSA_PART_Q]);
+
+ /* s = (kinv * ( hash + x * r)) mod q */
+ tmp = mpi_alloc(mpi_get_nlimbs(skey->part[DSA_PART_P]));
+ mpi_mul(tmp, skey->part[DSA_PART_X], r);
+ mpi_add(tmp, tmp, hash);
+ mpi_mulm(s , kinv, tmp, skey->part[DSA_PART_Q]);
+
+ mpi_free(k);
+ mpi_free(kinv);
+ mpi_free(tmp);
+}
+
+struct dsa_ctx {
+ struct crypto_tfm *sha1;
+ struct key_payload_dsa *key;
+};
+
+static int dsa_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ struct dsa_ctx *dctx = ctx;
+ struct key_payload_dsa *dkey, *skey = (struct key_payload_dsa *)key;
+ int i, ret;
+
+ ret = -EINVAL;
+ if (keylen != sizeof(struct key_payload_dsa *)) {
+ printk(KERN_ERR "dsa: invalid key size in dsa_setkey\n");
+ goto out;
+ }
+
+ /* Make a copy of the key in case it later disappears */
+ ret = -ENOMEM;
+ dctx->key = kmalloc(sizeof(struct key_payload_dsa), GFP_KERNEL);
+ if (!dctx->key) {
+ printk(KERN_ERR "dsa: failed to allocate memory for key\n");
+ goto out;
+ }
+ dkey = dctx->key;
+
+ ret = 0;
+ for (i = 0; i < DSA_PARTS; i++)
+ if (mpi_copy(&dkey->part[i], skey->part[i]))
+ ret = -ENOMEM;
+
+ if (ret) {
+ for (i = 0; i < DSA_PARTS; i++)
+ mpi_free(dkey->part[i]);
+ kfree(dkey);
+ }
+
+out:
+ return ret;
+}
+
+static void dsa_init(void *ctx)
+{
+ struct dsa_ctx *dctx = ctx;
+
+ dctx->key = NULL;
+ dctx->sha1 = crypto_alloc_tfm("sha1", 0);
+ if (!dctx->sha1)
+ printk(KERN_ERR "dsa_init: failed to allocate sha1 tfm\n");
+ else
+ crypto_digest_init(dctx->sha1);
+}
+
+static void dsa_update(void *ctx, const u8 *data, unsigned int dlen)
+{
+ struct scatterlist sg[1];
+ struct dsa_ctx *dctx = ctx;
+
+ if (!dctx->sha1)
+ return;
+
+ sg_init_one(sg, (u8 *)data, dlen);
+ crypto_digest_update(dctx->sha1, sg, 1);
+}
+
+static void dsa_final(void *ctx, u8 *out)
+{
+ struct dsa_ctx *dctx = ctx;
+ unsigned int dsize = crypto_tfm_alg_digestsize(dctx->sha1);
+ u8 buffer[dsize];
+ MPI hash, r, s;
+ u8 *outp = out;
+ unsigned int rbytes, rbits, sbytes, sbits;
+ char *rbuf, *sbuf;
+ int i;
+
+ if (!dctx->sha1)
+ return;
+
+ crypto_digest_final(dctx->sha1, buffer);
+ crypto_free_tfm(dctx->sha1);
+ dctx->sha1 = NULL;
+
+ hash = mpi_alloc(1);
+ r = mpi_alloc(1);
+ s = mpi_alloc(1);
+ if (!hash || !r || !s) {
+ printk(KERN_ERR "dsa: failed to allocate mpis\n");
+ goto out1;
+ }
+
+ mpi_set_buffer(hash, buffer, dsize, 0);
+ dsa_sign_hash(r, s, hash, dctx->key);
+ rbuf = mpi_get_buffer(r, &rbytes, NULL);
+ sbuf = mpi_get_buffer(s, &sbytes, NULL);
+ if (!rbuf || !sbuf) {
+ printk(KERN_ERR "dsa: failed to allocate buffers\n");
+ goto out2;
+ }
+
+ rbits = mpi_get_nbits(r);
+ MPI_WSIZE(outp, rbits);
+ memcpy(outp, rbuf, rbytes);
+ outp += rbytes;
+
+ sbits = mpi_get_nbits(s);
+ MPI_WSIZE(outp, sbits);
+ memcpy(outp, sbuf, sbytes);
+
+out2:
+ kfree(rbuf);
+ kfree(sbuf);
+out1:
+ mpi_free(hash);
+ mpi_free(r);
+ mpi_free(s);
+
+ for (i = 0; i < DSA_PARTS; i++)
+ mpi_free(dctx->key->part[i]);
+ kfree(dctx->key);
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "dsa",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = DSA_HMAC_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct dsa_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_u = { .digest = {
+ .dia_digestsize = DSA_DIGEST_SIZE,
+ .dia_init = dsa_init,
+ .dia_update = dsa_update,
+ .dia_final = dsa_final,
+ .dia_setkey = dsa_setkey } }
+};
+
+static int __init init(void)
+{
+ printk(KERN_INFO "Registering Digital Signature Algorithm crypto\n");
+ return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+ printk(KERN_INFO "Unregistering Digital Signature Algorithm crypto\n");
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("David Härdeman");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DSA Digital Signature Algorithm");
Index: dsa-kernel/include/linux/dsa.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dsa-kernel/include/linux/dsa.h 2006-01-25 20:46:45.000000000 +0100
@@ -0,0 +1,33 @@
+/* dsa.h: digital signature architecture
+ *
+ * Copyright (C) 2005 David Härdeman ([email protected]).
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_DSA_H
+#define _LINUX_DSA_H
+#ifdef __KERNEL__
+
+#include <linux/mpi.h>
+
+#define DSA_DIGEST_SIZE 44
+#define DSA_HMAC_BLOCK_SIZE 64
+#define DSA_PART_P 0
+#define DSA_PART_Q 1
+#define DSA_PART_G 2
+#define DSA_PART_Y 3
+#define DSA_PART_X 4
+#define DSA_PARTS 5
+#define DSA_PUBLIC_PARTS 4
+
+struct key_payload_dsa {
+ MPI part[DSA_PARTS]; /* p,q,g,y,x */
+};
+
+#endif
+#endif
David H?rdeman <[email protected]> wrote:
>
> crypto/mpi/Makefile | 31
Wouldn't this make more sense under lib/mpi?
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
On Fri, Jan 27, 2006 at 12:10:06PM +1100, Herbert Xu wrote:
>David H?rdeman <[email protected]> wrote:
>>
>> crypto/mpi/Makefile | 31
>
>Wouldn't this make more sense under lib/mpi?
I have no problems with moving it to lib/mpi unless someone feels its a
bad idea (DHowells, do you agree?).
Re,
David
On Thu, Jan 26, 2006 at 10:58:15PM +0100, David H?rdeman wrote:
>
> Adds the multi-precision-integer maths library which was originally taken
> from GnuPG and ported to the kernel by (among others) David Howells.
> This version is taken from Fedora kernel 2.6.15-1.1871_FC5.
This is ugly as hell. If we decided to add it it really needs a major
cleanup, fitting into linux style and removal of unused functionality,
the assembly bits needs to move to an asm/ header, etc.
But to be honest I'd say anything that requires bigints shouldn't go into
the kernel at all. Could someone explain why they want dsa support in
kernelspace?
Christoph Hellwig <[email protected]> wrote:
> This is ugly as hell. If we decided to add it it really needs a major
> cleanup, fitting into linux style and removal of unused functionality,
> the assembly bits needs to move to an asm/ header, etc.
Which would make it harder to compare against the original, and so potentially
harder to track bug fixes in the original was my thinking.
> But to be honest I'd say anything that requires bigints shouldn't go into
> the kernel at all. Could someone explain why they want dsa support in
> kernelspace?
Well... I'd like to revisit module signing at some point, though I imagine
it'll cause the LKML to melt again by those who think that I shouldn't have
the right to sign my modules because they imagine it impinges on their
rights:-) But I suspect the reason David wants this is so that he can encrypt
something with keys that he's not actually permitted to retrieve
directly. David?
David
David H?rdeman <[email protected]> wrote:
> I have no problems with moving it to lib/mpi unless someone feels its a bad
> idea (DHowells, do you agree?).
I don't think that's the right place for it, except for the fact you can then
use the archive library generated to only include as much of mpilib as you
actually require. It seems to me that it should really belong with the crypto
stuff.
David
On Fri, Jan 27, 2006 at 08:07:50PM +0000, David Howells wrote:
>Christoph Hellwig <[email protected]> wrote:
>
>> This is ugly as hell. If we decided to add it it really needs a major
>> cleanup, fitting into linux style and removal of unused functionality,
>> the assembly bits needs to move to an asm/ header, etc.
>
>Which would make it harder to compare against the original, and so potentially
>harder to track bug fixes in the original was my thinking.
I think it might still work quite well with a subset since each function
is quite self-contained and a bugfix in one function would still be
quite easy to match to the corresponding function in the in-kernel code
even if it has been refactored and moved around.
>> But to be honest I'd say anything that requires bigints shouldn't go into
>> the kernel at all. Could someone explain why they want dsa support in
>> kernelspace?
>
>Well... I'd like to revisit module signing at some point, though I imagine
>it'll cause the LKML to melt again by those who think that I shouldn't have
>the right to sign my modules because they imagine it impinges on their
>rights:-) But I suspect the reason David wants this is so that he can encrypt
>something with keys that he's not actually permitted to retrieve
>directly. David?
The reason that I wanted DSA-keys supported by the in-kernel key stuff
is that it allows for some cool stuff which is either impossible or very
hard to do otherwise.
For example, a backup daemon which wishes to store the backup on another
host using ssh. Usually this is solved by storing an unencrypted key in
the fs or by providing a connection to a ssh-agent which has been
preloaded with the proper key(s). Both are quite inelegant solutions.
With the in-kernel support, the daemon can request the key using the
request_key call, and (provided proper scripts are written), the user
who controls the relevant key can supply it. This in turn means that the
backup daemon can sign using the key and read its public parts but not
the private key.
So yes, that is one example of doing "something" with keys that the
process is not allowed to retrieve directly (the key itself could be
supplied from removable storage or something and given a few minutes of
time-to-live).
It also means that users would not have to run ssh-agent and would not
have to bother with making sure that only one instance of ssh-agent is
running even if they are logged in multiple times.
The in-kernel key management also protects the key against many of the
different ways in which a user-space daemon could be attacked (ptrace,
swap-out, coredump, etc).
In addition, the dsa key code can be used to implement signed binaries
and signed modules.
For now I'll create a version of mpilib which has been stripped down to
only the functions that are in use by the dsa-crypto stuff, hopefully
this will substantially reduce the size and amount of code. I'll get
back when I have some results.
Regards,
David
On Fri, 2006-01-27 at 21:41 +0100, David Härdeman wrote:
> For example, a backup daemon which wishes to store the backup on another
> host using ssh. Usually this is solved by storing an unencrypted key in
> the fs or by providing a connection to a ssh-agent which has been
> preloaded with the proper key(s). Both are quite inelegant solutions.
> With the in-kernel support, the daemon can request the key using the
> request_key call, and (provided proper scripts are written), the user
> who controls the relevant key can supply it. This in turn means that the
> backup daemon can sign using the key and read its public parts but not
> the private key.
...but why would you want such a daemon to live in the kernel in the
first place? A backup application might perhaps need some kernel support
in order to ensure filesystem consistency, but that does not mean that
moving the entire daemon into the kernel is a good idea.
Cheers,
Trond
On Fri, Jan 27, 2006 at 08:11:25PM +0000, David Howells wrote:
> David H?rdeman <[email protected]> wrote:
>
> > I have no problems with moving it to lib/mpi unless someone feels its a bad
> > idea (DHowells, do you agree?).
>
> I don't think that's the right place for it, except for the fact you can then
> use the archive library generated to only include as much of mpilib as you
> actually require. It seems to me that it should really belong with the crypto
> stuff.
IMHO crypto/ should only contain things that are actually part of the
crypto layer: API code and crypto_alg implementations.
We have precedents for this. We have the crypto_alg implementation of
sha1 in crypto, but the actual algorithm lives in lib. Ditto for crc
and zlib.
In this case, the MPI library is even further away from the crypto layer
than any of these cases since it is not a crypto algorithm by itself.
In fact, we can't be sure that there won't ever be another part of the
kernel that requires direct access to the MPI library without going
through the crypto layer.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
On Jan 27, 2006, at 17:19, Trond Myklebust wrote:
> On Fri, 2006-01-27 at 21:41 +0100, David H?rdeman wrote:
>
>> For example, a backup daemon which wishes to store the backup on
>> another host using ssh. Usually this is solved by storing an
>> unencrypted key in the fs or by providing a connection to a ssh-
>> agent which has been preloaded with the proper key(s). Both are
>> quite inelegant solutions. With the in-kernel support, the daemon
>> can request the key using the request_key call, and (provided
>> proper scripts are written), the user who controls the relevant
>> key can supply it. This in turn means that the backup daemon can
>> sign using the key and read its public parts but not the private key.
>
> ...but why would you want such a daemon to live in the kernel in
> the first place? A backup application might perhaps need some
> kernel support in order to ensure filesystem consistency, but that
> does not mean that moving the entire daemon into the kernel is a
> good idea.
No, the point is not to put the backup daemon into the kernel, but to
provide a way for the backup daemon and my user process to
communicate DSA key details without completely giving the backup
daemon my key. I may not entirely trust the backup daemon not to get
compromised, but with support for the kernel keyring system,
compromising the backup daemon would only compromise the backed up
files, not the private keys and other secure data.
Cheers,
Kyle Moffett
--
I lost interest in "blade servers" when I found they didn't throw
knives at people who weren't supposed to be in your machine room.
-- Anthony de Boer
On Fri, Jan 27, 2006 at 09:41:58PM +0100, David H?rdeman wrote:
> On Fri, Jan 27, 2006 at 08:07:50PM +0000, David Howells wrote:
>...
> >Well... I'd like to revisit module signing at some point, though I imagine
> >it'll cause the LKML to melt again by those who think that I shouldn't have
> >the right to sign my modules because they imagine it impinges on their
> >rights:-) But I suspect the reason David wants this is so that he can
> >encrypt
> >something with keys that he's not actually permitted to retrieve
> >directly. David?
>
> The reason that I wanted DSA-keys supported by the in-kernel key stuff
> is that it allows for some cool stuff which is either impossible or very
> hard to do otherwise.
>
> For example, a backup daemon which wishes to store the backup on another
> host using ssh. Usually this is solved by storing an unencrypted key in
> the fs or by providing a connection to a ssh-agent which has been
> preloaded with the proper key(s). Both are quite inelegant solutions.
> With the in-kernel support, the daemon can request the key using the
> request_key call, and (provided proper scripts are written), the user
> who controls the relevant key can supply it. This in turn means that the
> backup daemon can sign using the key and read its public parts but not
> the private key.
What exactly is the unsolvable problem with doing this in userspace?
> So yes, that is one example of doing "something" with keys that the
> process is not allowed to retrieve directly (the key itself could be
> supplied from removable storage or something and given a few minutes of
> time-to-live).
>
> It also means that users would not have to run ssh-agent and would not
> have to bother with making sure that only one instance of ssh-agent is
> running even if they are logged in multiple times.
>
> The in-kernel key management also protects the key against many of the
> different ways in which a user-space daemon could be attacked (ptrace,
> swap-out, coredump, etc).
If an attacker has enough privileges for attacking the daemon, he should
usually also have enough privileges for attacking the kernel.
The number of different attacks might be lower, but you haven't
completely solved any problem.
> In addition, the dsa key code can be used to implement signed binaries
> and signed modules.
>...
Checking signatures on modules sounds like a job for module-init-tools
(if there's any real benefit in signing GPL'ed modules).
> Regards,
> David
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Fri, Jan 27, 2006 at 06:35:40PM -0500, Kyle Moffett wrote:
> On Jan 27, 2006, at 17:19, Trond Myklebust wrote:
> >On Fri, 2006-01-27 at 21:41 +0100, David H?rdeman wrote:
> >
> >>For example, a backup daemon which wishes to store the backup on
> >>another host using ssh. Usually this is solved by storing an
> >>unencrypted key in the fs or by providing a connection to a ssh-
> >>agent which has been preloaded with the proper key(s). Both are
> >>quite inelegant solutions. With the in-kernel support, the daemon
> >>can request the key using the request_key call, and (provided
> >>proper scripts are written), the user who controls the relevant
> >>key can supply it. This in turn means that the backup daemon can
> >>sign using the key and read its public parts but not the private key.
> >
> >...but why would you want such a daemon to live in the kernel in
> >the first place? A backup application might perhaps need some
> >kernel support in order to ensure filesystem consistency, but that
> >does not mean that moving the entire daemon into the kernel is a
> >good idea.
>
> No, the point is not to put the backup daemon into the kernel, but to
> provide a way for the backup daemon and my user process to
> communicate DSA key details without completely giving the backup
> daemon my key. I may not entirely trust the backup daemon not to get
> compromised, but with support for the kernel keyring system,
> compromising the backup daemon would only compromise the backed up
> files, not the private keys and other secure data.
And why exactly is this not solvable through a userspace daemon?
> Cheers,
> Kyle Moffett
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Fri, 2006-01-27 at 18:35 -0500, Kyle Moffett wrote:
> No, the point is not to put the backup daemon into the kernel, but to
> provide a way for the backup daemon and my user process to
> communicate DSA key details without completely giving the backup
> daemon my key. I may not entirely trust the backup daemon not to get
> compromised, but with support for the kernel keyring system,
> compromising the backup daemon would only compromise the backed up
> files, not the private keys and other secure data.
This sort of thing is implemented routinely in user space by means of
proxy tickets/certificates/credentials. What makes them insufficient for
this use?
Cheers,
Trond
On Jan 27, 2006, at 19:22, Adrian Bunk wrote:
> On Fri, Jan 27, 2006 at 09:41:58PM +0100, David H?rdeman wrote:
>> The in-kernel key management also protects the key against many of
>> the different ways in which a user-space daemon could be attacked
>> (ptrace, swap-out, coredump, etc).
>
> If an attacker has enough privileges for attacking the daemon, he
> should usually also have enough privileges for attacking the kernel.
Not necessarily. If the daemon runs as the "backup" user or similar,
access to it does not imply root. We want to make an efficient way
to allow the _use_ of keys without implying access to the key data.
For example, one item under consideration is a "key handle" that
could be cloned, however if you revoke a given handle, all of its
cloned handles (and their clones), will be automatically revoked as
well. This would make it possible to pass a key to a program without
risking the key to compromise of that program. Say I pass my SSL key
to Mozilla. With this and some of the other new security features
(One of the code-isolation ones I think?), you could allow Mozilla to
use SSL websites without risking compromise of the SSL keys because
of a browser security hole.
On Jan 27, 2006, at 22:45, Trond Myklebust wrote:
> On Fri, 2006-01-27 at 18:35 -0500, Kyle Moffett wrote:
>
>> No, the point is not to put the backup daemon into the kernel, but
>> to provide a way for the backup daemon and my user process to
>> communicate DSA key details without completely giving the backup
>> daemon my key. I may not entirely trust the backup daemon not to
>> get compromised, but with support for the kernel keyring system,
>> compromising the backup daemon would only compromise the backed up
>> files, not the private keys and other secure data.
>
> This sort of thing is implemented routinely in user space by means
> of proxy tickets/certificates/credentials. What makes them
> insufficient for this use?
The problem is that there is no standard way to store/use the keys.
I can put my key in an ssh-agent to handle SSH, but that doesn't let
me securely auth mozilla. To do that, I need to explore how mozilla
configs work. And there are similar problems with context for
Kerberos, OpenAFS, encrypted filesystems, etc. You need to have a
common standardized way to pass the secure information around. This
provides that interface.
Cheers,
Kyle Moffett
--
Simple things should be simple and complex things should be possible
-- Alan Kay
On Sat, Jan 28, 2006 at 02:17:49AM -0500, Kyle Moffett wrote:
> On Jan 27, 2006, at 19:22, Adrian Bunk wrote:
> >On Fri, Jan 27, 2006 at 09:41:58PM +0100, David H?rdeman wrote:
> >>The in-kernel key management also protects the key against many of
> >>the different ways in which a user-space daemon could be attacked
> >>(ptrace, swap-out, coredump, etc).
> >
> >If an attacker has enough privileges for attacking the daemon, he
> >should usually also have enough privileges for attacking the kernel.
>
> Not necessarily. If the daemon runs as the "backup" user or similar,
> access to it does not imply root. We want to make an efficient way
> to allow the _use_ of keys without implying access to the key data.
> For example, one item under consideration is a "key handle" that
> could be cloned, however if you revoke a given handle, all of its
> cloned handles (and their clones), will be automatically revoked as
> well. This would make it possible to pass a key to a program without
> risking the key to compromise of that program. Say I pass my SSL key
> to Mozilla. With this and some of the other new security features
> (One of the code-isolation ones I think?), you could allow Mozilla to
> use SSL websites without risking compromise of the SSL keys because
> of a browser security hole.
I still haven't gotten the point which part of this is technically
impossible to implement in userspace.
> On Jan 27, 2006, at 22:45, Trond Myklebust wrote:
> >On Fri, 2006-01-27 at 18:35 -0500, Kyle Moffett wrote:
> >
> >>No, the point is not to put the backup daemon into the kernel, but
> >>to provide a way for the backup daemon and my user process to
> >>communicate DSA key details without completely giving the backup
> >>daemon my key. I may not entirely trust the backup daemon not to
> >>get compromised, but with support for the kernel keyring system,
> >>compromising the backup daemon would only compromise the backed up
> >>files, not the private keys and other secure data.
> >
> >This sort of thing is implemented routinely in user space by means
> >of proxy tickets/certificates/credentials. What makes them
> >insufficient for this use?
>
> The problem is that there is no standard way to store/use the keys.
> I can put my key in an ssh-agent to handle SSH, but that doesn't let
> me securely auth mozilla. To do that, I need to explore how mozilla
> configs work. And there are similar problems with context for
> Kerberos, OpenAFS, encrypted filesystems, etc. You need to have a
> common standardized way to pass the secure information around. This
> provides that interface.
"There's currently no standard" doesn't sound like a compelling reason
why a standard should be implemented in the kernel instead of userspace.
> Cheers,
> Kyle Moffett
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Sat, Jan 28, 2006 at 01:22:41AM +0100, Adrian Bunk wrote:
>On Fri, Jan 27, 2006 at 09:41:58PM +0100, David H?rdeman wrote:
>> The reason that I wanted DSA-keys supported by the in-kernel key stuff
>> is that it allows for some cool stuff which is either impossible or very
>> hard to do otherwise.
>>
>> For example, a backup daemon which wishes to store the backup on another
>> host using ssh. Usually this is solved by storing an unencrypted key in
>> the fs or by providing a connection to a ssh-agent which has been
>> preloaded with the proper key(s). Both are quite inelegant solutions.
>> With the in-kernel support, the daemon can request the key using the
>> request_key call, and (provided proper scripts are written), the user
>> who controls the relevant key can supply it. This in turn means that the
>> backup daemon can sign using the key and read its public parts but not
>> the private key.
>
>What exactly is the unsolvable problem with doing this in userspace?
See below
>> So yes, that is one example of doing "something" with keys that the
>> process is not allowed to retrieve directly (the key itself could be
>> supplied from removable storage or something and given a few minutes of
>> time-to-live).
>>
>> It also means that users would not have to run ssh-agent and would not
>> have to bother with making sure that only one instance of ssh-agent is
>> running even if they are logged in multiple times.
>>
>> The in-kernel key management also protects the key against many of the
>> different ways in which a user-space daemon could be attacked (ptrace,
>> swap-out, coredump, etc).
>
>If an attacker has enough privileges for attacking the daemon, he should
>usually also have enough privileges for attacking the kernel.
Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
your account (forgot to lock the screen while going to the bathroom?
did the OOM-condition occur which killed the program which locks the
screen? remote compromise of the system? local compromise?) means that a large
array of attacks are possible against the daemon.
In addition, as stated before, the "backup" account, or whatever user the
daemon which wants to sign stuff with your key is running as, might be
compromised.
Currently, if you want to give the daemon access to the keys via
ssh-agent (or something similar), you have to change the permissions on
the ssh-agent socket to be much less restricted (especially since it's
unlikely that you have permission to change the uid or gid of the socket
to that of the daemon). Alternatively you can provide the backup daemon
with the key directly (via fs, or loaded somehow at startup...etc), but
then a compromise of the daemon means that the attacker has the private
key.
Finally, the in-kernel system also provides a mechanism for the daemon
to request the key when it is needed should it realize that the proper
key is missing/has changed/whatever.
>The number of different attacks might be lower, but you haven't
>completely solved any problem.
Many of the problems are unsolveable without having specialized hardware
(i.e. a smartcard). The fact that the dsa patch is not a panacea does
not mean that it can't, or that we shouldn't strive to, improve upon the
current situation
>> In addition, the dsa key code can be used to implement signed binaries
>> and signed modules.
>>...
>
>Checking signatures on modules sounds like a job for module-init-tools
>(if there's any real benefit in signing GPL'ed modules).
No, not really, take a look at http://lwn.net/Articles/92617/ for
details of how signed modules could work (public key is merged into
kernel at build time, private key is used to build modules with embedded
signature, kernel checks module sigs at load-time using the embedded public
key, so checks can't be in module-init-tools).
Regards,
David
On Sat, Jan 28, 2006 at 11:46:11AM +0100, David H?rdeman wrote:
> On Sat, Jan 28, 2006 at 01:22:41AM +0100, Adrian Bunk wrote:
>...
> >If an attacker has enough privileges for attacking the daemon, he should
> >usually also have enough privileges for attacking the kernel.
>
> Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
> your account (forgot to lock the screen while going to the bathroom?
> did the OOM-condition occur which killed the program which locks the
> screen? remote compromise of the system? local compromise?) means that a
> large array of attacks are possible against the daemon.
>
> In addition, as stated before, the "backup" account, or whatever user the
> daemon which wants to sign stuff with your key is running as, might be
> compromised.
>
> Currently, if you want to give the daemon access to the keys via
> ssh-agent (or something similar), you have to change the permissions on
> the ssh-agent socket to be much less restricted (especially since it's
> unlikely that you have permission to change the uid or gid of the socket
> to that of the daemon). Alternatively you can provide the backup daemon
> with the key directly (via fs, or loaded somehow at startup...etc), but
> then a compromise of the daemon means that the attacker has the private
> key.
>
> Finally, the in-kernel system also provides a mechanism for the daemon
> to request the key when it is needed should it realize that the proper
> key is missing/has changed/whatever.
I'm sorry, but I'm still not getting the point:
Which part of this task is technically impossible to implement through a
userspace daemon?
> >The number of different attacks might be lower, but you haven't
> >completely solved any problem.
>
> Many of the problems are unsolveable without having specialized hardware
> (i.e. a smartcard). The fact that the dsa patch is not a panacea does
> not mean that it can't, or that we shouldn't strive to, improve upon the
> current situation
I'm still not understanding the big improvements when doing it in the
kernel instead of doing it in a userspace daemon.
> >>In addition, the dsa key code can be used to implement signed binaries
> >>and signed modules.
> >>...
> >
> >Checking signatures on modules sounds like a job for module-init-tools
> >(if there's any real benefit in signing GPL'ed modules).
>
> No, not really, take a look at http://lwn.net/Articles/92617/ for
> details of how signed modules could work (public key is merged into
> kernel at build time, private key is used to build modules with embedded
> signature, kernel checks module sigs at load-time using the embedded public
> key, so checks can't be in module-init-tools).
The only point in this lwn article that is not solvable outside of the
kernel is if distributions want to prevent loading of modules they
haven't authorized.
The lwn article outlines how distributions can use this for demanding
money from module vendors. Distributions can do this if they want to,
but this is nothing we should add a single byte of code for.
> Regards,
> David
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Sat, 2006-01-28 at 11:46 +0100, David Härdeman wrote:
> Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
> your account (forgot to lock the screen while going to the bathroom?
> did the OOM-condition occur which killed the program which locks the
> screen? remote compromise of the system? local compromise?) means that a large
> array of attacks are possible against the daemon.
>
> In addition, as stated before, the "backup" account, or whatever user the
> daemon which wants to sign stuff with your key is running as, might be
> compromised.
>
> Currently, if you want to give the daemon access to the keys via
> ssh-agent (or something similar), you have to change the permissions on
> the ssh-agent socket to be much less restricted (especially since it's
> unlikely that you have permission to change the uid or gid of the socket
> to that of the daemon). Alternatively you can provide the backup daemon
> with the key directly (via fs, or loaded somehow at startup...etc), but
> then a compromise of the daemon means that the attacker has the private
> key.
>
> Finally, the in-kernel system also provides a mechanism for the daemon
> to request the key when it is needed should it realize that the proper
> key is missing/has changed/whatever.
Then fix ssh, not the kernel. As I said before, this is a problem that
has been solved entirely in userspace by means of proxy certificates:
they allow the user to issue time-limited certificates that are signed
by the original certificate (hence can be authenticated as such), and
that authorise a service to do a specific thing.
Cheers,
Trond
On Sat, Jan 28, 2006 at 11:37:51AM -0500, Trond Myklebust wrote:
>On Sat, 2006-01-28 at 11:46 +0100, David H?rdeman wrote:
>> Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
>> your account (forgot to lock the screen while going to the bathroom?
>> did the OOM-condition occur which killed the program which locks the
>> screen? remote compromise of the system? local compromise?) means that a large
>> array of attacks are possible against the daemon.
>>
>> In addition, as stated before, the "backup" account, or whatever user the
>> daemon which wants to sign stuff with your key is running as, might be
>> compromised.
>>
>> Currently, if you want to give the daemon access to the keys via
>> ssh-agent (or something similar), you have to change the permissions on
>> the ssh-agent socket to be much less restricted (especially since it's
>> unlikely that you have permission to change the uid or gid of the socket
>> to that of the daemon). Alternatively you can provide the backup daemon
>> with the key directly (via fs, or loaded somehow at startup...etc), but
>> then a compromise of the daemon means that the attacker has the private
>> key.
>>
>> Finally, the in-kernel system also provides a mechanism for the daemon
>> to request the key when it is needed should it realize that the proper
>> key is missing/has changed/whatever.
>
>Then fix ssh, not the kernel. As I said before, this is a problem that
>has been solved entirely in userspace by means of proxy certificates:
>they allow the user to issue time-limited certificates that are signed
>by the original certificate (hence can be authenticated as such), and
>that authorise a service to do a specific thing.
What about the first paragraph of what I wrote? You are going to want to
keep often-used keys around somehow, proxy certificates is not a
solution for your own use of your personal keys and with the exception
of hardware solutions such as smart cards, the keys will be safer in the
kernel than in a user-space daemon...
Further, the mpi and dsa code can also be used for supporting signed
modules and binaries...the "store dsa-keys in kernel" part adds 376
lines of code (counted with wc so comments and includes etc are also
counted)...
Regards,
David
On Sat, Jan 28, 2006 at 02:03:16PM +0100, Adrian Bunk wrote:
>On Sat, Jan 28, 2006 at 11:46:11AM +0100, David H?rdeman wrote:
>> On Sat, Jan 28, 2006 at 01:22:41AM +0100, Adrian Bunk wrote:
>>...
>> >If an attacker has enough privileges for attacking the daemon, he should
>> >usually also have enough privileges for attacking the kernel.
>>
>> Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
>> your account (forgot to lock the screen while going to the bathroom?
>> did the OOM-condition occur which killed the program which locks the
>> screen? remote compromise of the system? local compromise?) means that a
>> large array of attacks are possible against the daemon.
>>
>> In addition, as stated before, the "backup" account, or whatever user the
>> daemon which wants to sign stuff with your key is running as, might be
>> compromised.
>>
>> Currently, if you want to give the daemon access to the keys via
>> ssh-agent (or something similar), you have to change the permissions on
>> the ssh-agent socket to be much less restricted (especially since it's
>> unlikely that you have permission to change the uid or gid of the socket
>> to that of the daemon). Alternatively you can provide the backup daemon
>> with the key directly (via fs, or loaded somehow at startup...etc), but
>> then a compromise of the daemon means that the attacker has the private
>> key.
>>
>> Finally, the in-kernel system also provides a mechanism for the daemon
>> to request the key when it is needed should it realize that the proper
>> key is missing/has changed/whatever.
>
>
>I'm sorry, but I'm still not getting the point:
>
>Which part of this task is technically impossible to implement through a
>userspace daemon?
See my latest reply to Trond...putting the keys in the kernel makes them
as secure as they can be without having specialized hardware (e.g.
smartcards).
>> >The number of different attacks might be lower, but you haven't
>> >completely solved any problem.
>>
>> Many of the problems are unsolveable without having specialized hardware
>> (i.e. a smartcard). The fact that the dsa patch is not a panacea does
>> not mean that it can't, or that we shouldn't strive to, improve upon the
>> current situation
>
>I'm still not understanding the big improvements when doing it in the
>kernel instead of doing it in a userspace daemon.
You said it yourself above...the number of different attacks is lower
>> >>In addition, the dsa key code can be used to implement signed binaries
>> >>and signed modules.
>> >>...
>> >
>> >Checking signatures on modules sounds like a job for module-init-tools
>> >(if there's any real benefit in signing GPL'ed modules).
>>
>> No, not really, take a look at http://lwn.net/Articles/92617/ for
>> details of how signed modules could work (public key is merged into
>> kernel at build time, private key is used to build modules with embedded
>> signature, kernel checks module sigs at load-time using the embedded public
>> key, so checks can't be in module-init-tools).
>
>
>The only point in this lwn article that is not solvable outside of the
>kernel is if distributions want to prevent loading of modules they
>haven't authorized.
Ehh...how do you provide the features of signed modules in user-space?
>The lwn article outlines how distributions can use this for demanding
>money from module vendors. Distributions can do this if they want to,
>but this is nothing we should add a single byte of code for.
There are already distributions with the patch in their kernel (Fedora),
so why would they care if signed modules patches are added to the
vanilla kernel or not?
On the other hand, it does add functionality which is useful to some
users even if it is not useful to all.
Regards,
David
On Sat, 2006-01-28 at 17:57 +0100, David Härdeman wrote:
> What about the first paragraph of what I wrote? You are going to want to
> keep often-used keys around somehow, proxy certificates is not a
> solution for your own use of your personal keys and with the exception
> of hardware solutions such as smart cards, the keys will be safer in the
> kernel than in a user-space daemon...
I don't get this explanation at all.
Why would you want to use proxy certificates for you own use? Use your
own certificate for your own processes, and issue one or more proxy
certificates to any daemon that you want to authorise to do some limited
task.
...and what does this statement about "keys being safer in the kernel"
mean?
> Further, the mpi and dsa code can also be used for supporting signed
> modules and binaries...the "store dsa-keys in kernel" part adds 376
> lines of code (counted with wc so comments and includes etc are also
> counted)...
Signed modules sounds like a better motivation, but is a full dsa
implementation in the kernel really necessary to achieve this?
Cheers,
Trond
On Sat, Jan 28, 2006 at 10:20:29PM -0500, Trond Myklebust wrote:
>On Sat, 2006-01-28 at 17:57 +0100, David H?rdeman wrote:
>> What about the first paragraph of what I wrote? You are going to want to
>> keep often-used keys around somehow, proxy certificates is not a
>> solution for your own use of your personal keys and with the exception
>> of hardware solutions such as smart cards, the keys will be safer in the
>> kernel than in a user-space daemon...
>
>I don't get this explanation at all.
>
>Why would you want to use proxy certificates for you own use? Use your
>own certificate for your own processes, and issue one or more proxy
>certificates to any daemon that you want to authorise to do some limited
>task.
I meant that you can't use proxy certs for your own use, so you still need
to store your own cert/key somehow...and I still believe that the kernel
keyring is the best place...
>...and what does this statement about "keys being safer in the kernel"
>mean?
swap-out to disk, ptrace, coredump all become non-issues. And in
combination with some other security features (such as disallowing
modules, read/write of /dev/mem + /dev/kmem, limited permissions via
SELinux, etc), it becomes pretty hard for the attacker to get your
private key even if he/she manages to get access to the root account.
>> Further, the mpi and dsa code can also be used for supporting signed
>> modules and binaries...the "store dsa-keys in kernel" part adds 376
>> lines of code (counted with wc so comments and includes etc are also
>> counted)...
>
>Signed modules sounds like a better motivation, but is a full dsa
>implementation in the kernel really necessary to achieve this?
How would you do it otherwise?
Re,
David
On Sun, Jan 29, 2006 at 12:33:20PM +0100, David H?rdeman wrote:
> On Sat, Jan 28, 2006 at 10:20:29PM -0500, Trond Myklebust wrote:
> >On Sat, 2006-01-28 at 17:57 +0100, David H?rdeman wrote:
> >>What about the first paragraph of what I wrote? You are going to want to
> >>keep often-used keys around somehow, proxy certificates is not a
> >>solution for your own use of your personal keys and with the exception
> >>of hardware solutions such as smart cards, the keys will be safer in the
> >>kernel than in a user-space daemon...
> >
> >I don't get this explanation at all.
> >
> >Why would you want to use proxy certificates for you own use? Use your
> >own certificate for your own processes, and issue one or more proxy
> >certificates to any daemon that you want to authorise to do some limited
> >task.
>
> I meant that you can't use proxy certs for your own use, so you still need
> to store your own cert/key somehow...and I still believe that the kernel
> keyring is the best place...
You are taking the wrong approach.
The _only_ question that matters is:
Why is it technically impossible to do the same in userspace?
If it's technically possible to do the same in userspace, it must not be
done in the kernel.
That's exactly the reason why e.g. kernel 2.6 does not contain a
webserver.
> >...and what does this statement about "keys being safer in the kernel"
> >mean?
>
> swap-out to disk, ptrace, coredump all become non-issues. And in
> combination with some other security features (such as disallowing
> modules, read/write of /dev/mem + /dev/kmem, limited permissions via
> SELinux, etc), it becomes pretty hard for the attacker to get your
> private key even if he/she manages to get access to the root account.
>...
Which part of this is technically impossible when doing key management
in usespace?
> Re,
> David
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
>
> You are taking the wrong approach.
>
> The _only_ question that matters is:
> Why is it technically impossible to do the same in userspace?
>
> If it's technically possible to do the same in userspace, it must not be
> done in the kernel.
that is not a reasonable statement because...
1) you can do all of tcp/ip in userspace just fine
2) you can do the NFS server in userspace
3) ...
4) ...
there are reasons why things that can be done in userspace sometimes
still make sense to do in kernel space, performance could be one of
those reasons, being unreasonably complex in userspace is another.
Identity management to some degree belongs in the kernel, simply because
identity *enforcing* is in the kernel. Some things related to security
need to be in the kernel at least partially just to avoid a LOT of hairy
issues and never ending series of security holes due to the exceptional
complexity you get.
On Sun, Jan 29, 2006 at 01:29:01PM +0100, Adrian Bunk wrote:
>You are taking the wrong approach.
>
>The _only_ question that matters is:
>Why is it technically impossible to do the same in userspace?
>
>If it's technically possible to do the same in userspace, it must not be
>done in the kernel.
It may not be impossible, but adding support for dsa key types to the
in-kernel key management is something like 150 lines of code once the
dsa crypto-ops are implemented. I think you get a lot of convenience
for those 150 lines (and yes, I do believe that convenience is also a
valid argument for adding functionality). Having to protect against all
attack vectors is much harder in user-space than in kernel-space.
As for the addition of the dsa crypto-ops, you still haven't answered
the question of how signed modules and/or binaries can be implemented
in userspace...
>That's exactly the reason why e.g. kernel 2.6 does not contain a
>webserver.
Apples and oranges
Re,
David
On Sun, 2006-01-29 at 12:33 +0100, David Härdeman wrote:
> >Why would you want to use proxy certificates for you own use? Use your
> >own certificate for your own processes, and issue one or more proxy
> >certificates to any daemon that you want to authorise to do some limited
> >task.
>
> I meant that you can't use proxy certs for your own use, so you still need
> to store your own cert/key somehow...and I still believe that the kernel
> keyring is the best place...
Agreed. Now, reread what I said above, and tell me why this is an
argument for doing dsa in the kernel?
> >...and what does this statement about "keys being safer in the kernel"
> >mean?
>
> swap-out to disk, ptrace, coredump all become non-issues. And in
> combination with some other security features (such as disallowing
> modules, read/write of /dev/mem + /dev/kmem, limited permissions via
> SELinux, etc), it becomes pretty hard for the attacker to get your
> private key even if he/she manages to get access to the root account.
Turning off coredump is trivial. All the features that LSM provide apply
to userland too (including security_ptrace()), so the SELinux policies
are not an argument for putting stuff in the kernel.
Only the swap-out to disk is an issue, and that is less of a worry if
you use a time-limited proxy in the daemon.
> >> Further, the mpi and dsa code can also be used for supporting signed
> >> modules and binaries...the "store dsa-keys in kernel" part adds 376
> >> lines of code (counted with wc so comments and includes etc are also
> >> counted)...
> >
> >Signed modules sounds like a better motivation, but is a full dsa
> >implementation in the kernel really necessary to achieve this?
>
> How would you do it otherwise?
Has anyone tried to look for simpler signing mechanisms that make use of
the crypto algorithms that are already in the kernel?
Cheers,
Trond
..... Original Message .......
On Sun, 29 Jan 2006 11:38:22 -0500 "Trond Myklebust" <[email protected]> wrote:
>On Sun, 2006-01-29 at 12:33 +0100, David Härdeman wrote:
>
>> >Why would you want to use proxy certificates for you own use? Use your
>> >own certificate for your own processes, and issue one or more proxy
>> >certificates to any daemon that you want to authorise to do some limited
>> >task.
>>
>> I meant that you can't use proxy certs for your own use, so you still need
>> to store your own cert/key somehow...and I still believe that the kernel
>> keyring is the best place...
>
>Agreed. Now, reread what I said above, and tell me why this is an
>argument for doing dsa in the kernel?
>
>> >...and what does this statement about "keys being safer in the kernel"
>> >mean?
>>
>> swap-out to disk, ptrace, coredump all become non-issues. And in
>> combination with some other security features (such as disallowing
>> modules, read/write of /dev/mem + /dev/kmem, limited permissions via
>> SELinux, etc), it becomes pretty hard for the attacker to get your
>> private key even if he/she manages to get access to the root account.
>
>Turning off coredump is trivial. All the features that LSM provide apply
>to userland too (including security_ptrace()), so the SELinux policies
>are not an argument for putting stuff in the kernel.
>
>Only the swap-out to disk is an issue, and that is less of a worry if
>you use a time-limited proxy in the daemon.
I seem to remember a feature in the kernel that allows each uid to mlock a small number of memory pages specifically intended to be used by daemons that cache keys. It is possible this was a Fedora kernel patch and not in the mainline kernel.
>> >> Further, the mpi and dsa code can also be used for supporting signed
>> >> modules and binaries...the "store dsa-keys in kernel" part adds 376
>> >> lines of code (counted with wc so comments and includes etc are also
>> >> counted)...
>> >
>> >Signed modules sounds like a better motivation, but is a full dsa
>> >implementation in the kernel really necessary to achieve this?
>>
>> How would you do it otherwise?
>
>Has anyone tried to look for simpler signing mechanisms that make use of
>the crypto algorithms that are already in the kernel?
Maybe you meant something else, but history has shown that 'rolling your own' mechanism is a bad idea.
Are there even any suitable algorithms in the kernel??
___
Dax Kelson
Sent with my Treo
On Sun, 2006-01-29 at 11:49 -0700, Dax Kelson wrote:
> >Has anyone tried to look for simpler signing mechanisms that make use of
> >the crypto algorithms that are already in the kernel?
>
> Maybe you meant something else, but history has shown that 'rolling your own' mechanism is a bad idea.
>
> Are there even any suitable algorithms in the kernel??
I'm suggesting that if the only real problem that dsa in the kernel
solves is module signing, then perhaps one can simplify the problem.
For instance, if instead of going for a general signing mechanism in the
kernel that will take any old module and verify it, you define a
particular binary as being trusted, and then devise a signature that the
kernel can check (even the SHA-1 of the binary image might be
sufficient).
The object would be to give the kernel a trusted program that can check
module signatures on its behalf.
Cheers,
Trond
Arjan van de Ven wrote:
>>You are taking the wrong approach.
>>
>>The _only_ question that matters is:
>>Why is it technically impossible to do the same in userspace?
>>
>>If it's technically possible to do the same in userspace, it must not be
>>done in the kernel.
>>
>>
>
>
>that is not a reasonable statement because...
>1) you can do all of tcp/ip in userspace just fine
>2) you can do the NFS server in userspace
>3) ...
>4) ...
>
>there are reasons why things that can be done in userspace sometimes
>still make sense to do in kernel space, performance could be one of
>those reasons, being unreasonably complex in userspace is another.
>
>Identity management to some degree belongs in the kernel, simply because
>identity *enforcing* is in the kernel. Some things related to security
>need to be in the kernel at least partially just to avoid a LOT of hairy
>issues and never ending series of security holes due to the exceptional
>complexity you get.
>
>
>
>
Yes - nicely stated. There are a few cases in which code would be
simpler in kernel, and there are even more cases where performance or
security considerations argue for a mostly kernel implementation of a
key piece of function. Although I don't know if the case has been
reproven for web servers (userspace) or nfs server (kernel) recently,
this case may be easier to work through if we understood the likely use
scenarios better of this piece of code. I don't know the right answer
for the particular math library question, but I have not seen the
typical argument considered about whether a user space implementation of
this paticular function could deadlock - ie would this code (proposed to
move to userspace) ever be called in a path in which the:
1) kernel were out of memory and userspace is needed to resolve the
write out of dirty memory
2) hang due to code going up to userspace in path in which key
kernel semaphores must be held across the call.
> I don't know the right answer
> for the particular math library question, but I have not seen the
> typical argument considered about whether a user space implementation of
> this paticular function could deadlock
it's not that kind of thing. It's basically a public key encryption
step. Putting it in the kernel can only serve one purpose: to be there
to allow other parts to use this pke for encrypting/signing/verifying
signatures.
The keyring stuff is in the kernel for three reasons:
1) to have a secure "vault" for keys, so that userspace doesn't need to
store secret keys and manage them securely; this requires that certain
operations on these keys also happen in the kernel
2) to make session management of keys easier. Yes you can do that in
userspace too but it's a mess (ssh-agent, while it works, isn't really
it)
3) to allow kernel pieces to do key things, like the secure nfs parts of
nfsv4 or ipsec.
Hi!
> >If an attacker has enough privileges for attacking the daemon, he should
> >usually also have enough privileges for attacking the kernel.
>
> Not necessarily, if you have your ssh-keys in ssh-agent, a compromise of
> your account (forgot to lock the screen while going to the bathroom?
> did the OOM-condition occur which killed the program which locks the
> screen? remote compromise of the system? local compromise?) means that a
> large array of attacks are possible against the daemon.
Run your ssh-agent on root, then. That's as safe as kernel... And does
not add potential security holes into kernel :-).
Pavel
--
Thanks, Sharp!
On Sun, Jan 29, 2006 at 11:38:22AM -0500, Trond Myklebust wrote:
>On Sun, 2006-01-29 at 12:33 +0100, David H?rdeman wrote:
>>>Why would you want to use proxy certificates for you own use? Use your
>>>own certificate for your own processes, and issue one or more proxy
>>>certificates to any daemon that you want to authorise to do some limited
>>>task.
>>
>>I meant that you can't use proxy certs for your own use, so you still need
>>to store your own cert/key somehow...and I still believe that the kernel
>>keyring is the best place...
>
>Agreed. Now, reread what I said above, and tell me why this is an
>argument for doing dsa in the kernel?
If you agree that the kernel keyring is the best place, it shouldn't be
a big step to also agree that in-kernel signing is "good" since it
allows you to use the key while it makes it possible for the kernel to
refuse to divulge the private part...even to the user who added the key
(i.e. yourself)...
>>>...and what does this statement about "keys being safer in the kernel"
>>>mean?
>>
>> swap-out to disk, ptrace, coredump all become non-issues. And in
>> combination with some other security features (such as disallowing
>> modules, read/write of /dev/mem + /dev/kmem, limited permissions via
>> SELinux, etc), it becomes pretty hard for the attacker to get your
>> private key even if he/she manages to get access to the root account.
>
>Turning off coredump is trivial. All the features that LSM provide apply
>to userland too (including security_ptrace()), so the SELinux policies
>are not an argument for putting stuff in the kernel.
>
>Only the swap-out to disk is an issue, and that is less of a worry if
>you use a time-limited proxy in the daemon.
How do you use a "time-limited proxy in the daemon" for your own
keys/cerificates (e.g. ssh keys)?
Re,
David
On Sun, Jan 29, 2006 at 02:10:46PM -0500, Trond Myklebust wrote:
>On Sun, 2006-01-29 at 11:49 -0700, Dax Kelson wrote:
>>>Has anyone tried to look for simpler signing mechanisms that make use of
>>>the crypto algorithms that are already in the kernel?
>>
>> Maybe you meant something else, but history has shown that 'rolling your own' mechanism is a bad idea.
>>
>> Are there even any suitable algorithms in the kernel??
>
>I'm suggesting that if the only real problem that dsa in the kernel
>solves is module signing, then perhaps one can simplify the problem.
>
>For instance, if instead of going for a general signing mechanism in the
>kernel that will take any old module and verify it, you define a
>particular binary as being trusted, and then devise a signature that the
>kernel can check (even the SHA-1 of the binary image might be
>sufficient).
>The object would be to give the kernel a trusted program that can check
>module signatures on its behalf.
Today, if a security bug is found in the kernel, you have to compile and
install a new kernel.
With your system, the signature of a "trusted" binary is embedded in the
kernel. Now, if a bug is found in said binary, you also get to compile
and install a new kernel along with a new binary.
Since the application is trusted, a security hole in the binary equals a
security hole in the kernel. In addition, you are bound to a given
kernel <-> userspace ABI, so if it has to be changed, you get to keep
several different trusted binaries around for different kernel versions
(/sbin/module-validate-v1 for ABI version 1, /sbin/module-validate-v2
for ABI version 2, etc).
Further, how is the module actually verified? If the trusted binary
reads it and checks "something" (i.e. a signature), and then says it's
ok, what is to say that the module is not changed on-disk between the
time when the binary reads it and when the kernel does so (for instance
by direct access to the disk). How do you expect the system to provide
security if you are running with nfs-root?
In addition you must protect the user-space binary against a slew of
attacks (you did statically link it to protect against LD_PRELOAD, right?).
What exactly is the advantage of user-space trusted binary signing?
Regards,
David
On Sun, 2006-01-29 at 22:13 +0100, David Härdeman wrote:
> If you agree that the kernel keyring is the best place, it shouldn't be
> a big step to also agree that in-kernel signing is "good" since it
> allows you to use the key while it makes it possible for the kernel to
> refuse to divulge the private part...even to the user who added the key
> (i.e. yourself)...
No! I agree that the kernel keyring is a good place to keep keys because
it has been designed with the correct inheritance rules. I do not agree
with the above logic that the kernel is inherently safer than userland.
By the above logic, we should put libpam, openssl, kerberos, all login
programs, kdcs, etc all in the kernel. That will not happen!
> >>>...and what does this statement about "keys being safer in the kernel"
> >>>mean?
> >>
> >> swap-out to disk, ptrace, coredump all become non-issues. And in
> >> combination with some other security features (such as disallowing
> >> modules, read/write of /dev/mem + /dev/kmem, limited permissions via
> >> SELinux, etc), it becomes pretty hard for the attacker to get your
> >> private key even if he/she manages to get access to the root account.
> >
> >Turning off coredump is trivial. All the features that LSM provide apply
> >to userland too (including security_ptrace()), so the SELinux policies
> >are not an argument for putting stuff in the kernel.
> >
> >Only the swap-out to disk is an issue, and that is less of a worry if
> >you use a time-limited proxy in the daemon.
>
> How do you use a "time-limited proxy in the daemon" for your own
> keys/cerificates (e.g. ssh keys)?
I don't have to. Why are you apparently insisting on this weird fallacy
that a keyring can only hold one certificate at a time?
However if you want an example of how I can do this, just look to
kerberos. What is probably the world's most commonly used security
mechanism is entirely based on the concept of time-limited tickets. When
I log in, I get a TGT, which is a time-limited proxy ticket that allows
me to obtain more tickets without having to re-enter my password. This
again allows me to obtain "service tickets", i.e. time-limited proxies
with limited capabilities for any service that requires it.
Cheers,
Trond
Arjan van de Ven wrote:
>it's not that kind of thing. It's basically a public key encryption
>step. Putting it in the kernel can only serve one purpose: to be there
>to allow other parts to use this pke for encrypting/signing/verifying
>signatures.
>
>
...
>3) to allow kernel pieces to do key things, like the secure nfs parts of
>nfsv4 or ipsec.
>
>
That can still deadlock. If write or writepage or writepages requires
a network frame to be signed and
an upcall occurs in that path ... For example cifs has long had
signature code in kernel (depends on MD5
code in kernel, which because it is so small has not been controversial
presumably) and write requests
(which can be necessary to flush inode data when the system is low on
memory) are signed
and of course of types of frames are signed in cases where various
semaphores on the parent directory
or inode are held by the vfs. This signing is done in kernel and at
least when authenticated with NTLM
(and presumably NTLMv2 as well) has turned out to be fairly simple.
Note that for many or most
cifs servers in modern day domains packet signatures are required by
default (unlike four or five years
ago when it was less common). A key issue that I have not worked
through is whether this would change
as SPNEGO authentication negotiates PKI or Kerberos like tickets - and
whether any of this in kernel
infrastructure being discussed would be needed for the common case of
cifs (beyond what
we already have with MD5 packet signatures) or helpful for the case when
Kerberos/SPNEGO authentication is negotiated (code that is not yet
complete in cifs, but will
probably be 90% done in userspace) because CIFS packet signing when
Kerberos is
authenticated (or when an alternative some x509/SPNEGO pki variant is
more commonly
seem from e.g. Windows servers or NAS appliances) different signing code
may be required -
and since the SMB WriteX frame would have to be signed ... it would be
very risky to upcall if
we find out that packet signing for the very, very common case (more
than 2/3 of enterprises today)
of Kerberized cifs sessions requires an encrypting/signing/verifying
mechanism that is not in kernel.
Beyond the issue of how to handle the newer version of packet signing,
my main interest in the
calling the keyring code from kernel (from cifs vfs) is using it to
determining more precisely
what the "kerberos identity" of the current process is (ie what is the
"user@realm" for the current
process and do I have an authenticated session for him - so I can map
the right smb_uid (in effect
a handle to the network security context for the smb session) for the
header of the SMB/CIFS
network file requests coming from any particular process).
A secondary benefit of the keyring infrastructure, an issue that I hear
frequently from advanced users, an
issue that the kernel keyring may eventually solve is allowing me to
automatically authenticate without all local
users having to resupply the password for every local mount (in
particular when /proc/fs/cifs/MultiuserMount
is enabled). Currently each unique user logged on to a system
typically authenticates through pam but
kernel code has no access to the password that was supplied earlier at
logon time, unless it is passed again
explicitly on mount. There are common cases in which users would logon
locally with the same userid/password
as they would supply to mount to a remote server (especially when users
authenticate to a central
security server through pam_winbind or pam_ldap, pam_kerberos) - in
those cases I hope someday that
an optional pam module is available which saves the password (or in my
case there is also a one way hash of the
password which would be fine) in the kernel key ring so cifs does not
have to upcall in the middle of
an operation (from what to cifs is a new user for this mount) to prompt
the user at runtime for a password (which
would be awful). Currently users have to mount to the same server (and
export) multiple times, once with
each uid/user/password combination - and the keyring would solve this if
there were an optional pam module that
could save passwords (and eventually kerberos tickets too) securely in
kernel in the keyring.
On Sun, 2006-01-29 at 22:29 +0100, David Härdeman wrote:
> With your system, the signature of a "trusted" binary is embedded in the
> kernel. Now, if a bug is found in said binary, you also get to compile
> and install a new kernel along with a new binary.
If you compile a SHA-1 signature directly into the kernel, yes.
Alternatively, you could for instance allow it to be set once and only
once upon boot.
> Since the application is trusted, a security hole in the binary equals a
> security hole in the kernel. In addition, you are bound to a given
> kernel <-> userspace ABI, so if it has to be changed, you get to keep
> several different trusted binaries around for different kernel versions
> (/sbin/module-validate-v1 for ABI version 1, /sbin/module-validate-v2
> for ABI version 2, etc).
See modprobe. We already have that sort of dependency.
> Further, how is the module actually verified? If the trusted binary
> reads it and checks "something" (i.e. a signature), and then says it's
> ok, what is to say that the module is not changed on-disk between the
> time when the binary reads it and when the kernel does so (for instance
> by direct access to the disk). How do you expect the system to provide
> security if you are running with nfs-root?
You have to verify the module _after_ it has been loaded into the
kernel, but before any code has been run. No difference there between a
userspace and a kernel space solution.
> In addition you must protect the user-space binary against a slew of
> attacks (you did statically link it to protect against LD_PRELOAD, right?).
I assume so.
> What exactly is the advantage of user-space trusted binary signing?
Umm... No unnecessary junk in the kernel when you are not loading in
modules? Greater possible choice of signing mechanisms? Support for
revoking signatures?
Cheers,
Trond
On Sun, Jan 29, 2006 at 04:28:20PM -0500, Trond Myklebust wrote:
>On Sun, 2006-01-29 at 22:13 +0100, David H?rdeman wrote:
>> How do you use a "time-limited proxy in the daemon" for your own
>> keys/cerificates (e.g. ssh keys)?
>
>I don't have to. Why are you apparently insisting on this weird fallacy
>that a keyring can only hold one certificate at a time?
I'm talking about ssh keys, not kerberos tickets.
Re,
David
On Sun, 2006-01-29 at 23:02 +0100, David Härdeman wrote:
> On Sun, Jan 29, 2006 at 04:28:20PM -0500, Trond Myklebust wrote:
> >On Sun, 2006-01-29 at 22:13 +0100, David Härdeman wrote:
> >> How do you use a "time-limited proxy in the daemon" for your own
> >> keys/cerificates (e.g. ssh keys)?
> >
> >I don't have to. Why are you apparently insisting on this weird fallacy
> >that a keyring can only hold one certificate at a time?
>
> I'm talking about ssh keys, not kerberos tickets.
As I said previously, the lack of support for proxies would appear to be
a bug in ssh, not the kernel.
Cheers,
Trond
On Jan 29, 2006, at 17:05, Trond Myklebust wrote:
> On Sun, 2006-01-29 at 23:02 +0100, David H?rdeman wrote:
>> On Sun, Jan 29, 2006 at 04:28:20PM -0500, Trond Myklebust wrote:
>>> On Sun, 2006-01-29 at 22:13 +0100, David H?rdeman wrote:
>>>> How do you use a "time-limited proxy in the daemon" for your own
>>>> keys/cerificates (e.g. ssh keys)?
>>>
>>> I don't have to. Why are you apparently insisting on this weird
>>> fallacy that a keyring can only hold one certificate at a time?
>>
>> I'm talking about ssh keys, not kerberos tickets.
>
> As I said previously, the lack of support for proxies would appear
> to be a bug in ssh, not the kernel.
You keep mentioning proxy certificates. So you are saying that when
I pass the key to some daemon to which I do not want it to have
permanent access, I should create a proxy certificate to pass
instead? This _vastly_ increases the amount of math that needs to be
done. Instead of just using my private key to encrypt data, I would
need to generate a new private key with the required encryption
strength, generate a proxy certificate, sign the proxy certificate
with the old private key, keep track of revocation lists somehow (how
do I reliably expire a proxy certificate on-demand everywhere it
might be without a web-server hosting the CRLs?), _then_ I can
finally encrypt my data with the proxy certificate. I think this
qualifies as a serious performance problem, especially if I'm opening
and closing lots of SSH tunnels, like running remote commands on
every system in a cluster.
If we use this proposed in-kernel system, then I can give my
certificate/pubkey to the kernel code, and then my web browser, SSH,
and anything else can automatically use it to decrypt and sign data
without being able to directly access (and thus compromise) the key.
If I later notice what I think might be a rogue process, I can
instantly and globally revoke all access to that keypair.
Cheers,
Kyle Moffett
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/E/U d- s++: a18 C++++>$ ULBX*++++(+++)>$ P++++(+++)>$ L++++
(+++)>$ !E- W+++(++) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+ PGP
+ t+(+++) 5 X R? !tv-(--) b++++(++) DI+(++) D+++ G e>++++$ h*(+)>++$ r
%(--) !y?-(--)
------END GEEK CODE BLOCK------
On Sun, 2006-01-29 at 17:54 -0500, Kyle Moffett wrote:
> You keep mentioning proxy certificates. So you are saying that when
> I pass the key to some daemon to which I do not want it to have
> permanent access, I should create a proxy certificate to pass
> instead? This _vastly_ increases the amount of math that needs to be
> done. Instead of just using my private key to encrypt data, I would
> need to generate a new private key with the required encryption
> strength, generate a proxy certificate, sign the proxy certificate
> with the old private key, keep track of revocation lists somehow (how
> do I reliably expire a proxy certificate on-demand everywhere it
> might be without a web-server hosting the CRLs?), _then_ I can
> finally encrypt my data with the proxy certificate. I think this
> qualifies as a serious performance problem, especially if I'm opening
> and closing lots of SSH tunnels, like running remote commands on
> every system in a cluster.
Feel free to profile it. I challenge you to find a real-life application
where the above is actually a performance problem.
> If we use this proposed in-kernel system, then I can give my
> certificate/pubkey to the kernel code, and then my web browser, SSH,
> and anything else can automatically use it to decrypt and sign data
> without being able to directly access (and thus compromise) the key.
> If I later notice what I think might be a rogue process, I can
> instantly and globally revoke all access to that keypair.
The latter is something you can do with keyrings anyway. As for the
former, that too is completely solvable in userspace. For instance, CITI
has a scheme for issuing X509 proxy certificates given a kerberos key.
ssh can log you in automatically given the same kerberos key,...
This sort of problem is simply not a reason for sticking dsa into the
kernel.
Cheers,
Trond
On Sun, Jan 29, 2006 at 05:54:00PM -0500, Kyle Moffett wrote:
>...
> If we use this proposed in-kernel system, then I can give my
> certificate/pubkey to the kernel code, and then my web browser, SSH,
> and anything else can automatically use it to decrypt and sign data
> without being able to directly access (and thus compromise) the key.
> If I later notice what I think might be a rogue process, I can
> instantly and globally revoke all access to that keypair.
Why do you need this in the kernel?
A userspace daemon could do exactly the same.
> Cheers,
> Kyle Moffett
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Sun, Jan 29, 2006 at 02:09:08PM +0100, Arjan van de Ven wrote:
>
> >
> > You are taking the wrong approach.
> >
> > The _only_ question that matters is:
> > Why is it technically impossible to do the same in userspace?
> >
> > If it's technically possible to do the same in userspace, it must not be
> > done in the kernel.
>
>
> that is not a reasonable statement because...
> 1) you can do all of tcp/ip in userspace just fine
> 2) you can do the NFS server in userspace
> 3) ...
> 4) ...
>
> there are reasons why things that can be done in userspace sometimes
> still make sense to do in kernel space, performance could be one of
> those reasons, being unreasonably complex in userspace is another.
Agreed, my sentence was too general.
> Identity management to some degree belongs in the kernel, simply because
> identity *enforcing* is in the kernel. Some things related to security
> need to be in the kernel at least partially just to avoid a LOT of hairy
> issues and never ending series of security holes due to the exceptional
> complexity you get.
OK, this sounds reasonable in the cases where the enforcing is actually
in the kernel (but not in the backup daemon example from this thread).
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On Sun, Jan 29, 2006 at 02:18:15PM +0100, David H?rdeman wrote:
>...
> you still haven't answered
> the question of how signed modules and/or binaries can be implemented
> in userspace...
>...
It seems I'm slowly getting the point.
I was partially confused by your backup daemon deamon example that can
be equally well implemented in userspace.
Signed modules and/or binaries seems to be the application this might be
required for, so let's discuss exactly this application and not the
others.
> Re,
> David
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
On 29 Jan 2006, Adrian Bunk uttered the following:
> Signed modules and/or binaries seems to be the application this might be
> required for, so let's discuss exactly this application and not the
> others.
Indeed. See e.g. the digsig project at <http://disec.sf.net/> for a
working implementation of signed binaries and shared libraries, with MPI
in the module for exactly this purpose.
--
`I won't make a secret of the fact that your statement/question
sent a wave of shock and horror through us.' --- David Anderson
Arjan van de Ven <[email protected]> wrote:
> 3) to allow kernel pieces to do key things, like the secure nfs parts of
> nfsv4 or ipsec.
Also eCryptFS.
David