Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S266163AbUIVPjq (ORCPT ); Wed, 22 Sep 2004 11:39:46 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S266170AbUIVPjq (ORCPT ); Wed, 22 Sep 2004 11:39:46 -0400 Received: from imr1.ericy.com ([198.24.6.9]:45796 "EHLO imr1.ericy.com") by vger.kernel.org with ESMTP id S266163AbUIVPid (ORCPT ); Wed, 22 Sep 2004 11:38:33 -0400 Message-ID: <41519A2C.2090705@ericsson.com> Date: Wed, 22 Sep 2004 11:28:44 -0400 From: Makan Pourzandi User-Agent: Mozilla Thunderbird 0.8 (X11/20040913) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Chris Wright CC: "Serge E. Hallyn" , linux-kernel@vger.kernel.org, Axelle Apvrille , serue@us.ibm.com, "David Gordon (QB/EMC)" , gaspoucho@yahoo.com Subject: Re: [ANNOUNCE] Release Digsig 1.3.1: kernel module for run-time a uthentication of binaries References: <21A5F45EFF209A44B3057E35CE1FE6E4BC415F@eammlex037.lmc.ericsson.se> <20040911125526.T1924@build.pdx.osdl.net> In-Reply-To: <20040911125526.T1924@build.pdx.osdl.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 40585 Lines: 1232 Hi all, We integrated Chris's patch to our cvs source code base. There is a new release 1.3.2 at our sourceforge site: http://sourceforge.net/projects/disec/. Best Regards, Makan Chris Wright wrote: > * Makan Pourzandi (QB/EMC) (makan.pourzandi@ericsson.com) wrote: > >>Thanks a lot for your feedback. We'll work on the modifications in >>the source code mentioned in your email and send out a new release >>hopefully soon. > > > Here's a patch with a bunch of cleanups: > (sorry it's one big patch, just kept growing...) > > - white space and braces cleanups > - NULL pointer checks unified as (!ptr) > - fixup confusion on ERR_PTR vs. NULL (fixes Oopsen) > - cast on kmalloc is unecessary > - make anyting static that can be > - functions > - variables (and remove redundany 0 initialization for static vars) > - use static initializers for things like semaphores, lists, locks > - remove set_digsig_ops/security_set_operations in favor of > statically initiaized digsig_security_ops > - name change digsig_attribute_st -> digsig_attribute > - introduce DIGSIG_ATTR macro, and use for attribute initialization > - change names of sysfs files (in module, and hopefully supporting scripts > and programs) > - digsig_interface -> key > - digsig_revoke -> revoke > - move extern defs to header files > - get ifndef/define header bits correct > - move towards single point of return (goto and error cleanup) > - fixup memory leaks on error return paths > - move towards use of error values rather than just -1 > - move ctx cleanup out of digsig_sign_verify_final so that caller is > responsible (less confusion and no chance of double free on error > cleanup) > - mark init functions as __init > - use security_initcall() > - remove unneeded digsig_init_revocation (list statically initialized now) > - remove inline on external functions > - use list_for_each_entry > - collapse 'n' and 'e' cases in digsig_key_store for raw_public_key allocation > - remove redundant file->f_security = NULL after digsig_allow_write_access() > - move list_add_tail() in dsi_sysfs for revoked key into digsig_revocation.c > under helper digsig_add_revoked_sig() > - add revoked_list_lock (used in above helper) for proper list manipulation > - s/SHA1_TFM/sha1_tfm/ ala CodingStyle > - fix bogus ctx==NULL check in digsig_sign_verify_update() > > It compiles, and I actually loaded it and ran some tests to make sure > it still works. Seems OK. I didn't work at stressing any of the error > paths, but I think they are cleaner than they were. > > thanks, > -chris > > diff -paur digsig-1.3.1.orig/digsig.c digsig-1.3.1/digsig.c > --- digsig-1.3.1.orig/digsig.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/digsig.c 2004-09-11 11:11:31.000000000 -0700 > @@ -60,18 +60,16 @@ > #define get_file_security(file) ((unsigned long)(file->f_security)) > #define set_file_security(file,val) (file->f_security = (void *)val) > > -extern MPI digsig_public_key[2]; /* dsi_sig_verify.c */ > - > unsigned long int total_jiffies = 0; > > /* Allocate and free functions for each kind of security blob. */ > -static struct semaphore digsig_sem; > +static DECLARE_MUTEX(digsig_sem); > > /* Indicate if module as key or not */ > int g_init = 0; > > /* Keep track of how we are registered */ > -int secondary = 0; > +static int secondary; > > #ifdef DIGSIG_LOG > int DigsigDebugLevel = DEBUG_INIT | DEBUG_SIGN; > @@ -84,9 +82,6 @@ int digsig_max_cached_sigs = 512; > module_param(digsig_max_cached_sigs, int, 0); > MODULE_PARM_DESC(digsig_max_cached_sigs, "Number of signatures to keep cached\n"); > > -/* Number of signature validations cached so far */ > -int digsig_num_cached_sigs = 0; > - > /****************************************************************************** > Description : > * For a file being opened for write, check: > @@ -141,13 +136,6 @@ digsig_inode_unlink(struct inode *dir, s > return 0; > } > > -struct security_operations digsig_security_ops; > - > -#define set_digsig_ops(ops, function) \ > - if (!ops->function) { \ > - ops->function = digsig_##function; \ > - } > - > static int > digsig_verify_signature(Elf32_Shdr * elf_shdata, > char *sig_orig, struct file *file, int sh_offset); > @@ -195,7 +183,7 @@ static char *digsig_find_signature(struc > return NULL; > } > > - buffer = (char *) kmalloc(DIGSIG_ELF_SIG_SIZE, DIGSIG_SAFE_ALLOC); > + buffer = kmalloc(DIGSIG_ELF_SIG_SIZE, DIGSIG_SAFE_ALLOC); > if (!buffer) { > DSM_ERROR ("kmalloc failed in %s for buffer.\n", __FUNCTION__); > return NULL; > @@ -231,62 +219,50 @@ static int > digsig_verify_signature(Elf32_Shdr * elf_shdata, > char *sig_orig, struct file *file, int sh_offset) > { > - char *sig_result, *read_blocks; > - int retval, offset; > - unsigned int size; > + char *sig_result = NULL, *read_blocks = NULL; > + int retval = -EPERM, offset; > unsigned int lower, upper; > - SIGCTX *ctx; > + loff_t i_size; > + SIGCTX *ctx = NULL; > > down (&digsig_sem); > if (digsig_is_revoked_sig(sig_orig)) { > DSM_ERROR("%s: Refusing attempt to load an ELF file with" > " a revoked signature.\n", __FUNCTION__); > - up (&digsig_sem); > - return -EPERM; > + goto out; > } > > - if ((ctx = digsig_sign_verify_init(HASH_SHA1, SIGN_RSA)) == NULL) { > + retval = -ENOMEM; > + ctx = digsig_sign_verify_init(HASH_SHA1, SIGN_RSA); > + if (!ctx ) { > DSM_PRINT(DEBUG_SIGN, > "%s: Cannot allocate crypto context.\n", __FUNCTION__); > - up (&digsig_sem); > - return -ENOMEM; > + goto out; > } > > - sig_result = (char *) kmalloc(DIGSIG_ELF_SIG_SIZE, DIGSIG_SAFE_ALLOC); > + sig_result = kmalloc(DIGSIG_ELF_SIG_SIZE, DIGSIG_SAFE_ALLOC); > if (!sig_result) { > DSM_ERROR ("kmalloc failed in %s for sig_result.\n", __FUNCTION__); > - kfree (ctx->tvmem); > - kfree (ctx); > - up (&digsig_sem); > - return -ENOMEM; > + goto out; > } > - read_blocks = (char *) kmalloc(DIGSIG_ELF_READ_BLOCK_SIZE, DIGSIG_SAFE_ALLOC); > + read_blocks = kmalloc(DIGSIG_ELF_READ_BLOCK_SIZE, DIGSIG_SAFE_ALLOC); > if (!read_blocks) { > DSM_ERROR ("kmalloc failed in %s for read_block.\n", __FUNCTION__); > - kfree (ctx->tvmem); > - kfree (ctx); > - kfree (sig_result); > - up (&digsig_sem); > - return -ENOMEM; > + goto out; > } > > memset(sig_result, 0, DIGSIG_ELF_SIG_SIZE); > > - for (offset = 0; offset < file->f_dentry->d_inode->i_size; > - offset += DIGSIG_ELF_READ_BLOCK_SIZE) { > + i_size = i_size_read(file->f_dentry->d_inode); > + for (offset = 0; offset < i_size; offset += DIGSIG_ELF_READ_BLOCK_SIZE){ > > - size = kernel_read(file, offset, (char *) read_blocks, > + retval = kernel_read(file, offset, (char *) read_blocks, > DIGSIG_ELF_READ_BLOCK_SIZE); > - if (size <= 0) { > + if (retval <= 0) { > DSM_PRINT(DEBUG_SIGN, > "%s: Unable to read signature in blocks: %d\n", > - __FUNCTION__, size); > - kfree(sig_result); > - kfree(read_blocks); > - kfree(ctx->tvmem); > - kfree(ctx); > - up (&digsig_sem); > - return -1; > + __FUNCTION__, retval); > + goto out; > } > > /* Makan: This is in order to avoid building a buffer > @@ -308,31 +284,32 @@ digsig_verify_signature(Elf32_Shdr * elf > } > > /* continue verification loop */ > - if (digsig_sign_verify_update(ctx, read_blocks, size) != 0) { > + retval = digsig_sign_verify_update(ctx, read_blocks, retval); > + if (retval < 0) { > DSM_PRINT(DEBUG_SIGN, > "%s: Error updating crypto verification\n", __FUNCTION__); > - kfree(sig_result); > - kfree(read_blocks); > - kfree(ctx->tvmem); > - kfree(ctx); > - up (&digsig_sem); > - return -1; > + goto out; > } > } > > /* A bit of bsign formatting else hashes won't match, works with bsign v0.4.4 */ > - if ((retval = digsig_sign_verify_final(ctx, sig_result, DIGSIG_ELF_SIG_SIZE, > - sig_orig + DIGSIG_BSIGN_INFOS)) < 0) { > + retval = digsig_sign_verify_final(ctx, sig_result, DIGSIG_ELF_SIG_SIZE, > + sig_orig + DIGSIG_BSIGN_INFOS); > + if (retval < 0) { > DSM_PRINT(DEBUG_SIGN, > "%s: Error calculating final crypto verification\n", __FUNCTION__); > - kfree(sig_result); > - kfree(read_blocks); > - up (&digsig_sem); > - return -1; > + goto out; > } > > + retval = 0; > + > +out: > kfree(sig_result); > kfree(read_blocks); > + if (ctx) { > + kfree(ctx->tvmem); > + kfree(ctx); > + } > up (&digsig_sem); > return retval; > } > @@ -382,7 +359,7 @@ static void digsig_allow_write_access(st > * file->f_security>0, and we decrement the inode usage count to > * show that we are done with it. > */ > -void digsig_file_free_security(struct file *file) > +static void digsig_file_free_security(struct file *file) > { > if (file->f_security) { > digsig_allow_write_access(file); > @@ -426,18 +403,17 @@ static inline struct elfhdr *read_elf_he > { > struct elfhdr *elf_ex; > > - elf_ex = > - (struct elfhdr *)kmalloc(sizeof(struct elfhdr), DIGSIG_SAFE_ALLOC); > + elf_ex = kmalloc(sizeof(struct elfhdr), DIGSIG_SAFE_ALLOC); > if (!elf_ex) { > DSM_ERROR ("%s: kmalloc failed for elf_ex\n", __FUNCTION__); > - return NULL; > + return ERR_PTR(-ENOMEM); > } > > kernel_read(file, 0, (char *)elf_ex, sizeof(struct elfhdr)); > > if (elf_sanity_check(elf_ex)) { > kfree(elf_ex); > - return NULL; > + return ERR_PTR(-EINVAL); > } > > return elf_ex; > @@ -449,7 +425,7 @@ read_section_header(struct file *file, i > Elf32_Shdr *elf_shdata; > int retval; > > - elf_shdata = (Elf32_Shdr *) kmalloc(sh_size, DIGSIG_SAFE_ALLOC); > + elf_shdata = kmalloc(sh_size, DIGSIG_SAFE_ALLOC); > if (!elf_shdata) { > DSM_ERROR("%s: Cannot allocate memory to read Section Header\n", > __FUNCTION__); > @@ -493,7 +469,7 @@ static inline int is_unprotected_file(st > __FUNCTION__, file->f_dentry->d_name.name, exec_time); \ > } > > -int digsig_file_mmap(struct file * file, unsigned long prot, unsigned long flags) > +static int digsig_file_mmap(struct file * file, unsigned long prot, unsigned long flags) > { > struct elfhdr *elf_ex; > int retval, sh_offset; > @@ -566,7 +542,7 @@ int digsig_file_mmap(struct file * file, > } > > /* Verify binary's signature */ > - retval = digsig_verify_signature (elf_shdata, sig_orig, file, sh_offset); > + retval = digsig_verify_signature(elf_shdata, sig_orig, file, sh_offset); > > if (!retval) { > DSM_PRINT(DEBUG_SIGN, > @@ -587,71 +563,67 @@ int digsig_file_mmap(struct file * file, > kfree (sig_orig); > out_free_shdata: > kfree (elf_shdata); > - > out_with_file: > kfree (elf_ex); > out_file_no_buf: > - if (allow_write_on_exit) { > + if (allow_write_on_exit) > digsig_allow_write_access(file); > - file->f_security = NULL; > - } > > end_digsig_bench; > > return retval; > } > > -void security_set_operations(struct security_operations *ops) > -{ > - set_digsig_ops(ops, file_mmap); > - set_digsig_ops(ops, file_free_security); > - set_digsig_ops(ops, inode_permission); > - set_digsig_ops(ops, inode_unlink); > -} > +static struct security_operations digsig_security_ops = { > + .file_mmap = digsig_file_mmap, > + .file_free_security = digsig_file_free_security, > + .inode_permission = digsig_inode_permission, > + .inode_unlink = digsig_inode_unlink, > +}; > > static int __init digsig_init_module(void) > { > + int ret = -ENOMEM; > DSM_PRINT(DEBUG_INIT, "Initializing module\n"); > > /* initialize caching mechanisms */ > > - if (digsig_init_caching()){ > - return -ENOMEM; > - } > - digsig_init_revocation(); > + if (digsig_init_caching()) > + goto out; > > - /* initialize DigSig's hooks */ > - security_set_operations(&digsig_security_ops); > + ret = -EINVAL; > + if (digsig_init_sysfs()) { > + DSM_ERROR("Error setting up sysfs for DigSig\n"); > + goto out_cache; > + } > > /* register */ > - if (register_security (&digsig_security_ops)) { > - DSM_ERROR ("%s: Failure registering DigSig as primairy security module\n", __FUNCTION__); > - if (mod_reg_security ("digsig_verif", &digsig_security_ops)) { > - DSM_ERROR ("%s: Failure registering DigSig as secondary module\n", __FUNCTION__); > - return -EINVAL; > + if (register_security(&digsig_security_ops)) { > + DSM_ERROR("%s: Failure registering DigSig as primairy security module\n", __FUNCTION__); > + if (mod_reg_security("digsig_verif", &digsig_security_ops)) { > + DSM_ERROR("%s: Failure registering DigSig as secondary module\n", __FUNCTION__); > + goto out_sysfs; > } > - DSM_PRINT (DEBUG_INIT, "Registered as secondary module\n"); > + DSM_PRINT(DEBUG_INIT, "Registered as secondary module\n"); > secondary = 1; > } > - > - init_MUTEX (&digsig_sem); > - > - if (digsig_init_sysfs()) { > - DSM_ERROR("Error setting up sysfs for DigSig\n"); > - return -EINVAL; > - } > - > return 0; > +out_sysfs: > + digsig_cleanup_sysfs(); > +out_cache: > + digsig_cache_cleanup(); > +out: > + return ret; > } > > static void __exit digsig_exit_module(void) > { > DSM_PRINT (DEBUG_INIT, "Deinitializing module\n"); > g_init = 0; > - digsig_sign_verify_free (); > - digsig_cleanup_sysfs (); > - digsig_cleanup_revocation (); > - digsig_cache_cleanup (); > + digsig_sign_verify_free(); > + digsig_cleanup_sysfs(); > + digsig_cleanup_revocation(); > + digsig_cache_cleanup(); > mpi_free(digsig_public_key[0]); > mpi_free(digsig_public_key[1]); > if (secondary) { > @@ -666,7 +638,7 @@ static void __exit digsig_exit_module(vo > } > } > > -module_init(digsig_init_module); > +security_initcall(digsig_init_module); > module_exit(digsig_exit_module); > > /* see linux/module.h */ > diff -paur digsig-1.3.1.orig/digsig_cache.c digsig-1.3.1/digsig_cache.c > --- digsig-1.3.1.orig/digsig_cache.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/digsig_cache.c 2004-09-11 09:11:01.000000000 -0700 > @@ -33,10 +33,9 @@ > #define DIGSIG_BENCH 0 > #endif > > -extern int DigsigDebugLevel; > - > -extern int digsig_max_cached_sigs, digsig_num_cached_sigs; > -extern int g_init; > +extern int digsig_max_cached_sigs; > +/* Number of signature validations cached so far */ > +static int digsig_num_cached_sigs; > > /* > * digsig_hash_table: > @@ -71,8 +70,8 @@ struct digsig_hash_table { > struct digsig_hash_table *prev; /* only set if dynamically alloced */ > }; > > -static struct digsig_hash_table *sig_cache = NULL; > -static struct list_head sig_cache_lru; > +static struct digsig_hash_table *sig_cache; > +static LIST_HEAD(sig_cache_lru); > static spinlock_t sig_cache_spinlock = SPIN_LOCK_UNLOCKED; > > /****************************************************************************** > @@ -177,7 +176,7 @@ Description : > Parameters : @num: number of cached sig validation entries to clear. > Return value: number of entries actually deleted. > ******************************************************************************/ > -int digsig_purge_cache(int num) > +static int digsig_purge_cache(int num) > { > int i=0; > struct digsig_hash_table *tmph, *del; > @@ -313,7 +312,7 @@ Description : Initialize caching > Parameters : none > Return value: 0 on success, 1 on failure. > ******************************************************************************/ > -int digsig_init_caching(void) > +int __init digsig_init_caching(void) > { > int tmp; > > @@ -321,7 +320,7 @@ int digsig_init_caching(void) > sizeof(struct digsig_hash_table), GFP_ATOMIC); > /* GFP_KERNEL); */ > > - if (IS_ERR(sig_cache)) { > + if (!sig_cache) { > DSM_PRINT(DEBUG_ERROR, "No memory to initialize digsig cache.\n"); > return 1; > } > @@ -333,10 +332,7 @@ int digsig_init_caching(void) > sig_cache[tmp].orig = 1; > } > > - INIT_LIST_HEAD(&sig_cache_lru); > - > return 0; > - > } > > /* > diff -paur digsig-1.3.1.orig/digsig_cache.h digsig-1.3.1/digsig_cache.h > --- digsig-1.3.1.orig/digsig_cache.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/digsig_cache.h 2004-09-11 10:53:49.000000000 -0700 > @@ -15,16 +15,17 @@ > * > */ > > -#ifndef __DSI_CACHE_H > +#ifndef _DSI_CACHE_H > +#define _DSI_CACHE_H > > #include > #include "gnupg/mpi/mpi.h" > > int is_cached_signature(struct inode *inode); > void remove_signature(struct inode *inode); > -int digsig_purge_cache(int num); > void digsig_cache_signature(struct inode *inode); > int digsig_init_caching(void); > void digsig_cache_cleanup(void); > > -#endif > +#endif /* _DSI_CACHE_H */ > + > diff -paur digsig-1.3.1.orig/digsig.init digsig-1.3.1/digsig.init > --- digsig-1.3.1.orig/digsig.init 2004-04-27 06:49:36.000000000 -0700 > +++ digsig-1.3.1/digsig.init 2004-09-11 11:55:40.000000000 -0700 > @@ -47,7 +47,7 @@ case "$1" in > echo "Catting revoked sigs into revocation list" > if [ -d $REVKEY_DIR ]; then > for name in `/bin/ls $REVKEY_DIR`; do > - /bin/cat $REVKEY_DIR/$name > /sys/digsig/digsig_revoke > + /bin/cat $REVKEY_DIR/$name > /sys/digsig/revoke > done > fi > echo "Loading public key." > diff -paur digsig-1.3.1.orig/digsig_revocation.c digsig-1.3.1/digsig_revocation.c > --- digsig-1.3.1.orig/digsig_revocation.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/digsig_revocation.c 2004-09-11 12:09:25.558845224 -0700 > @@ -34,10 +34,8 @@ > #define DIGSIG_BENCH 0 > #endif > > -extern int DigsigDebugLevel; > - > -extern int digsig_max_hashed_sigs, digsig_num_hashed_sigs; > -struct list_head digsig_revoked_sigs; > +static LIST_HEAD(digsig_revoked_sigs); > +static spinlock_t revoked_list_lock = SPIN_LOCK_UNLOCKED; > > /* > * Description: Called at module unload to free the list of revoked > @@ -48,6 +46,7 @@ void digsig_free_revoked_sigs(void) > struct list_head *tmp; > struct revoked_sig *rsig; > > + spin_lock(&revoked_list_lock); > while (!list_empty(&digsig_revoked_sigs)) { > tmp = digsig_revoked_sigs.next; > if (tmp != &digsig_revoked_sigs) { > @@ -57,9 +56,10 @@ void digsig_free_revoked_sigs(void) > kfree(rsig); > } else { > DSM_ERROR("major list screwyness\n"); > - return; > + break; > } > } > + spin_unlock(&revoked_list_lock); > } > > /* > @@ -70,33 +70,34 @@ void digsig_free_revoked_sigs(void) > #ifdef DIGSIG_REVOCATION > int digsig_is_revoked_sig(char *buffer) > { > - struct list_head *tmp; > struct revoked_sig *rsig; > char *tmp1 = buffer + DIGSIG_BSIGN_INFOS + DIGSIG_RSA_DATA_OFFSET; > int count = DIGSIG_ELF_SIG_SIZE - DIGSIG_BSIGN_INFOS - DIGSIG_RSA_DATA_OFFSET; > int ret = 0; > MPI file_sig = mpi_read_from_buffer(tmp1, &count, 0); > > - list_for_each(tmp, &digsig_revoked_sigs) { > - rsig = list_entry(tmp, struct revoked_sig, next); > + spin_lock(&revoked_list_lock); > + list_for_each_entry(rsig, &digsig_revoked_sigs, next) { > if (mpi_cmp(file_sig, rsig->sig) == 0) { > ret = 1; > goto out; > } > } > - > out: > + spin_unlock(&revoked_list_lock); > mpi_free(file_sig); > return ret; > } > #endif > > -inline void digsig_init_revocation() > +void digsig_add_revoked_sig(struct revoked_sig *sig) > { > - INIT_LIST_HEAD(&digsig_revoked_sigs); > + spin_lock(&revoked_list_lock); > + list_add_tail(&sig->next, &digsig_revoked_sigs); > + spin_unlock(&revoked_list_lock); > } > > -inline void digsig_cleanup_revocation() > +void digsig_cleanup_revocation(void) > { > digsig_free_revoked_sigs(); > } > diff -paur digsig-1.3.1.orig/digsig_revocation.h digsig-1.3.1/digsig_revocation.h > --- digsig-1.3.1.orig/digsig_revocation.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/digsig_revocation.h 2004-09-11 10:54:03.000000000 -0700 > @@ -15,19 +15,12 @@ > * > */ > > -#ifndef __DSI_REVOKE_H > +#ifndef _DSI_REVOKE_H > +#define _DSI_REVOKE_H > > #include > #include "gnupg/mpi/mpi.h" > > -void digsig_init_revocation(void); > -void digsig_cleanup_revocation(void); > -#ifdef DIGSIG_REVOCATION > -int digsig_is_revoked_sig(char *buffer); > -#else > -#define digsig_is_revoked_sig(x) 0 > -#endif > - > /* > * A linear array of revoked signatures. > * > @@ -39,4 +32,14 @@ struct revoked_sig { > MPI sig; > }; > > +void digsig_init_revocation(void); > +void digsig_cleanup_revocation(void); > +void digsig_add_revoked_sig(struct revoked_sig *sig); > +#ifdef DIGSIG_REVOCATION > +int digsig_is_revoked_sig(char *buffer); > +#else > +#define digsig_is_revoked_sig(x) 0 > #endif > + > +#endif /* _DSI_REVOKE_H */ > + > diff -paur digsig-1.3.1.orig/dsi_debug.h digsig-1.3.1/dsi_debug.h > --- digsig-1.3.1.orig/dsi_debug.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi_debug.h 2004-09-11 10:56:06.000000000 -0700 > @@ -18,8 +18,8 @@ > */ > > > -#ifndef __DSI_DEBUG_H > -#define __DSI_DEBUG_H > +#ifndef _DSI_DEBUG_H > +#define _DSI_DEBUG_H > > #define DIGSIG_MODULE_NAME "DIGSIG MODULE" > > @@ -63,4 +63,4 @@ extern int DigsigDebugLevel; > #define DSM_PRINT_NO_PREFIX(dbg,fmt,arg...) \ > if (dbg & DigsigDebugLevel) printk(fmt,##arg) > > -#endif /* __DSI_DEBUG_H */ > +#endif /* _DSI_DEBUG_H */ > diff -paur digsig-1.3.1.orig/dsi.h digsig-1.3.1/dsi.h > --- digsig-1.3.1.orig/dsi.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi.h 2004-09-11 10:56:12.000000000 -0700 > @@ -20,8 +20,8 @@ > */ > > > -#ifndef __DSI_H > -#define __DSI_H > +#ifndef _DSI_H > +#define _DSI_H > > #ifdef MODULE > #include > @@ -49,4 +49,6 @@ > > #endif /* MODULE */ > > -#endif > +extern int g_init; > + > +#endif /* _DSI_H */ > diff -paur digsig-1.3.1.orig/dsi_sig_verify.c digsig-1.3.1/dsi_sig_verify.c > --- digsig-1.3.1.orig/dsi_sig_verify.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi_sig_verify.c 2004-09-11 11:21:59.000000000 -0700 > @@ -33,12 +33,10 @@ > * n bytes: MPI (ie. 0x29) > */ > > -extern int DigsigDebugLevel; > - > #define TVMEMSIZE 4096 > > int gDigestLength[] = { /* SHA-1 */ 0x14 }; > -static struct crypto_tfm *SHA1_TFM = NULL; > +static struct crypto_tfm *sha1_tfm; > MPI digsig_public_key[] = {MPI_NULL, MPI_NULL}; > > > @@ -70,17 +68,16 @@ SIGCTX *digsig_sign_verify_init(int hash > SIGCTX *ctx; > > /* allocating signature context */ > - ctx = (SIGCTX *) kmalloc(sizeof(SIGCTX), GFP_KERNEL); > - if (ctx == NULL) { > + ctx = kmalloc(sizeof(SIGCTX), GFP_KERNEL); > + if (!ctx) { > DSM_ERROR("Cannot allocate ctx\n"); > - return NULL; > + goto err; > } > > ctx->tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); > - if (ctx->tvmem == NULL) { > - kfree(ctx); > + if (!ctx->tvmem) { > DSM_ERROR("Cannot allocate plaintext buffer\n"); > - return NULL; > + goto err; > } > > /* checking hash algorithm is known */ > @@ -88,16 +85,12 @@ SIGCTX *digsig_sign_verify_init(int hash > case HASH_SHA1: > if (digsig_sha1_init(ctx)) { > DSM_ERROR("Initializing SHA1 failed\n"); > - kfree(ctx->tvmem); > - kfree(ctx); > - return NULL; > + goto err; > } > break; > default: > DSM_ERROR("Unknown hash algo\n"); > - kfree(ctx->tvmem); > - kfree(ctx); > - return NULL; > + goto err; > } > > /* checking sign algo is known */ > @@ -106,13 +99,18 @@ SIGCTX *digsig_sign_verify_init(int hash > break; > default: > DSM_ERROR("Unknown sign algo\n"); > - kfree(ctx->tvmem); > - kfree(ctx); > - return NULL; > + goto err; > } > ctx->digestAlgo = hashalgo; > ctx->signAlgo = signalgo; > return ctx; > + > +err: > + if (ctx) { > + kfree(ctx->tvmem); > + kfree(ctx); > + } > + return NULL; > } > > /****************************************************************************** > @@ -125,17 +123,16 @@ Return value: 0 normally > ******************************************************************************/ > int digsig_sign_verify_update(SIGCTX * ctx, char *buf, int buflen) > { > + if (ctx == NULL) > + return -EINVAL; > + > switch (ctx->digestAlgo) { > case HASH_SHA1: > - if (ctx == NULL) { > - return -1; > - } > - > digsig_sha1_update(ctx, buf, buflen); > break; > default: > DSM_ERROR("%s: Unknown hash algo\n", __FUNCTION__); > - return -1; > + return -EINVAL; > } > > return 0; > @@ -151,30 +148,24 @@ digsig_sign_verify_final(SIGCTX * ctx, c > unsigned char *signed_hash) > { > char *digest; > - int rc = -1; > + int rc = -ENOMEM; > > digest = kmalloc (gDigestLength[ctx->digestAlgo], DIGSIG_SAFE_ALLOC); > if (!digest) { > DSM_ERROR ("kmalloc failed in %s for digest\n", __FUNCTION__); > - return -ENOMEM; > + goto err; > } > /* TO DO: check the length of the signature: it should be equal to the length > of the modulus */ > if ((rc = digsig_sha1_final(ctx, digest)) < 0) { > DSM_ERROR > ("%s: Cannot finalize hash algorithm\n", __FUNCTION__); > - kfree(ctx->tvmem); > - kfree(ctx); > - kfree (digest); > - return rc; > + goto err; > } > > - if (siglen < gDigestLength[ctx->digestAlgo]) { > - kfree(ctx->tvmem); > - kfree(ctx); > - kfree (digest); > - return -2; > - } > + rc = -EINVAL; > + if (siglen < gDigestLength[ctx->digestAlgo]) > + goto err; > memcpy(sig, digest, gDigestLength[ctx->digestAlgo]); > > switch (ctx->digestAlgo) { > @@ -190,8 +181,7 @@ digsig_sign_verify_final(SIGCTX * ctx, c > > /* free everything */ > /* do not free SHA1-TFM. For optimization, we choose always to use the same one */ > - kfree(ctx->tvmem); > - kfree(ctx); > +err: > kfree (digest); > return rc; > } > @@ -203,11 +193,11 @@ Description : > Parameters : > Return value: > ******************************************************************************/ > -void digsig_sign_verify_free() > +void digsig_sign_verify_free(void) > { > - if (SHA1_TFM) { > - crypto_free_tfm(SHA1_TFM); > - SHA1_TFM = NULL; > + if (sha1_tfm) { > + crypto_free_tfm(sha1_tfm); > + sha1_tfm = NULL; > } > /* this might cause unpredictable behavior if structures are refering to this, > their pointer might suddenly become NULL, might need a usage count associated */ > @@ -252,7 +242,7 @@ Return value: 0 - RSA signature is valid > -1 - an error occured > ******************************************************************************/ > > -int digsig_rsa_bsign_verify(unsigned char *hash_format, int length, > +static int digsig_rsa_bsign_verify(unsigned char *hash_format, int length, > unsigned char *signed_hash) > { > int rc = 0; > @@ -265,7 +255,7 @@ int digsig_rsa_bsign_verify(unsigned cha > SIGCTX *ctx = NULL; > unsigned char *new_sig; > > - new_sig = kmalloc (gDigestLength[HASH_SHA1], DIGSIG_SAFE_ALLOC); > + new_sig = kmalloc(gDigestLength[HASH_SHA1], DIGSIG_SAFE_ALLOC); > if (!new_sig) { > DSM_ERROR ("kmalloc failed in %s for new_sig\n", __FUNCTION__); > return -ENOMEM; > @@ -274,18 +264,20 @@ int digsig_rsa_bsign_verify(unsigned cha > /* Get MPI of signed data from .sig file/section */ > nread = DIGSIG_ELF_SIG_SIZE; > > - data = mpi_read_from_buffer(signed_hash + DIGSIG_RSA_DATA_OFFSET, &nread, > - 0); > - if (!data) > + data = mpi_read_from_buffer(signed_hash + DIGSIG_RSA_DATA_OFFSET, > + &nread, 0); > + if (!data) { > + kfree(new_sig); > return -EINVAL; > + } > > /* Get MPI for hash */ > /* bsign modif - file hash - gpg modif */ > /* bsign modif: add bsign greet at beginning */ > /* gpg modif: add class and timestamp at end */ > > - ctx = (SIGCTX *) kmalloc(sizeof(SIGCTX), GFP_KERNEL); > - if (ctx == NULL) { > + ctx = kmalloc(sizeof(SIGCTX), GFP_KERNEL); > + if (!ctx) { > DSM_ERROR("Cannot allocate ctx\n"); > mpi_free (data); > kfree (new_sig); > @@ -293,7 +285,7 @@ int digsig_rsa_bsign_verify(unsigned cha > } > > ctx->tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); > - if (ctx->tvmem == NULL) { > + if (!ctx->tvmem) { > kfree (ctx); > mpi_free(data); > kfree (new_sig); > @@ -356,9 +348,9 @@ static int digsig_sha1_init(SIGCTX * ctx > if (ctx == NULL) > return -1; > > - if (SHA1_TFM == NULL) > - SHA1_TFM = crypto_alloc_tfm("sha1", 0); > - ctx->tfm = SHA1_TFM; > + if (sha1_tfm == NULL) > + sha1_tfm = crypto_alloc_tfm("sha1", 0); > + ctx->tfm = sha1_tfm; > if (ctx->tfm == NULL) { > DSM_ERROR("tfm allocation failed\n"); > return -1; > @@ -392,7 +384,7 @@ static void digsig_sha1_update(SIGCTX * > /****************************************************************************** > Description : Portability layer function. > Parameters : > -Return value: 0 for successful allocation, -1 for failed > +Return value: 0 for successful allocation, -EINVAL for failed > ******************************************************************************/ > > static int digsig_sha1_final(SIGCTX * ctx, char *digest) > @@ -401,7 +393,7 @@ static int digsig_sha1_final(SIGCTX * ct > of the modulus */ > > if (ctx == NULL) > - return -1; > + return -EINVAL; > > crypto_digest_final(ctx->tfm, digest); > return 0; > diff -paur digsig-1.3.1.orig/dsi_sig_verify.h digsig-1.3.1/dsi_sig_verify.h > --- digsig-1.3.1.orig/dsi_sig_verify.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi_sig_verify.h 2004-09-11 10:52:10.000000000 -0700 > @@ -14,8 +14,8 @@ > * David Gordon > */ > > -#ifndef _DSI_SIG_VERIFY_H_ > -#define _DSI_SIG_VERIFY_H_ > +#ifndef _DSI_SIG_VERIFY_H > +#define _DSI_SIG_VERIFY_H > > #include > #include > @@ -79,6 +79,7 @@ typedef struct sig_ctx_st { > } SIGCTX; > > extern int gDigestLength[1]; > +extern MPI digsig_public_key[]; > > SIGCTX *digsig_sign_verify_init(int hashalgo, int signalgo); > int digsig_sign_verify_update(SIGCTX * ctx, char *buf, int buflen); > @@ -90,4 +91,4 @@ int digsig_init_pkey(const char read_par > > > > -#endif > +#endif /* _DSI_SIG_VERIFY_H */ > diff -paur digsig-1.3.1.orig/dsi_sysfs.c digsig-1.3.1/dsi_sysfs.c > --- digsig-1.3.1.orig/dsi_sysfs.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi_sysfs.c 2004-09-11 11:55:15.000000000 -0700 > @@ -47,31 +47,26 @@ > #define DIGSIG_KEY_OFFSET 1 > #endif > > -extern int g_init; /* digsig.c */ > extern long int total_jiffies; /* digsig.c */ > -extern MPI digsig_public_key[2]; /* dsi_sig_verify.c */ > > -extern struct list_head digsig_revoked_sigs; /* dsi_cache.c */ > - > -struct digsig_attribute_st { > +struct digsig_attribute { > struct attribute attr; > ssize_t (*show)(struct kobject *, struct attribute *attr, char *); > ssize_t (*store)(struct kobject *, struct attribute *attr, const char *, size_t); > }; > > -/* from digsig_cache.c */ > -extern struct list_head digsig_revoked_sigs; > +#define DIGSIG_ATTR(_name, _mode, _show, _store) \ > +struct digsig_attribute digsig_attr_##_name = __ATTR(_name,_mode,_show,_store) > > /* > * These are the show/hide prototypes and attribute for the > - * /sys/digsig/digsig_interface file, which is used to tell digsig the > + * /sys/digsig/key file, which is used to tell digsig the > * public key to use to verify ELF file signatures. > */ > static ssize_t digsig_key_show (struct kobject *obj, struct attribute *attr, > char *buff); > static ssize_t digsig_key_store (struct kobject *obj, struct attribute *attr, > const char *buff, size_t count); > -char digsig_file_name[] = "digsig_interface"; > /* > * For the curious, notice what's going on: We create a structure which > * contains .attr . This .attr is what we pass into sysfs_create_file > @@ -82,39 +77,26 @@ char digsig_file_name[] = "digsig_interf > * subtracting that from the address we were sent, which is what container_of > * in digsig_store and digsig_show (just a few definitions below) do. > */ > -static struct digsig_attribute_st digsig_attribute = { > - .attr = {.name = digsig_file_name, > - .owner = THIS_MODULE, > - .mode = S_IRUSR | S_IWUSR}, > - .show = digsig_key_show, > - .store = digsig_key_store > -}; > +static DIGSIG_ATTR(key, 0600, digsig_key_show, digsig_key_store); > > /* > * These are the show/hide prototypes and attribute for the > - * /sys/digsig/digsig_revoke file, which is used to tell digsig the > + * /sys/digsig/revoke file, which is used to tell digsig the > * ELF file signatures which are revoked. Digsig will not allow > * loading any files which carry one of these signatures. > */ > -static ssize_t digsig_revoked_list_show (struct kobject *obj, > +static ssize_t digsig_revoked_show (struct kobject *obj, > struct attribute *attr, char *buff); > -static ssize_t digsig_revoked_list_store (struct kobject *obj, > +static ssize_t digsig_revoked_store (struct kobject *obj, > struct attribute *attr, const char *buff, size_t count); > -char digsig_r_file_name[] = "digsig_revoke"; > -static struct digsig_attribute_st digsig_r_attribute = { > - .attr = {.name = digsig_r_file_name, > - .owner = THIS_MODULE, > - .mode = S_IRUSR | S_IWUSR}, > - .show = digsig_revoked_list_show, > - .store = digsig_revoked_list_store > -}; > +static DIGSIG_ATTR(revoke, 0600, digsig_revoked_show, digsig_revoked_store); > > /* > * Next are the digsig sysfs file operations. These are assigned to > - * the files under /sys/digsig. They will use the digsig_attribute_st > + * the files under /sys/digsig. They will use the digsig_attribute > * struct defined above to find the function which should actually be > * called for read/write. The attr argument to these functions is a > - * member of the digsig_attribute_st struct we defined, so we use its > + * member of the digsig_attribute struct we defined, so we use its > * offset to find our structure, which in turn contains the read and > * write operations we actually want to perform. > */ > @@ -122,8 +104,8 @@ static ssize_t > digsig_store(struct kobject *kobj, struct attribute *attr, const char *buf, > size_t len) > { > - struct digsig_attribute_st *attribute = container_of(attr, > - struct digsig_attribute_st, attr); > + struct digsig_attribute *attribute = container_of(attr, > + struct digsig_attribute, attr); > > return attribute->store ? attribute->store(kobj, attr, buf, len) : 0; > } > @@ -131,8 +113,8 @@ digsig_store(struct kobject *kobj, struc > static ssize_t > digsig_show(struct kobject *kobj, struct attribute *attr, char *buf) > { > - struct digsig_attribute_st *attribute = container_of(attr, > - struct digsig_attribute_st, attr); > + struct digsig_attribute *attribute = container_of(attr, > + struct digsig_attribute, attr); > > return attribute->show ? attribute->show(kobj, attr, buf) : 0; > } > @@ -161,28 +143,34 @@ static struct kobject digsig_kobject = { > /* > * init and cleanup functions for the /sys/digsig directory. > */ > -int digsig_init_sysfs(void) > +int __init digsig_init_sysfs(void) > { > if (kobject_register (&digsig_kobject) != 0) { > DSM_ERROR ("Digsig key failed to register properly\n"); > - return -1; > + goto err; > } > - if (sysfs_create_file(&digsig_kobject, &digsig_attribute.attr) != 0) { > + if (sysfs_create_file(&digsig_kobject, &digsig_attr_key.attr) != 0) { > DSM_ERROR ("Create file failed\n"); > - return -1; > + goto create_key; > } > - if (sysfs_create_file(&digsig_kobject, &digsig_r_attribute.attr) != 0) { > + if (sysfs_create_file(&digsig_kobject, &digsig_attr_revoke.attr) != 0) { > DSM_ERROR ("Create revocation file failed\n"); > - return -1; > + goto create_revoke; > } > - > return 0; > + > +create_revoke: > + sysfs_remove_file (&digsig_kobject, &digsig_attr_key.attr); > +create_key: > + kobject_unregister (&digsig_kobject); > +err: > + return -1; > } > > void digsig_cleanup_sysfs(void) > { > - sysfs_remove_file (&digsig_kobject, &digsig_attribute.attr); > - sysfs_remove_file (&digsig_kobject, &digsig_r_attribute.attr); > + sysfs_remove_file (&digsig_kobject, &digsig_attr_key.attr); > + sysfs_remove_file (&digsig_kobject, &digsig_attr_revoke.attr); > kobject_unregister (&digsig_kobject); > } > > @@ -219,28 +207,17 @@ digsig_key_store (struct kobject *obj, s > return -1; > > switch (buff[0]) { > - > case 'n': > - raw_public_key = > - (unsigned char *) kmalloc(count - DIGSIG_KEY_OFFSET, DIGSIG_SAFE_ALLOC); > - if (!raw_public_key) { > - DSM_ERROR("kmalloc fail for n in %s\n", __FUNCTION__); > - return -ENOMEM; > - } > - memcpy(raw_public_key, &buff[DIGSIG_KEY_OFFSET], count - DIGSIG_KEY_OFFSET); > - mpi_size = count - DIGSIG_KEY_OFFSET; > - DSM_PRINT(DEBUG_DEV, "pkey->n size is %i\n", mpi_size); > - break; > case 'e': > raw_public_key = > - (unsigned char *) kmalloc(count - DIGSIG_KEY_OFFSET, DIGSIG_SAFE_ALLOC); > + kmalloc(count - DIGSIG_KEY_OFFSET, DIGSIG_SAFE_ALLOC); > if (!raw_public_key) { > - DSM_ERROR("kmalloc fail for e in %s\n", __FUNCTION__); > + DSM_ERROR("kmalloc fail for %c in %s\n", buff[0], __FUNCTION__); > return -ENOMEM; > } > memcpy(raw_public_key, &buff[DIGSIG_KEY_OFFSET], count - DIGSIG_KEY_OFFSET); > mpi_size = count - DIGSIG_KEY_OFFSET; > - DSM_PRINT(DEBUG_DEV, "pkey->e size is %i\n", mpi_size); > + DSM_PRINT(DEBUG_DEV, "pkey->%c size is %i\n", buff[0], mpi_size); > break; > default: > return -EINVAL; > @@ -265,12 +242,12 @@ digsig_key_show (struct kobject *obj, st > } > > /* > - * callbacks for read/write to /sys/digsig/digsig_revoke file > + * callbacks for read/write to /sys/digsig/revoke file > */ > static ssize_t > -digsig_revoked_list_store (struct kobject *obj, struct attribute *attr, const char *buff, size_t count) > +digsig_revoked_store (struct kobject *obj, struct attribute *attr, const char *buff, size_t count) > { > - struct revoked_sig *tmp; > + struct revoked_sig *sig; > int rcount = DIGSIG_ELF_SIG_SIZE - DIGSIG_BSIGN_INFOS - DIGSIG_RSA_DATA_OFFSET; > > if (g_init) > @@ -282,22 +259,22 @@ digsig_revoked_list_store (struct kobjec > return -EINVAL; > } > > - tmp = kmalloc(sizeof(struct revoked_sig), GFP_KERNEL); > - if (!tmp) > + sig = kmalloc(sizeof(struct revoked_sig), GFP_KERNEL); > + if (!sig) > return -ENOMEM; > - memset(tmp, 0, sizeof(struct revoked_sig)); > - tmp->sig = mpi_read_from_buffer( > + memset(sig, 0, sizeof(struct revoked_sig)); > + sig->sig = mpi_read_from_buffer( > buff + DIGSIG_BSIGN_INFOS + DIGSIG_RSA_DATA_OFFSET, > &rcount, 0); > > - list_add_tail(&tmp->next, &digsig_revoked_sigs); > + digsig_add_revoked_sig(sig); > > DSM_PRINT(DEBUG_SIGN, "Added a revoked sig.\n"); > return count; > } > > static ssize_t > -digsig_revoked_list_show (struct kobject *obj, struct attribute *attr, char *buff) > +digsig_revoked_show (struct kobject *obj, struct attribute *attr, char *buff) > { > > return 0; > diff -paur digsig-1.3.1.orig/dsi_sysfs.h digsig-1.3.1/dsi_sysfs.h > --- digsig-1.3.1.orig/dsi_sysfs.h 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/dsi_sysfs.h 2004-09-11 10:55:08.000000000 -0700 > @@ -14,8 +14,8 @@ > * > * Vincent Roy > */ > -#ifndef __DSI_SYSFS_H > -#define __DSI_SYSFS_H > +#ifndef _DSI_SYSFS_H > +#define _DSI_SYSFS_H > > ssize_t digsig_store (struct kobject *obj, struct attribute *attr, const char *buff, size_t count); > ssize_t digsig_show (struct kobject *obj, struct attribute *attr, char *buff); > @@ -26,4 +26,4 @@ ssize_t digsig_rev_list_show (struct kob > int digsig_init_sysfs(void); > void digsig_cleanup_sysfs(void); > > -#endif > +#endif /* _DSI_SYSFS_H */ > diff -paur digsig-1.3.1.orig/tools/extract_pkey.c digsig-1.3.1/tools/extract_pkey.c > --- digsig-1.3.1.orig/tools/extract_pkey.c 2004-09-03 05:31:19.000000000 -0700 > +++ digsig-1.3.1/tools/extract_pkey.c 2004-09-11 11:53:37.000000000 -0700 > @@ -53,7 +53,7 @@ int main(int argc, char **argv) > printf ("Unable to open pkey_file %s %s\n", argv[1], strerror(errno)); > return -1; > } > - module_file = open ("/sys/digsig/digsig_interface", O_WRONLY); > + module_file = open ("/sys/digsig/key", O_WRONLY); > if (!module_file) { > printf ("Unable to open module char device %s\n", strerror(errno)); > return -1; -- Makan Pourzandi, Open Systems Lab Ericsson Research, Montreal, Canada *This email does not represent or express the opinions of Ericsson Inc.* - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/