* [PATCH 02/04] Add dsa crypto ops [not found] <11380489522552@2gen.com> @ 2006-01-23 20:42 ` David Härdeman 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman 2006-01-24 1:22 ` [PATCH 02/04] Add dsa crypto ops Herbert Xu 2006-01-24 10:37 ` [PATCH 01/04] Add multi-precision-integer maths library David Howells 1 sibling, 2 replies; 25+ messages in thread From: David Härdeman @ 2006-01-23 20:42 UTC (permalink / raw) To: linux-kernel; +Cc: dhowells, david Adds dsa cryptographic operations. Since a dsa signature is always two 160-bit integer, I've modeled the dsa crypto as a hash algorithm. Signed-off-by: David Härdeman <david@2gen.com> -- Index: vanilla-kernel/crypto/Kconfig =================================================================== --- vanilla-kernel.orig/crypto/Kconfig 2006-01-22 22:02:20.000000000 +0100 +++ vanilla-kernel/crypto/Kconfig 2006-01-22 22:08:27.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: vanilla-kernel/crypto/Makefile =================================================================== --- vanilla-kernel.orig/crypto/Makefile 2006-01-22 22:02:37.000000000 +0100 +++ vanilla-kernel/crypto/Makefile 2006-01-22 22:08:27.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: vanilla-kernel/crypto/dsa.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ vanilla-kernel/crypto/dsa.c 2006-01-22 22:08:11.000000000 +0100 @@ -0,0 +1,230 @@ +/* + * DSA Digital Signature Algorithm (FIPS-186). + * + * Copyright (c) 2005 David Härdeman <david@2gen.com> + * + * 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> + + +/**************** + * Generate a random secret exponent k less than q + */ +static MPI +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("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 +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 = gen_k(skey->part[DSA_PART_Q]); + if (!k) { + printk("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; + + if (keylen != sizeof(struct key_payload_dsa *)) { + printk("Invalid key size in dsa_setkey\n"); + return -EINVAL; + } + + dctx->key = (struct key_payload_dsa *)key; + return 0; +} + +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("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; + + 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("dsa_final: failed to allocate mpis\n"); + goto out1; + } + + mpi_set_buffer(hash, buffer, dsize, 0); + 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("dsa_final: 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); +} + +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) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + 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: vanilla-kernel/include/linux/dsa.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ vanilla-kernel/include/linux/dsa.h 2006-01-22 22:07:58.000000000 +0100 @@ -0,0 +1,39 @@ +/* dsa.h: digital signature architecture + * + * Copyright (C) 2005 David Härdeman (david@2gen.com). + * 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 */ +}; + +#if 0 +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) do { } while(0) +#endif + +#endif +#endif ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-23 20:42 ` [PATCH 02/04] Add dsa crypto ops David Härdeman @ 2006-01-23 20:42 ` David Härdeman 2006-01-23 20:42 ` [PATCH 04/04] Add dsa key type David Härdeman ` (3 more replies) 2006-01-24 1:22 ` [PATCH 02/04] Add dsa crypto ops Herbert Xu 1 sibling, 4 replies; 25+ messages in thread From: David Härdeman @ 2006-01-23 20:42 UTC (permalink / raw) To: linux-kernel; +Cc: dhowells, david Changes the keyctl syscall to accept six arguments (is it valid to do so?) and adds encryption as one of the supported ops for in-kernel keys. Signed-off-by: David Härdeman <david@2gen.com> -- Index: vanilla-kernel/include/linux/compat.h =================================================================== --- vanilla-kernel.orig/include/linux/compat.h 2006-01-15 18:22:51.000000000 +0100 +++ vanilla-kernel/include/linux/compat.h 2006-01-23 18:40:52.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: vanilla-kernel/include/linux/key.h =================================================================== --- vanilla-kernel.orig/include/linux/key.h 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/include/linux/key.h 2006-01-23 18:40:52.000000000 +0100 @@ -220,6 +220,17 @@ */ long (*read)(const struct key *key, char __user *buffer, size_t buflen); + /* encrypt data using a key (optional) + * - permission checks will be done by the caller + * - the key's semaphore will be readlocked by the caller + * - should return the amount of data that would be returned from the + * encryption even if the buffer is NULL + * - expects the output buffer to be able to hold the result + */ + long (*encrypt)(const struct key *key, + 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: vanilla-kernel/include/linux/keyctl.h =================================================================== --- vanilla-kernel.orig/include/linux/keyctl.h 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/include/linux/keyctl.h 2006-01-23 18:40:52.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: vanilla-kernel/include/linux/syscalls.h =================================================================== --- vanilla-kernel.orig/include/linux/syscalls.h 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/include/linux/syscalls.h 2006-01-23 18:40:52.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: vanilla-kernel/security/keys/compat.c =================================================================== --- vanilla-kernel.orig/security/keys/compat.c 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/security/keys/compat.c 2006-01-23 18:44:01.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: vanilla-kernel/security/keys/keyctl.c =================================================================== --- vanilla-kernel.orig/security/keys/keyctl.c 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/security/keys/keyctl.c 2006-01-23 18:44:02.000000000 +0100 @@ -1066,10 +1066,71 @@ /*****************************************************************************/ /* + * 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, + const 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) { + /* encrypt the data with the semaphore held (since we + * might sleep) */ + down_read(&key->sem); + ret = key->type->encrypt(key, data, dlen, result, rlen); + up_read(&key->sem); + } + } + + 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 +1205,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, + (const char __user *) arg5, + (size_t) arg6); + default: return -EOPNOTSUPP; } ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 04/04] Add dsa key type 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman @ 2006-01-23 20:42 ` David Härdeman 2006-01-24 11:08 ` David Howells 2006-01-24 4:33 ` [PATCH 03/04] Add encryption ops to the keyctl syscall Randy.Dunlap ` (2 subsequent siblings) 3 siblings, 1 reply; 25+ messages in thread From: David Härdeman @ 2006-01-23 20:42 UTC (permalink / raw) To: linux-kernel; +Cc: dhowells, david Adds the dsa in-kernel key type. Signed-off-by: David Härdeman <david@2gen.com> -- Index: vanilla-kernel/security/Kconfig =================================================================== --- vanilla-kernel.orig/security/Kconfig 2006-01-17 22:49:50.000000000 +0100 +++ vanilla-kernel/security/Kconfig 2006-01-23 18:45:29.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: vanilla-kernel/security/keys/Makefile =================================================================== --- vanilla-kernel.orig/security/keys/Makefile 2006-01-15 18:22:51.000000000 +0100 +++ vanilla-kernel/security/keys/Makefile 2006-01-23 18:46:00.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: vanilla-kernel/security/keys/dsa_key.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ vanilla-kernel/security/keys/dsa_key.c 2006-01-23 18:46:00.000000000 +0100 @@ -0,0 +1,372 @@ +/* dsa_key.c: DSA key + * + * Copyright (C) 2005 David Härdeman (david@2gen.com). 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(const struct key *key, + 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 * +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]; + + dprintk("dsa: entering sign\n"); + 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("dsa: 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; +} + +/**************** + * Test whether the secret key is valid. + * Returns: if this is a valid key. + */ +static int check_secret_key(struct key_payload_dsa *skey) +{ + int rc; + MPI y; + + /* y = g^x mod p */ + dprintk("dsa: In check secret\n"); + 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; +} + +/*****************************************************************************/ +/* + * 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; + + dprintk("dsa: entering dsa_create_payload\n"); + + 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++) { + dprintk("dsa: 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; + dprintk("dsa: end loop\n"); + } + + if (ret < 0) + goto out3; + + /* check validity */ + ret = -EINVAL; + if(check_secret_key(*payload)) { + ret = 0; + dprintk("dsa: valid\n"); + goto out1; + } + +out3: + printk("dsa: 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; + + dprintk("dsa: entering dsa_instantiate\n"); + 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; + + dprintk("dsa: entering dsa_update\n"); + ret = dsa_create_payload(&new_payload, key, data, datalen); + if (ret == 0) { + dprintk("dsa: dsa_create_payload success\n"); + /* this destroys the old payload, not the entire key */ + dsa_destroy(key); + key->payload.data = new_payload; + key->expiry = 0; + } + + 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; + + dprintk("dsa: entering dsa_destroy\n"); + 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; + + dprintk("dsa: entering dsa_read\n"); + 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]) { + dprintk("dsa: failed to get 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++) { + dprintk("dsa: checking part %i\n", i); + dprintk("dsa: 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: + dprintk("dsa: leving dsa_read\n"); + return ret; + +} /* end dsa_read() */ + +/*****************************************************************************/ +/* + * encrypt data using a key + */ +static long dsa_encrypt(const struct key *key, + char __user *data, size_t dlen, + char __user *result, size_t rlen) +{ + char *signature; + char *inbuf; + long ret; + size_t siglen = 0; + + dprintk("dsa: entering dsa_encrypt\n"); + 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 = 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: + return ret; +} /* end dsa_encrypt() */ + +static int __init dsa_init(void) +{ + int ret; + + ret = register_key_type(&key_type_dsa); + if (ret < 0) + printk("dsa_key: failed to register key type\n"); + else + printk("dsa_key: new key type registered\n"); + + return ret; +} + +static void __exit dsa_exit (void) +{ + printk("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"); ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 04/04] Add dsa key type 2006-01-23 20:42 ` [PATCH 04/04] Add dsa key type David Härdeman @ 2006-01-24 11:08 ` David Howells 2006-01-25 19:14 ` David Härdeman 2006-01-26 9:41 ` David Howells 0 siblings, 2 replies; 25+ messages in thread From: David Howells @ 2006-01-24 11:08 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: linux-kernel, dhowells David Härdeman <david@2gen.com> wrote: > Adds the dsa in-kernel key type. Please add a header file in include/keys/ to provide access to the key type definition and any special payload structures you use. > +static char * > +sign(const struct key_payload_dsa *skey, Please be consistent about sticking prefixes on the names of your functions. This ought to be called something like dsa_sign. > + printk("dsa: crypto_digest_setkey failed with error %i\n", i); Should involve KERN_ERR or something like. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 04/04] Add dsa key type 2006-01-24 11:08 ` David Howells @ 2006-01-25 19:14 ` David Härdeman 2006-01-26 9:41 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Härdeman @ 2006-01-25 19:14 UTC (permalink / raw) To: David Howells; +Cc: linux-kernel On Tue, Jan 24, 2006 at 11:08:45AM +0000, David Howells wrote: >David Härdeman <david@2gen.com> wrote: > >> Adds the dsa in-kernel key type. > >Please add a header file in include/keys/ to provide access to the key type >definition and any special payload structures you use. That was already added by one of the earlier patches as include/dsa.h since its shared by crypto/dsa.c and security/keys/dsa_key.c, do you prefer some other solution? >> +static char * >> +sign(const struct key_payload_dsa *skey, > >Please be consistent about sticking prefixes on the names of your >functions. This ought to be called something like dsa_sign. Ok >> + printk("dsa: crypto_digest_setkey failed with error %i\n", i); > >Should involve KERN_ERR or something like. Ok Regards, David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 04/04] Add dsa key type 2006-01-24 11:08 ` David Howells 2006-01-25 19:14 ` David Härdeman @ 2006-01-26 9:41 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Howells @ 2006-01-26 9:41 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: David Howells, linux-kernel David Härdeman <david@2gen.com> wrote: > That was already added by one of the earlier patches as include/dsa.h since > its shared by crypto/dsa.c and security/keys/dsa_key.c, do you prefer some > other solution? That'll do then. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman 2006-01-23 20:42 ` [PATCH 04/04] Add dsa key type David Härdeman @ 2006-01-24 4:33 ` Randy.Dunlap 2006-01-24 10:58 ` David Howells 2006-01-24 11:09 ` David Howells 3 siblings, 0 replies; 25+ messages in thread From: Randy.Dunlap @ 2006-01-24 4:33 UTC (permalink / raw) To: David Härdeman; +Cc: linux-kernel, dhowells On Mon, 23 Jan 2006 21:42:32 +0100 David Härdeman wrote: > > Changes the keyctl syscall to accept six arguments (is it valid to do so?) > and adds encryption as one of the supported ops for in-kernel keys. Does this say anything about the amount of syscall testing that this code has had? --- ~Randy ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman 2006-01-23 20:42 ` [PATCH 04/04] Add dsa key type David Härdeman 2006-01-24 4:33 ` [PATCH 03/04] Add encryption ops to the keyctl syscall Randy.Dunlap @ 2006-01-24 10:58 ` David Howells 2006-01-25 20:40 ` David Härdeman 2006-01-26 9:43 ` David Howells 2006-01-24 11:09 ` David Howells 3 siblings, 2 replies; 25+ messages in thread From: David Howells @ 2006-01-24 10:58 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: linux-kernel, dhowells David Härdeman <david@2gen.com> wrote: > Changes the keyctl syscall to accept six arguments (is it valid to do so?) > and adds encryption as one of the supported ops for in-kernel keys. I tried to avoid doing that for it required arch support as I recall, but I'm not sure which arch I was thinking of. It looks like it ought to be okay... it's no worse than mmap. > + * - should return the amount of data that would be returned from the > + * encryption even if the buffer is NULL > + * - expects the output buffer to be able to hold the result > + */ Can you use TAB chars here please. > #define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */ > +#define KEYCTL_ENCRYPT 17 /* encrypt a chunk of data using key */ And here. > + key = key_ref_to_ptr(key_ref); > + > + /* see if we can read it directly */ > + ret = key_permission(key_ref, KEY_READ); You don't actually need to calculate key until after you've done all those checks, so I'd move it further down the file. You can use the function to release key references in the error handling or have a separate error handling return path. > + down_read(&key->sem); > + ret = key->type->encrypt(key, data, dlen, result, rlen); > + up_read(&key->sem); Do we really want to restrict the key type implementor to using the r/w semaphore. Would it be better to let the type decide whether it wants to use the semaphore or let it use RCU if it so desires? David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-24 10:58 ` David Howells @ 2006-01-25 20:40 ` David Härdeman 2006-01-26 9:43 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Härdeman @ 2006-01-25 20:40 UTC (permalink / raw) To: David Howells; +Cc: linux-kernel On Tue, Jan 24, 2006 at 10:58:24AM +0000, David Howells wrote: >> + key = key_ref_to_ptr(key_ref); >> + >> + /* see if we can read it directly */ >> + ret = key_permission(key_ref, KEY_READ); > >You don't actually need to calculate key until after you've done all those >checks, so I'd move it further down the file. You can use the function to >release key references in the error handling or have a separate error handling >return path. Do you mean that I should move the key_ref_to_ptr call to right after the can_read_key label? If that is the case, shouldn't the same thing be done for keyctl_read_key? >> + down_read(&key->sem); >> + ret = key->type->encrypt(key, data, dlen, result, rlen); >> + up_read(&key->sem); > >Do we really want to restrict the key type implementor to using the r/w >semaphore. Would it be better to let the type decide whether it wants to use >the semaphore or let it use RCU if it so desires? Ok, I'll move the semaphore into the dsa key type instead and change the appropriate comments. Re, David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-24 10:58 ` David Howells 2006-01-25 20:40 ` David Härdeman @ 2006-01-26 9:43 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Howells @ 2006-01-26 9:43 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: David Howells, linux-kernel David Härdeman <david@2gen.com> wrote: > Do you mean that I should move the key_ref_to_ptr call to right after the > can_read_key label? If that is the case, shouldn't the same thing be done for > keyctl_read_key? Quite possibly. I'll have a look at it when I get back from NZ. Actually, it's possible that the compiler shifts it down anyway since it has no side effects. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/04] Add encryption ops to the keyctl syscall 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman ` (2 preceding siblings ...) 2006-01-24 10:58 ` David Howells @ 2006-01-24 11:09 ` David Howells 3 siblings, 0 replies; 25+ messages in thread From: David Howells @ 2006-01-24 11:09 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: linux-kernel, dhowells David Härdeman <david@2gen.com> wrote: > and adds encryption as one of the supported ops for in-kernel keys. Do not forget to update Documentation/keys.txt. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 02/04] Add dsa crypto ops 2006-01-23 20:42 ` [PATCH 02/04] Add dsa crypto ops David Härdeman 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman @ 2006-01-24 1:22 ` Herbert Xu 2006-01-24 6:49 ` David Härdeman 1 sibling, 1 reply; 25+ messages in thread From: Herbert Xu @ 2006-01-24 1:22 UTC (permalink / raw) To: David H?rdeman; +Cc: linux-kernel, dhowells, david David H?rdeman <david@2gen.com> wrote: > > +static int dsa_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) > +{ > + struct dsa_ctx *dctx = ctx; > + > + if (keylen != sizeof(struct key_payload_dsa *)) { > + printk("Invalid key size in dsa_setkey\n"); > + return -EINVAL; > + } > + > + dctx->key = (struct key_payload_dsa *)key; > + return 0; > +} This is bad. You're putting a pointer to an object with an unknown lifetime into the tfm. Is there anything wrong with allocating the memory for it and storing the key in the tfm like everyone else? Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 02/04] Add dsa crypto ops 2006-01-24 1:22 ` [PATCH 02/04] Add dsa crypto ops Herbert Xu @ 2006-01-24 6:49 ` David Härdeman 0 siblings, 0 replies; 25+ messages in thread From: David Härdeman @ 2006-01-24 6:49 UTC (permalink / raw) To: Herbert Xu; +Cc: linux-kernel, dhowells On Tue, Jan 24, 2006 at 12:22:02PM +1100, Herbert Xu wrote: >David H?rdeman <david@2gen.com> wrote: >> >> +static int dsa_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) >> +{ >> + struct dsa_ctx *dctx = ctx; >> + >> + if (keylen != sizeof(struct key_payload_dsa *)) { >> + printk("Invalid key size in dsa_setkey\n"); >> + return -EINVAL; >> + } >> + >> + dctx->key = (struct key_payload_dsa *)key; >> + return 0; >> +} > >This is bad. You're putting a pointer to an object with an unknown >lifetime into the tfm. > >Is there anything wrong with allocating the memory for it and storing >the key in the tfm like everyone else? No, not at all, it's a mistake and I'll change it... ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library [not found] <11380489522552@2gen.com> 2006-01-23 20:42 ` [PATCH 02/04] Add dsa crypto ops David Härdeman @ 2006-01-24 10:37 ` David Howells 2006-01-25 20:46 ` David Härdeman 2006-01-26 9:45 ` David Howells 1 sibling, 2 replies; 25+ messages in thread From: David Howells @ 2006-01-24 10:37 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: linux-kernel, dhowells David Härdeman <david@2gen.com> wrote: > Adds the multi-precision-integer maths library which was originally taken > from GnuPG and ported to the kernel by David Howells in 2004 > (http://people.redhat.com/~dhowells/modsign/modsign-269rc4mm1-2.diff.bz2) You should update these files from a latest Fedora, Rawhide or RHEL kernel to pick up the bug fixes that have been made. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-24 10:37 ` [PATCH 01/04] Add multi-precision-integer maths library David Howells @ 2006-01-25 20:46 ` David Härdeman 2006-01-26 9:45 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Härdeman @ 2006-01-25 20:46 UTC (permalink / raw) To: David Howells; +Cc: linux-kernel On Tue, Jan 24, 2006 at 10:37:47AM +0000, David Howells wrote: >David Härdeman <david@2gen.com> wrote: > >> Adds the multi-precision-integer maths library which was originally taken >> from GnuPG and ported to the kernel by David Howells in 2004 >> (http://people.redhat.com/~dhowells/modsign/modsign-269rc4mm1-2.diff.bz2) > >You should update these files from a latest Fedora, Rawhide or RHEL kernel to >pick up the bug fixes that have been made. Somewhat confusing...I downloaded kernel-2.6.15-1.1871_FC5.src.rpm and extracted linux-2.6-modsign-mpilib.patch from the srpm. After diffing the mpi dirs created by the previously mentioned patch and that from the Fedora kernel I get: (david@austin:~/src/kernel/div)$ diff -Nurbw linux-2.6.9-rc4-mm1/crypto/mpi/ linux-902/crypto/mpi/ diff -Nurbw linux-2.6.9-rc4-mm1/crypto/mpi/mpi-div.c linux-902/crypto/mpi/mpi-div.c --- linux-2.6.9-rc4-mm1/crypto/mpi/mpi-div.c 2006-01-24 22:56:09.000000000 +0100 +++ linux-902/crypto/mpi/mpi-div.c 2006-01-24 22:55:18.000000000 +0100 @@ -101,7 +101,7 @@ MPI temp_divisor = NULL; if( quot == divisor || rem == divisor ) { - if (mpi_copy( &temp_divisor, divisor ) < 0); + if (mpi_copy( &temp_divisor, divisor ) < 0) return -ENOMEM; divisor = temp_divisor; } Was that all the difference there was or am I missing something? Re, David ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-24 10:37 ` [PATCH 01/04] Add multi-precision-integer maths library David Howells 2006-01-25 20:46 ` David Härdeman @ 2006-01-26 9:45 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: David Howells @ 2006-01-26 9:45 UTC (permalink / raw) To: David =?iso-8859-1?Q?H=E4rdeman?=; +Cc: David Howells, linux-kernel David Härdeman <david@2gen.com> wrote: > Somewhat confusing...I downloaded kernel-2.6.15-1.1871_FC5.src.rpm and > extracted linux-2.6-modsign-mpilib.patch from the srpm. After diffing the mpi > dirs created by the previously mentioned patch and that from the Fedora kernel > I get: That may be the only fix you need. Check the related patches also for overlap. David ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 00/04] Add DSA key type @ 2006-01-26 21:58 David Härdeman 2006-01-26 21:58 ` [PATCH 01/04] Add multi-precision-integer maths library David Härdeman 0 siblings, 1 reply; 25+ messages in thread From: David Härdeman @ 2006-01-26 21:58 UTC (permalink / raw) To: linux-kernel; +Cc: dhowells, keyrings, david 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(-) ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/04] Add multi-precision-integer maths library 2006-01-26 21:58 [PATCH 00/04] Add DSA key type David Härdeman @ 2006-01-26 21:58 ` David Härdeman 2006-01-27 9:28 ` Christoph Hellwig 2006-01-27 20:07 ` David Howells 0 siblings, 2 replies; 25+ messages in thread From: David Härdeman @ 2006-01-26 21:58 UTC (permalink / raw) To: linux-kernel; +Cc: dhowells, keyrings, david 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 <david@2gen.com> The patch is too large for LKML, so it's available at: http://www.hardeman.nu/~david/lkml/01-add-mpilib ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-26 21:58 ` [PATCH 01/04] Add multi-precision-integer maths library David Härdeman @ 2006-01-27 9:28 ` Christoph Hellwig 2006-01-27 20:07 ` David Howells 1 sibling, 0 replies; 25+ messages in thread From: Christoph Hellwig @ 2006-01-27 9:28 UTC (permalink / raw) To: David H?rdeman; +Cc: linux-kernel, dhowells, keyrings 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? ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-26 21:58 ` [PATCH 01/04] Add multi-precision-integer maths library David Härdeman 2006-01-27 9:28 ` Christoph Hellwig @ 2006-01-27 20:07 ` David Howells 2006-01-27 20:41 ` David Härdeman 1 sibling, 1 reply; 25+ messages in thread From: David Howells @ 2006-01-27 20:07 UTC (permalink / raw) To: Christoph Hellwig; +Cc: David H?rdeman, linux-kernel, dhowells, keyrings Christoph Hellwig <hch@infradead.org> 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-27 20:07 ` David Howells @ 2006-01-27 20:41 ` David Härdeman 2006-01-28 0:22 ` Adrian Bunk 0 siblings, 1 reply; 25+ messages in thread From: David Härdeman @ 2006-01-27 20:41 UTC (permalink / raw) To: David Howells; +Cc: Christoph Hellwig, linux-kernel, keyrings On Fri, Jan 27, 2006 at 08:07:50PM +0000, David Howells wrote: >Christoph Hellwig <hch@infradead.org> 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-27 20:41 ` David Härdeman @ 2006-01-28 0:22 ` Adrian Bunk 2006-01-28 10:46 ` David Härdeman 0 siblings, 1 reply; 25+ messages in thread From: Adrian Bunk @ 2006-01-28 0:22 UTC (permalink / raw) To: David Howells, Christoph Hellwig, linux-kernel, keyrings 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-28 0:22 ` Adrian Bunk @ 2006-01-28 10:46 ` David Härdeman 2006-01-28 13:03 ` Adrian Bunk 2006-01-29 21:09 ` Pavel Machek 0 siblings, 2 replies; 25+ messages in thread From: David Härdeman @ 2006-01-28 10:46 UTC (permalink / raw) To: Adrian Bunk; +Cc: David Howells, Christoph Hellwig, linux-kernel, keyrings 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-28 10:46 ` David Härdeman @ 2006-01-28 13:03 ` Adrian Bunk 2006-01-28 17:09 ` David Härdeman 2006-01-29 21:09 ` Pavel Machek 1 sibling, 1 reply; 25+ messages in thread From: Adrian Bunk @ 2006-01-28 13:03 UTC (permalink / raw) To: David Howells, Christoph Hellwig, linux-kernel, keyrings 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-28 13:03 ` Adrian Bunk @ 2006-01-28 17:09 ` David Härdeman 0 siblings, 0 replies; 25+ messages in thread From: David Härdeman @ 2006-01-28 17:09 UTC (permalink / raw) To: Adrian Bunk; +Cc: David Howells, Christoph Hellwig, linux-kernel, keyrings 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/04] Add multi-precision-integer maths library 2006-01-28 10:46 ` David Härdeman 2006-01-28 13:03 ` Adrian Bunk @ 2006-01-29 21:09 ` Pavel Machek 1 sibling, 0 replies; 25+ messages in thread From: Pavel Machek @ 2006-01-29 21:09 UTC (permalink / raw) To: Adrian Bunk, David Howells, Christoph Hellwig, linux-kernel, keyrings 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! ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2006-01-29 21:09 UTC | newest] Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <11380489522552@2gen.com> 2006-01-23 20:42 ` [PATCH 02/04] Add dsa crypto ops David Härdeman 2006-01-23 20:42 ` [PATCH 03/04] Add encryption ops to the keyctl syscall David Härdeman 2006-01-23 20:42 ` [PATCH 04/04] Add dsa key type David Härdeman 2006-01-24 11:08 ` David Howells 2006-01-25 19:14 ` David Härdeman 2006-01-26 9:41 ` David Howells 2006-01-24 4:33 ` [PATCH 03/04] Add encryption ops to the keyctl syscall Randy.Dunlap 2006-01-24 10:58 ` David Howells 2006-01-25 20:40 ` David Härdeman 2006-01-26 9:43 ` David Howells 2006-01-24 11:09 ` David Howells 2006-01-24 1:22 ` [PATCH 02/04] Add dsa crypto ops Herbert Xu 2006-01-24 6:49 ` David Härdeman 2006-01-24 10:37 ` [PATCH 01/04] Add multi-precision-integer maths library David Howells 2006-01-25 20:46 ` David Härdeman 2006-01-26 9:45 ` David Howells 2006-01-26 21:58 [PATCH 00/04] Add DSA key type David Härdeman 2006-01-26 21:58 ` [PATCH 01/04] Add multi-precision-integer maths library David Härdeman 2006-01-27 9:28 ` Christoph Hellwig 2006-01-27 20:07 ` David Howells 2006-01-27 20:41 ` David Härdeman 2006-01-28 0:22 ` Adrian Bunk 2006-01-28 10:46 ` David Härdeman 2006-01-28 13:03 ` Adrian Bunk 2006-01-28 17:09 ` David Härdeman 2006-01-29 21:09 ` Pavel Machek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).