diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | cryptodev.h | 154 | ||||
-rw-r--r-- | cryptodev_cipher.c | 1 | ||||
-rw-r--r-- | cryptodev_int.h | 41 | ||||
-rw-r--r-- | cryptodev_main.c | 825 | ||||
-rw-r--r-- | examples/Makefile | 10 | ||||
-rw-r--r-- | examples/cipher.c | 230 | ||||
-rw-r--r-- | examples/hmac.c | 210 | ||||
-rw-r--r-- | examples/speed.c | 95 | ||||
-rw-r--r-- | extras/openssl-0.9.8k-cryptodev-linux.diff | 74 | ||||
-rw-r--r-- | extras/openssl-0.9.8l-cryptodev-aes256.patch | 112 | ||||
-rw-r--r-- | ncr-dh.c | 1 | ||||
-rw-r--r-- | ncr-int.h | 3 | ||||
-rw-r--r-- | ncr-key-storage.c | 1 | ||||
-rw-r--r-- | ncr-key-wrap.c | 1 | ||||
-rw-r--r-- | ncr-key.c | 1 | ||||
-rw-r--r-- | ncr-limits.c | 1 | ||||
-rw-r--r-- | ncr-pk.c | 1 | ||||
-rw-r--r-- | ncr-sessions.c | 1 | ||||
-rw-r--r-- | ncr.c | 4 |
21 files changed, 25 insertions, 1746 deletions
@@ -7,8 +7,6 @@ Module.symvers *.o *.mod.c modules.order -examples/cipher -examples/hmac examples/ncr examples/ncr_lib examples/pk @@ -82,8 +82,7 @@ build: install: $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_install - @echo "Installing cryptodev.h in /usr/include/crypto ..." - @install -D cryptodev.h /usr/include/crypto/cryptodev.h + @echo "Installing ncr.h in /usr/include/crypto ..." @install -D ncr.h /usr/include/crypto/ncr.h clean: diff --git a/cryptodev.h b/cryptodev.h deleted file mode 100644 index 4a546b8..0000000 --- a/cryptodev.h +++ /dev/null @@ -1,154 +0,0 @@ -/* This is a source compatible implementation with the original API of - * cryptodev by Angelos D. Keromytis, found at openbsd cryptodev.h. - * Placed under public domain */ - -#ifndef L_CRYPTODEV_H -#define L_CRYPTODEV_H - -#include <linux/types.h> -#ifndef __KERNEL__ -#define __user -#endif - -/* API extensions for linux */ -#define CRYPTO_HMAC_MAX_KEY_LEN 512 -#define CRYPTO_CIPHER_MAX_KEY_LEN 64 - -/* All the supported algorithms - */ -typedef enum { - CRYPTO_DES_CBC=1, - CRYPTO_3DES_CBC=2, - CRYPTO_BLF_CBC=3, - CRYPTO_CAST_CBC=4, - CRYPTO_SKIPJACK_CBC=5, - CRYPTO_MD5_HMAC=6, - CRYPTO_SHA1_HMAC=7, - CRYPTO_RIPEMD160_HMAC=8, - CRYPTO_MD5_KPDK=9, - CRYPTO_SHA1_KPDK=10, - CRYPTO_RIJNDAEL128_CBC=11, - CRYPTO_AES_CBC=CRYPTO_RIJNDAEL128_CBC, - CRYPTO_ARC4=12, - CRYPTO_MD5=13, - CRYPTO_SHA1=14, - CRYPTO_DEFLATE_COMP=15, - CRYPTO_NULL=16, - CRYPTO_LZS_COMP=17, - CRYPTO_SHA2_256_HMAC=18, - CRYPTO_SHA2_384_HMAC=19, - CRYPTO_SHA2_512_HMAC=20, - CRYPTO_AES_CTR=21, - CRYPTO_AES_XTS=22, - - CRYPTO_CAMELLIA_CBC=101, - CRYPTO_RIPEMD160, - CRYPTO_SHA2_256, - CRYPTO_SHA2_384, - CRYPTO_SHA2_512, - CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */ -} cryptodev_crypto_op_t; -#define CRYPTO_ALGORITHM_MAX (CRYPTO_ALGORITHM_ALL - 1) - -/* Values for ciphers */ -#define DES_BLOCK_LEN 8 -#define DES3_BLOCK_LEN 8 -#define RIJNDAEL128_BLOCK_LEN 16 -#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN -#define CAMELLIA_BLOCK_LEN -#define BLOWFISH_BLOCK_LEN 8 -#define SKIPJACK_BLOCK_LEN 8 -#define CAST128_BLOCK_LEN 8 - -/* the maximum of the above */ -#define EALG_MAX_BLOCK_LEN 16 - -/* Values for hashes/MAC */ -#define AALG_MAX_RESULT_LEN 64 - -/* input of CIOCGSESSION */ -struct session_op { - /* Specify either cipher or mac - */ - __u32 cipher; /* cryptodev_crypto_op_t */ - __u32 mac; /* cryptodev_crypto_op_t */ - - __u32 keylen; - __u8 __user *key; - __u32 mackeylen; - __u8 __user *mackey; - - __u32 ses; /* session identifier */ -}; - -#define COP_ENCRYPT 0 -#define COP_DECRYPT 1 - -/* input of CIOCCRYPT */ - struct crypt_op { - __u32 ses; /* session identifier */ - __u16 op; /* COP_ENCRYPT or COP_DECRYPT */ - __u16 flags; /* no usage so far, use 0 */ - __u32 len; /* length of source data */ - __u8 __user *src; /* source data */ - __u8 __user *dst; /* pointer to output data */ - __u8 __user *mac; /* pointer to output data for hash/MAC operations */ - __u8 __user *iv; /* initialization vector for encryption operations */ -}; - -/* Stuff for bignum arithmetic and public key - * cryptography - not supported yet by linux - * cryptodev. - */ - -#define CRYPTO_ALG_FLAG_SUPPORTED 1 -#define CRYPTO_ALG_FLAG_RNG_ENABLE 2 -#define CRYPTO_ALG_FLAG_DSA_SHA 4 - -struct crparam { - __u8* crp_p; - __u32 crp_nbits; -}; - -#define CRK_MAXPARAM 8 - -/* input of CIOCKEY */ -struct crypt_kop { - __u32 crk_op; /* cryptodev_crk_ot_t */ - __u32 crk_status; - __u16 crk_iparams; - __u16 crk_oparams; - __u32 crk_pad1; - struct crparam crk_param[CRK_MAXPARAM]; -}; - -typedef enum { - CRK_MOD_EXP=0, - CRK_MOD_EXP_CRT=1, - CRK_DSA_SIGN=2, - CRK_DSA_VERIFY=3, - CRK_DH_COMPUTE_KEY=4, - CRK_ALGORITHM_ALL -} cryptodev_crk_op_t; - -#define CRK_ALGORITHM_MAX CRK_ALGORITHM_ALL-1 - -/* features to be queried with CIOCASYMFEAT ioctl - */ -#define CRF_MOD_EXP (1 << CRK_MOD_EXP) -#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT) -#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN) -#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) -#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) - - -/* ioctl's. Compatible with old linux cryptodev.h - */ -#define CRIOGET _IOWR('c', 101, __u32) -#define CIOCGSESSION _IOWR('c', 102, struct session_op) -#define CIOCFSESSION _IOW('c', 103, __u32) -#define CIOCCRYPT _IOWR('c', 104, struct crypt_op) -#define CIOCKEY _IOWR('c', 105, struct crypt_kop) -#define CIOCASYMFEAT _IOR('c', 106, __u32) - -#endif /* L_CRYPTODEV_H */ diff --git a/cryptodev_cipher.c b/cryptodev_cipher.c index 8322027..4e74fcc 100644 --- a/cryptodev_cipher.c +++ b/cryptodev_cipher.c @@ -31,7 +31,6 @@ #include <linux/uaccess.h> #include <crypto/algapi.h> #include <crypto/hash.h> -#include "cryptodev.h" #include "cryptodev_int.h" diff --git a/cryptodev_int.h b/cryptodev_int.h index b4059fe..e381505 100644 --- a/cryptodev_int.h +++ b/cryptodev_int.h @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/scatterlist.h> -#include <cryptodev.h> +#include <ncr.h> #define PFX "cryptodev: " #define dprintk(level,severity,format,a...) \ @@ -45,7 +45,7 @@ struct cipher_data struct crypto_ablkcipher* s; struct cryptodev_result *result; struct ablkcipher_request *request; - uint8_t iv[EALG_MAX_BLOCK_LEN]; + uint8_t iv[NCR_CIPHER_MAX_BLOCK_LEN]; } async; }; @@ -79,41 +79,4 @@ int cryptodev_hash_reset( struct hash_data* hdata); void cryptodev_hash_deinit(struct hash_data* hdata); int cryptodev_hash_init( struct hash_data* hdata, const char* alg_name, int hmac_mode, void* mackey, size_t mackeylen); -/* compatibility stuff */ -#ifdef CONFIG_COMPAT -#include <linux/compat.h> - -/* input of CIOCGSESSION */ -struct compat_session_op { - /* Specify either cipher or mac - */ - uint32_t cipher; /* cryptodev_crypto_op_t */ - uint32_t mac; /* cryptodev_crypto_op_t */ - - uint32_t keylen; - compat_uptr_t key; /* pointer to key data */ - uint32_t mackeylen; - compat_uptr_t mackey; /* pointer to mac key data */ - - uint32_t ses; /* session identifier */ -}; - -/* input of CIOCCRYPT */ - struct compat_crypt_op { - uint32_t ses; /* session identifier */ - uint16_t op; /* COP_ENCRYPT or COP_DECRYPT */ - uint16_t flags; /* no usage so far, use 0 */ - uint32_t len; /* length of source data */ - compat_uptr_t src; /* source data */ - compat_uptr_t dst; /* pointer to output data */ - compat_uptr_t mac; /* pointer to output data for hash/MAC operations */ - compat_uptr_t iv; /* initialization vector for encryption operations */ -}; - -/* compat ioctls, defined for the above structs */ -#define COMPAT_CIOCGSESSION _IOWR('c', 102, struct compat_session_op) -#define COMPAT_CIOCCRYPT _IOWR('c', 104, struct compat_crypt_op) - -#endif /* CONFIG_COMPAT */ - #endif /* CRYPTODEV_INT_H */ diff --git a/cryptodev_main.c b/cryptodev_main.c index a056b44..0a20888 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -39,7 +39,6 @@ #include <linux/syscalls.h> #include <linux/pagemap.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include "cryptodev_int.h" #include "ncr-int.h" @@ -50,452 +49,13 @@ MODULE_AUTHOR("Nikos Mavrogiannopoulos <nmav@gnutls.org>"); MODULE_DESCRIPTION("CryptoDev driver"); MODULE_LICENSE("GPL"); -/* ====== Compile-time config ====== */ - -#define CRYPTODEV_STATS - /* ====== Module parameters ====== */ int cryptodev_verbosity = 0; module_param(cryptodev_verbosity, int, 0644); MODULE_PARM_DESC(cryptodev_verbosity, "0: normal, 1: verbose, 2: debug"); -#ifdef CRYPTODEV_STATS -static int enable_stats = 0; -module_param(enable_stats, int, 0644); -MODULE_PARM_DESC(enable_stats, "collect statictics about cryptodev usage"); -#endif - /* ====== CryptoAPI ====== */ -struct fcrypt { - struct list_head list; - struct semaphore sem; -}; - -struct crypt_priv { - void * ncr; - struct fcrypt fcrypt; -}; - -#define FILL_SG(sg,ptr,len) \ - do { \ - (sg)->page = virt_to_page(ptr); \ - (sg)->offset = offset_in_page(ptr); \ - (sg)->length = len; \ - (sg)->dma_address = 0; \ - } while (0) - -struct csession { - struct list_head entry; - struct semaphore sem; - struct cipher_data cdata; - struct hash_data hdata; - uint32_t sid; -#ifdef CRYPTODEV_STATS -#if ! ((COP_ENCRYPT < 2) && (COP_DECRYPT < 2)) -#error Struct csession.stat uses COP_{ENCRYPT,DECRYPT} as indices. Do something! -#endif - unsigned long long stat[2]; - size_t stat_max_size, stat_count; -#endif - int array_size; - struct page **pages; - struct scatterlist *sg; -}; - -/* Prepare session for future use. */ -static int -crypto_create_session(struct fcrypt *fcr, struct session_op *sop) -{ - struct csession *ses_new = NULL, *ses_ptr; - int ret = 0; - const char *alg_name=NULL; - const char *hash_name=NULL; - int hmac_mode = 1; - - /* Does the request make sense? */ - if (unlikely(!sop->cipher && !sop->mac)) { - dprintk(1,KERN_DEBUG,"Both 'cipher' and 'mac' unset.\n"); - return -EINVAL; - } - - switch (sop->cipher) { - case 0: - break; - case CRYPTO_DES_CBC: - alg_name = "cbc(des)"; - break; - case CRYPTO_3DES_CBC: - alg_name = "cbc(des3_ede)"; - break; - case CRYPTO_BLF_CBC: - alg_name = "cbc(blowfish)"; - break; - case CRYPTO_AES_CBC: - alg_name = "cbc(aes)"; - break; - case CRYPTO_CAMELLIA_CBC: - alg_name = "cbc(camelia)"; - break; - case CRYPTO_AES_CTR: - alg_name = "ctr(aes)"; - break; - case CRYPTO_NULL: - alg_name = "ecb(cipher_null)"; - break; - default: - dprintk(1,KERN_DEBUG,"%s: bad cipher: %d\n", __func__, sop->cipher); - return -EINVAL; - } - - switch (sop->mac) { - case 0: - break; - case CRYPTO_MD5_HMAC: - hash_name = "hmac(md5)"; - break; - case CRYPTO_RIPEMD160_HMAC: - hash_name = "hmac(rmd160)"; - break; - case CRYPTO_SHA1_HMAC: - hash_name = "hmac(sha1)"; - break; - case CRYPTO_SHA2_256_HMAC: - hash_name = "hmac(sha256)"; - break; - case CRYPTO_SHA2_384_HMAC: - hash_name = "hmac(sha384)"; - break; - case CRYPTO_SHA2_512_HMAC: - hash_name = "hmac(sha512)"; - break; - - /* non-hmac cases */ - case CRYPTO_MD5: - hash_name = "md5"; - hmac_mode = 0; - break; - case CRYPTO_RIPEMD160: - hash_name = "rmd160"; - hmac_mode = 0; - break; - case CRYPTO_SHA1: - hash_name = "sha1"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_256: - hash_name = "sha256"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_384: - hash_name = "sha384"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_512: - hash_name = "sha512"; - hmac_mode = 0; - break; - - default: - dprintk(1,KERN_DEBUG,"%s: bad mac: %d\n", __func__, sop->mac); - return -EINVAL; - } - - /* Create a session and put it to the list. */ - ses_new = kzalloc(sizeof(*ses_new), GFP_KERNEL); - if(!ses_new) { - return -ENOMEM; - } - - /* Set-up crypto transform. */ - if (alg_name) { - uint8_t keyp[CRYPTO_CIPHER_MAX_KEY_LEN]; - - if (unlikely(sop->keylen > CRYPTO_CIPHER_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", - alg_name, (size_t)sop->keylen*8); - ret = -EINVAL; - goto error_cipher; - } - - if (unlikely(copy_from_user(keyp, sop->key, sop->keylen))) { - ret = -EFAULT; - goto error_cipher; - } - - ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keyp, sop->keylen); - if (ret < 0) { - dprintk(1,KERN_DEBUG,"%s: Failed to load cipher for %s\n", __func__, - alg_name); - ret = -EINVAL; - goto error_cipher; - } - } - - if (hash_name) { - uint8_t keyp[CRYPTO_HMAC_MAX_KEY_LEN]; - - if (unlikely(sop->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", - alg_name, (size_t)sop->mackeylen*8); - ret = -EINVAL; - goto error_hash; - } - - if (unlikely(copy_from_user(keyp, sop->mackey, - sop->mackeylen))) { - ret = -EFAULT; - goto error_hash; - } - - ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode, keyp, sop->mackeylen); - if (ret != 0) { - dprintk(1,KERN_DEBUG,"%s: Failed to load hash for %s\n", __func__, - hash_name); - ret = -EINVAL; - goto error_hash; - } - } - - ses_new->array_size = DEFAULT_PREALLOC_PAGES; - dprintk(2, KERN_DEBUG, "%s: preallocating for %d user pages\n", - __func__, ses_new->array_size); - ses_new->pages = kzalloc(ses_new->array_size * - sizeof(struct page *), GFP_KERNEL); - ses_new->sg = kzalloc(ses_new->array_size * - sizeof(struct scatterlist), GFP_KERNEL); - if (ses_new->sg == NULL || ses_new->pages == NULL) { - dprintk(0,KERN_DEBUG,"Memory error\n"); - ret = -ENOMEM; - goto error_hash; - } - - /* put the new session to the list */ - get_random_bytes(&ses_new->sid, sizeof(ses_new->sid)); - init_MUTEX(&ses_new->sem); - - down(&fcr->sem); -restart: - list_for_each_entry(ses_ptr, &fcr->list, entry) { - /* Check for duplicate SID */ - if (unlikely(ses_new->sid == ses_ptr->sid)) { - get_random_bytes(&ses_new->sid, sizeof(ses_new->sid)); - /* Unless we have a broken RNG this - shouldn't loop forever... ;-) */ - goto restart; - } - } - - list_add(&ses_new->entry, &fcr->list); - up(&fcr->sem); - - /* Fill in some values for the user. */ - sop->ses = ses_new->sid; - - return 0; - -error_hash: - cryptodev_cipher_deinit( &ses_new->cdata); - kfree(ses_new->sg); - kfree(ses_new->pages); -error_cipher: - if (ses_new) kfree(ses_new); - - return ret; - -} - -/* Everything that needs to be done when remowing a session. */ -static inline void -crypto_destroy_session(struct csession *ses_ptr) -{ - if(down_trylock(&ses_ptr->sem)) { - dprintk(2, KERN_DEBUG, "Waiting for semaphore of sid=0x%08X\n", - ses_ptr->sid); - down(&ses_ptr->sem); - } - dprintk(2, KERN_DEBUG, "Removed session 0x%08X\n", ses_ptr->sid); -#if defined(CRYPTODEV_STATS) - if(enable_stats) - dprintk(2, KERN_DEBUG, - "Usage in Bytes: enc=%llu, dec=%llu, max=%zu, avg=%lu, cnt=%zu\n", - ses_ptr->stat[COP_ENCRYPT], ses_ptr->stat[COP_DECRYPT], - ses_ptr->stat_max_size, ses_ptr->stat_count > 0 - ? ((unsigned long)(ses_ptr->stat[COP_ENCRYPT]+ - ses_ptr->stat[COP_DECRYPT]) / - ses_ptr->stat_count) : 0, - ses_ptr->stat_count); -#endif - cryptodev_cipher_deinit(&ses_ptr->cdata); - cryptodev_hash_deinit(&ses_ptr->hdata); - dprintk(2, KERN_DEBUG, "%s: freeing space for %d user pages\n", - __func__, ses_ptr->array_size); - kfree(ses_ptr->pages); - kfree(ses_ptr->sg); - - up(&ses_ptr->sem); - kfree(ses_ptr); -} - -/* Look up a session by ID and remove. */ -static int -crypto_finish_session(struct fcrypt *fcr, uint32_t sid) -{ - struct csession *tmp, *ses_ptr; - struct list_head *head; - int ret = 0; - - down(&fcr->sem); - head = &fcr->list; - list_for_each_entry_safe(ses_ptr, tmp, head, entry) { - if(ses_ptr->sid == sid) { - list_del(&ses_ptr->entry); - crypto_destroy_session(ses_ptr); - break; - } - } - - if (unlikely(!ses_ptr)) { - dprintk(1, KERN_ERR, "Session with sid=0x%08X not found!\n", sid); - ret = -ENOENT; - } - up(&fcr->sem); - - return ret; -} - -/* Remove all sessions when closing the file */ -static int -crypto_finish_all_sessions(struct fcrypt *fcr) -{ - struct csession *tmp, *ses_ptr; - struct list_head *head; - - down(&fcr->sem); - - head = &fcr->list; - list_for_each_entry_safe(ses_ptr, tmp, head, entry) { - list_del(&ses_ptr->entry); - crypto_destroy_session(ses_ptr); - } - up(&fcr->sem); - - return 0; -} - -/* Look up session by session ID. The returned session is locked. */ -static struct csession * -crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid) -{ - struct csession *ses_ptr; - - down(&fcr->sem); - list_for_each_entry(ses_ptr, &fcr->list, entry) { - if(ses_ptr->sid == sid) { - down(&ses_ptr->sem); - break; - } - } - up(&fcr->sem); - - return ses_ptr; -} - -static int -hash_n_crypt(struct csession *ses_ptr, struct crypt_op *cop, - struct scatterlist *src_sg, struct scatterlist *dst_sg, uint32_t len) -{ - int ret; - - /* Always hash before encryption and after decryption. Maybe - * we should introduce a flag to switch... TBD later on. - */ - if (cop->op == COP_ENCRYPT) { - if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_update(&ses_ptr->hdata, src_sg, len); - if (unlikely(ret)) - goto out_err; - } - if (ses_ptr->cdata.init != 0) { - ret = cryptodev_cipher_encrypt( &ses_ptr->cdata, src_sg, dst_sg, len); - - if (unlikely(ret)) - goto out_err; - } - } else { - if (ses_ptr->cdata.init != 0) { - ret = cryptodev_cipher_decrypt( &ses_ptr->cdata, src_sg, dst_sg, len); - - if (unlikely(ret)) - goto out_err; - } - - if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_update(&ses_ptr->hdata, dst_sg, len); - if (unlikely(ret)) - goto out_err; - } - } - return 0; -out_err: - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - return ret; -} - -/* This is the main crypto function - feed it with plaintext - and get a ciphertext (or vice versa :-) */ -static int -__crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop) -{ - char *data; - char __user *src, *dst; - struct scatterlist sg; - size_t nbytes, bufsize; - int ret = 0; - - nbytes = cop->len; - data = (char*)__get_free_page(GFP_KERNEL); - - if (unlikely(!data)) { - return -ENOMEM; - } - bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes; - - src = cop->src; - dst = cop->dst; - - while(nbytes > 0) { - size_t current_len = nbytes > bufsize ? bufsize : nbytes; - - if (unlikely(copy_from_user(data, src, current_len))) { - ret = -EFAULT; - break; - } - - sg_init_one(&sg, data, current_len); - - ret = hash_n_crypt(ses_ptr, cop, &sg, &sg, current_len); - - if (unlikely(ret)) - break; - - if (ses_ptr->cdata.init != 0) { - if (unlikely(copy_to_user(dst, data, current_len))) { - ret = -EFAULT; - break; - } - } - - dst += current_len; - nbytes -= current_len; - src += current_len; - } - - free_page((unsigned long)data); - return ret; -} - -#ifndef DISABLE_ZCOPY void release_user_pages(struct page **pg, int pagecount) { @@ -538,217 +98,29 @@ int __get_userbuf(uint8_t __user *addr, uint32_t len, int write, return 0; } -/* make cop->src and cop->dst available in scatterlists */ -static int get_userbuf(struct csession *ses, - struct crypt_op *cop, struct scatterlist **src_sg, - struct scatterlist **dst_sg, int *tot_pages) -{ - int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1; - - if (cop->src == NULL) { - return -EINVAL; - } - - src_pagecount = PAGECOUNT(cop->src, cop->len); - if (!ses->cdata.init) { /* hashing only */ - write_src = 0; - } else if (cop->src != cop->dst) { /* non-in-situ transformation */ - if (cop->dst == NULL) { - return -EINVAL; - } - dst_pagecount = PAGECOUNT(cop->dst, cop->len); - write_src = 0; - } - (*tot_pages) = pagecount = src_pagecount + dst_pagecount; - - if (pagecount > ses->array_size) { - struct scatterlist *sg; - struct page **pages; - int array_size; - - for (array_size = ses->array_size; array_size < pagecount; - array_size *= 2) - ; - - dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n", - __func__, array_size); - pages = krealloc(ses->pages, array_size * sizeof(struct page *), - GFP_KERNEL); - if (pages == NULL) - return -ENOMEM; - ses->pages = pages; - sg = krealloc(ses->sg, array_size * sizeof(struct scatterlist), - GFP_KERNEL); - if (sg == NULL) - return -ENOMEM; - ses->sg = sg; - ses->array_size = array_size; - } - - if (__get_userbuf(cop->src, cop->len, write_src, - src_pagecount, ses->pages, ses->sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); - return -EINVAL; - } - (*src_sg) = (*dst_sg) = ses->sg; - - if (dst_pagecount) { - (*dst_sg) = ses->sg + src_pagecount; - - if (__get_userbuf(cop->dst, cop->len, 1, dst_pagecount, - ses->pages + src_pagecount, *dst_sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data output\n"); - release_user_pages(ses->pages, src_pagecount); - return -EINVAL; - } - } - return 0; -} - -/* This is the main crypto function - zero-copy edition */ -static int -__crypto_run_zc(struct csession *ses_ptr, struct crypt_op *cop) -{ - struct scatterlist *src_sg, *dst_sg; - int ret = 0, pagecount; - - ret = get_userbuf(ses_ptr, cop, &src_sg, &dst_sg, &pagecount); - if (unlikely(ret)) { - dprintk(1, KERN_ERR, "Error getting user pages. Falling back to non zero copy.\n"); - return __crypto_run_std(ses_ptr, cop); - } - - ret = hash_n_crypt(ses_ptr, cop, src_sg, dst_sg, cop->len); - - release_user_pages(ses_ptr->pages, pagecount); - return ret; -} - -#endif /* DISABLE_ZCOPY */ - -static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) -{ - struct csession *ses_ptr; - uint8_t hash_output[AALG_MAX_RESULT_LEN]; - int ret; - - if (unlikely(cop->op != COP_ENCRYPT && cop->op != COP_DECRYPT)) { - dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", cop->op); - return -EINVAL; - } - - /* this also enters ses_ptr->sem */ - ses_ptr = crypto_get_session_by_sid(fcr, cop->ses); - if (unlikely(!ses_ptr)) { - dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", cop->ses); - return -EINVAL; - } - - if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_reset(&ses_ptr->hdata); - if (unlikely(ret)) { - dprintk(1, KERN_ERR, - "error in cryptodev_hash_reset()\n"); - goto out_unlock; - } - } - - if (ses_ptr->cdata.init != 0) { - int blocksize = ses_ptr->cdata.blocksize; - - if (unlikely(cop->len % blocksize)) { - dprintk(1, KERN_ERR, - "data size (%u) isn't a multiple of block size (%u)\n", - cop->len, blocksize); - ret = -EINVAL; - goto out_unlock; - } - - if (cop->iv) { - uint8_t iv[EALG_MAX_BLOCK_LEN]; - - ret = copy_from_user(iv, cop->iv, min( (int)sizeof(iv), (ses_ptr->cdata.ivsize))); - if (unlikely(ret)) { - dprintk(1, KERN_ERR, "error copying IV (%d bytes)\n", min( (int)sizeof(iv), (ses_ptr->cdata.ivsize))); - ret = -EFAULT; - goto out_unlock; - } - - cryptodev_cipher_set_iv(&ses_ptr->cdata, iv, ses_ptr->cdata.ivsize); - } - } - -#ifdef DISABLE_ZCOPY - ret = __crypto_run_std(ses_ptr, cop); -#else /* normal */ - ret = __crypto_run_zc(ses_ptr, cop); -#endif - if (unlikely(ret)) - goto out_unlock; - - if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_final(&ses_ptr->hdata, hash_output); - if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); - goto out_unlock; - } - - if (unlikely(copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize))) { - ret = -EFAULT; - goto out_unlock; - } - } - -#if defined(CRYPTODEV_STATS) - if (enable_stats) { - /* this is safe - we check cop->op at the function entry */ - ses_ptr->stat[cop->op] += cop->len; - if (ses_ptr->stat_max_size < cop->len) - ses_ptr->stat_max_size = cop->len; - ses_ptr->stat_count++; - } -#endif - -out_unlock: - up(&ses_ptr->sem); - return ret; -} - - /* ====== /dev/crypto ====== */ static int cryptodev_open(struct inode *inode, struct file *filp) { - struct crypt_priv *pcr; + void *ncr; - pcr = kmalloc(sizeof(*pcr), GFP_KERNEL); - if(!pcr) - return -ENOMEM; - - memset(pcr, 0, sizeof(*pcr)); - init_MUTEX(&pcr->fcrypt.sem); - INIT_LIST_HEAD(&pcr->fcrypt.list); - - pcr->ncr = ncr_init_lists(); - if (pcr->ncr == NULL) { - kfree(pcr); + ncr = ncr_init_lists(); + if (ncr == NULL) { return -ENOMEM; } - filp->private_data = pcr; + filp->private_data = ncr; return 0; } static int cryptodev_release(struct inode *inode, struct file *filp) { - struct crypt_priv *pcr = filp->private_data; + void *ncr = filp->private_data; - if(pcr) { - crypto_finish_all_sessions(&pcr->fcrypt); - ncr_deinit_lists(pcr->ncr); - kfree(pcr); + if (ncr) { + ncr_deinit_lists(ncr); filp->private_data = NULL; } @@ -756,194 +128,29 @@ cryptodev_release(struct inode *inode, struct file *filp) } static int -clonefd(struct file *filp) -{ - int ret; - ret = get_unused_fd(); - if (ret >= 0) { - get_file(filp); - fd_install(ret, filp); - } - - return ret; -} - -static int cryptodev_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg_) + unsigned int cmd, unsigned long arg) { - void __user *arg = (void __user *)arg_; - int __user *p = arg; - struct session_op sop; - struct crypt_op cop; - struct crypt_priv *pcr = filp->private_data; - struct fcrypt * fcr; - uint32_t ses; - int ret, fd; - - if (unlikely(!pcr)) - BUG(); + void *ncr = filp->private_data; - fcr = &pcr->fcrypt; + if (unlikely(!ncr)) + BUG(); - switch (cmd) { - case CIOCASYMFEAT: - return put_user(0, p); - case CRIOGET: - fd = clonefd(filp); - ret = put_user(fd, p); - if (unlikely(ret)) { - sys_close(fd); - return ret; - } - return ret; - case CIOCGSESSION: - if (unlikely(copy_from_user(&sop, arg, sizeof(sop)))) - return -EFAULT; - - ret = crypto_create_session(fcr, &sop); - if (unlikely(ret)) - return ret; - ret = copy_to_user(arg, &sop, sizeof(sop)); - if (unlikely(ret)) { - crypto_finish_session(fcr, sop.ses); - return -EFAULT; - } - return ret; - case CIOCFSESSION: - ret = get_user(ses, (uint32_t __user *)arg); - if (unlikely(ret)) - return ret; - ret = crypto_finish_session(fcr, ses); - return ret; - case CIOCCRYPT: - if (unlikely(copy_from_user(&cop, arg, sizeof(cop)))) - return -EFAULT; - - ret = crypto_run(fcr, &cop); - if (unlikely(ret)) - return ret; - if (unlikely(copy_to_user(arg, &cop, sizeof(cop)))) - return -EFAULT; - return 0; - - default: - return ncr_ioctl(pcr->ncr, filp, cmd, arg_); - } + return ncr_ioctl(ncr, cmd, arg); } /* compatibility code for 32bit userlands */ #ifdef CONFIG_COMPAT -static inline void -compat_to_session_op(struct compat_session_op *compat, struct session_op *sop) -{ - sop->cipher = compat->cipher; - sop->mac = compat->mac; - sop->keylen = compat->keylen; - - sop->key = compat_ptr(compat->key); - sop->mackeylen = compat->mackeylen; - sop->mackey = compat_ptr(compat->mackey); - sop->ses = compat->ses; -} - -static inline void -session_op_to_compat(struct session_op *sop, struct compat_session_op *compat) -{ - compat->cipher = sop->cipher; - compat->mac = sop->mac; - compat->keylen = sop->keylen; - - compat->key = ptr_to_compat(sop->key); - compat->mackeylen = sop->mackeylen; - compat->mackey = ptr_to_compat(sop->mackey); - compat->ses = sop->ses; -} - -static inline void -compat_to_crypt_op(struct compat_crypt_op *compat, struct crypt_op *cop) -{ - cop->ses = compat->ses; - cop->op = compat->op; - cop->flags = compat->flags; - cop->len = compat->len; - - cop->src = compat_ptr(compat->src); - cop->dst = compat_ptr(compat->dst); - cop->mac = compat_ptr(compat->mac); - cop->iv = compat_ptr(compat->iv); -} - -static inline void -crypt_op_to_compat(struct crypt_op *cop, struct compat_crypt_op *compat) -{ - compat->ses = cop->ses; - compat->op = cop->op; - compat->flags = cop->flags; - compat->len = cop->len; - - compat->src = ptr_to_compat(cop->src); - compat->dst = ptr_to_compat(cop->dst); - compat->mac = ptr_to_compat(cop->mac); - compat->iv = ptr_to_compat(cop->iv); -} - static long -cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_) +cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - void __user *arg = (void __user *)arg_; - struct fcrypt *fcr = file->private_data; - struct session_op sop; - struct compat_session_op compat_sop; - struct crypt_op cop; - struct compat_crypt_op compat_cop; - int ret; - - if (unlikely(!fcr)) + void *ncr = file->private_data; + + if (unlikely(!ncr)) BUG(); switch (cmd) { - case CIOCASYMFEAT: - case CRIOGET: - case CIOCFSESSION: - return cryptodev_ioctl(NULL, file, cmd, arg_); - - case COMPAT_CIOCGSESSION: - if (unlikely(copy_from_user(&compat_sop, arg, - sizeof(compat_sop)))) - return -EFAULT; - compat_to_session_op(&compat_sop, &sop); - - ret = crypto_create_session(fcr, &sop); - if (unlikely(ret)) - return ret; - - session_op_to_compat(&sop, &compat_sop); - ret = copy_to_user(arg, &compat_sop, sizeof(compat_sop)); - if (unlikely(ret)) { - crypto_finish_session(fcr, sop.ses); - return -EFAULT; - } - return ret; - - case COMPAT_CIOCCRYPT: - if (unlikely(copy_from_user(&compat_cop, arg, - sizeof(compat_cop)))) - return -EFAULT; - - compat_to_crypt_op(&compat_cop, &cop); - - ret = crypto_run(fcr, &cop); - if (unlikely(ret)) - return ret; - - crypt_op_to_compat(&cop, &compat_cop); - if (unlikely(copy_to_user(arg, &compat_cop, - sizeof(compat_cop)))) - return -EFAULT; - return 0; - default: return -EINVAL; } diff --git a/examples/Makefile b/examples/Makefile index 33a67bc..69c1f5c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -3,19 +3,13 @@ CFLAGS = -Wall -g -O2 -I../userspace GNUTLS_LDFLAGS = -L/usr/local/lib -lgnutls USERSPACE_LDFLAGS = -L../userspace -lcryptodev -progs := cipher hmac ncr ncr_lib pk pk_lib speed +progs := ncr ncr_lib pk pk_lib speed all: $(progs) -cipher: cipher.c - $(CC) $(CFLAGS) $< -o $@ - speed: speed.c $(CC) $(CFLAGS) $< -o $@ -hmac: hmac.c - $(CC) $(CFLAGS) $< -o $@ - ncr: ncr.c $(CC) $(CFLAGS) $< -o $@ @@ -33,8 +27,6 @@ check: $(progs) LD_LIBRARY_PATH=../userspace ./ncr_lib ./pk LD_LIBRARY_PATH=../userspace ./pk_lib - ./cipher - ./hmac ./speed clean: diff --git a/examples/cipher.c b/examples/cipher.c deleted file mode 100644 index 52b4996..0000000 --- a/examples/cipher.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Demo on how to use /dev/crypto device for ciphering. - * - * Placed under public domain. - * - */ -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/ioctl.h> -#include "../cryptodev.h" - -#define DATA_SIZE 4096 -#define BLOCK_SIZE 16 -#define KEY_SIZE 16 - -static int -test_crypto(int cfd) -{ - uint8_t plaintext[DATA_SIZE]; - uint8_t ciphertext[DATA_SIZE]; - uint8_t iv[BLOCK_SIZE]; - uint8_t key[KEY_SIZE]; - - struct session_op sess; - struct crypt_op cryp; - - memset(&sess, 0, sizeof(sess)); - memset(&cryp, 0, sizeof(cryp)); - - memset(plaintext, 0x15, sizeof(plaintext)); - memset(key, 0x33, sizeof(key)); - memset(iv, 0x03, sizeof(iv)); - - /* Get crypto session for AES128 */ - sess.cipher = CRYPTO_AES_CBC; - sess.keylen = KEY_SIZE; - sess.key = key; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - /* Encrypt data.in to data.encrypted */ - cryp.ses = sess.ses; - cryp.len = sizeof(plaintext); - cryp.src = plaintext; - cryp.dst = ciphertext; - cryp.iv = iv; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - /* Decrypt data.encrypted to data.decrypted */ - cryp.ses = sess.ses; - cryp.len = sizeof(plaintext); - cryp.src = ciphertext; - cryp.dst = ciphertext; - cryp.iv = iv; - cryp.op = COP_DECRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - /* Verify the result */ - if (memcmp(plaintext, ciphertext, sizeof(plaintext)) != 0) { - fprintf(stderr, - "FAIL: Decrypted data are different from the input data.\n"); - return 1; - } else - printf("Test passed\n"); - - /* Finish crypto session */ - if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { - perror("ioctl(CIOCFSESSION)"); - return 1; - } - - return 0; -} - -static int test_aes(int cfd) -{ - uint8_t plaintext1[BLOCK_SIZE]; - uint8_t ciphertext1[BLOCK_SIZE] = { 0xdf, 0x55, 0x6a, 0x33, 0x43, 0x8d, 0xb8, 0x7b, 0xc4, 0x1b, 0x17, 0x52, 0xc5, 0x5e, 0x5e, 0x49 }; - uint8_t iv1[BLOCK_SIZE]; - uint8_t key1[KEY_SIZE] = { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t plaintext2[BLOCK_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 }; - uint8_t ciphertext2[BLOCK_SIZE] = { 0xb7, 0x97, 0x2b, 0x39, 0x41, 0xc4, 0x4b, 0x90, 0xaf, 0xa7, 0xb2, 0x64, 0xbf, 0xba, 0x73, 0x87 }; - uint8_t iv2[BLOCK_SIZE]; - uint8_t key2[KEY_SIZE]; - - struct session_op sess; - struct crypt_op cryp; - - memset(&sess, 0, sizeof(sess)); - memset(&cryp, 0, sizeof(cryp)); - - memset(plaintext1, 0x0, sizeof(plaintext1)); - memset(iv1, 0x0, sizeof(iv1)); - - /* Get crypto session for AES128 */ - sess.cipher = CRYPTO_AES_CBC; - sess.keylen = KEY_SIZE; - sess.key = key1; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - /* Encrypt data.in to data.encrypted */ - cryp.ses = sess.ses; - cryp.len = sizeof(plaintext1); - cryp.src = plaintext1; - cryp.dst = plaintext1; - cryp.iv = iv1; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - /* Verify the result */ - if (memcmp(plaintext1, ciphertext1, sizeof(plaintext1)) != 0) { - fprintf(stderr, - "FAIL: Decrypted data are different from the input data.\n"); - return 1; - } - - /* Test 2 */ - - memset(key2, 0x0, sizeof(key2)); - memset(iv2, 0x0, sizeof(iv2)); - - /* Get crypto session for AES128 */ - sess.cipher = CRYPTO_AES_CBC; - sess.keylen = KEY_SIZE; - sess.key = key2; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - /* Encrypt data.in to data.encrypted */ - cryp.ses = sess.ses; - cryp.len = sizeof(plaintext2); - cryp.src = plaintext2; - cryp.dst = plaintext2; - cryp.iv = iv2; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - /* Verify the result */ - if (memcmp(plaintext2, ciphertext2, sizeof(plaintext2)) != 0) { - fprintf(stderr, - "FAIL: Decrypted data are different from the input data.\n"); - return 1; - } - - printf("AES Test passed\n"); - - /* Finish crypto session */ - if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { - perror("ioctl(CIOCFSESSION)"); - return 1; - } - - return 0; -} - -int -main() -{ - int fd = -1, cfd = -1; - - /* Open the crypto device */ - fd = open("/dev/crypto", O_RDWR, 0); - if (fd < 0) { - perror("open(/dev/crypto)"); - return 1; - } - - /* Clone file descriptor */ - if (ioctl(fd, CRIOGET, &cfd)) { - perror("ioctl(CRIOGET)"); - return 1; - } - - /* Set close-on-exec (not really neede here) */ - if (fcntl(cfd, F_SETFD, 1) == -1) { - perror("fcntl(F_SETFD)"); - return 1; - } - - /* Run the test itself */ - if (test_aes(cfd)) - return 1; - - if (test_crypto(cfd)) - return 1; - - /* Close cloned descriptor */ - if (close(cfd)) { - perror("close(cfd)"); - return 1; - } - - /* Close the original descriptor */ - if (close(fd)) { - perror("close(fd)"); - return 1; - } - - return 0; -} - diff --git a/examples/hmac.c b/examples/hmac.c deleted file mode 100644 index c54d741..0000000 --- a/examples/hmac.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Demo on how to use /dev/crypto device for HMAC. - * - * Placed under public domain. - * - */ -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/ioctl.h> -#include "../cryptodev.h" - -#define DATA_SIZE 4096 -#define BLOCK_SIZE 16 -#define KEY_SIZE 16 -#define SHA1_HASH_LEN 20 - -static int -test_crypto(int cfd) -{ - struct { - uint8_t in[DATA_SIZE], - encrypted[DATA_SIZE], - decrypted[DATA_SIZE], - iv[BLOCK_SIZE], - key[KEY_SIZE]; - } data; - struct session_op sess; - struct crypt_op cryp; - uint8_t mac[AALG_MAX_RESULT_LEN]; - uint8_t oldmac[AALG_MAX_RESULT_LEN]; - uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38"; - uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32"; - int i; - - memset(&sess, 0, sizeof(sess)); - memset(&cryp, 0, sizeof(cryp)); - - /* Use the garbage that is on the stack :-) */ - /* memset(&data, 0, sizeof(data)); */ - - /* SHA1 plain test */ - memset(mac, 0, sizeof(mac)); - - sess.cipher = 0; - sess.mac = CRYPTO_SHA1; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - cryp.ses = sess.ses; - cryp.len = sizeof("what do ya want for nothing?")-1; - cryp.src = "what do ya want for nothing?"; - cryp.mac = mac; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - if (memcmp(mac, sha1_out, 20)!=0) { - printf("mac: "); - for (i=0;i<SHA1_HASH_LEN;i++) { - printf("%.2x", (uint8_t)mac[i]); - } - puts("\n"); - fprintf(stderr, "HASH test 1: failed\n"); - } else { - fprintf(stderr, "HASH test 1: passed\n"); - } - - /* MD5-HMAC test */ - memset(mac, 0, sizeof(mac)); - - sess.cipher = 0; - sess.mackey = (uint8_t*)"Jefe"; - sess.mackeylen = 4; - sess.mac = CRYPTO_MD5_HMAC; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - cryp.ses = sess.ses; - cryp.len = sizeof("what do ya want for nothing?")-1; - cryp.src = "what do ya want for nothing?"; - cryp.mac = mac; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - if (memcmp(mac, md5_hmac_out, 16)!=0) { - printf("mac: "); - for (i=0;i<SHA1_HASH_LEN;i++) { - printf("%.2x", (uint8_t)mac[i]); - } - puts("\n"); - fprintf(stderr, "HMAC test 1: failed\n"); - } else { - fprintf(stderr, "HMAC test 1: passed\n"); - } - - /* Hash and encryption in one step test */ - sess.cipher = CRYPTO_AES_CBC; - sess.mac = CRYPTO_SHA1_HMAC; - sess.keylen = KEY_SIZE; - sess.key = data.key; - sess.mackeylen = 16; - sess.mackey = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; - if (ioctl(cfd, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - /* Encrypt data.in to data.encrypted */ - cryp.ses = sess.ses; - cryp.len = sizeof(data.in); - cryp.src = data.in; - cryp.dst = data.encrypted; - cryp.iv = data.iv; - cryp.mac = mac; - cryp.op = COP_ENCRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - memcpy(oldmac, mac, sizeof(mac)); - - /* Decrypt data.encrypted to data.decrypted */ - cryp.src = data.encrypted; - cryp.dst = data.decrypted; - cryp.op = COP_DECRYPT; - if (ioctl(cfd, CIOCCRYPT, &cryp)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - - /* Verify the result */ - if (memcmp(data.in, data.decrypted, sizeof(data.in)) != 0) { - fprintf(stderr, - "FAIL: Decrypted data are different from the input data.\n"); - return 1; - } else - printf("Crypt Test: passed\n"); - - if (memcmp(mac, oldmac, 20) != 0) { - fprintf(stderr, - "FAIL: Hash in decrypted data different than in encrypted.\n"); - return 1; - } else - printf("HMAC Test 2: passed\n"); - - /* Finish crypto session */ - if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { - perror("ioctl(CIOCFSESSION)"); - return 1; - } - - return 0; -} - -int -main() -{ - int fd = -1, cfd = -1; - - /* Open the crypto device */ - fd = open("/dev/crypto", O_RDWR, 0); - if (fd < 0) { - perror("open(/dev/crypto)"); - return 1; - } - - /* Clone file descriptor */ - if (ioctl(fd, CRIOGET, &cfd)) { - perror("ioctl(CRIOGET)"); - return 1; - } - - /* Set close-on-exec (not really neede here) */ - if (fcntl(cfd, F_SETFD, 1) == -1) { - perror("fcntl(F_SETFD)"); - return 1; - } - - /* Run the test itself */ - if (test_crypto(cfd)) - return 1; - - /* Close cloned descriptor */ - if (close(cfd)) { - perror("close(cfd)"); - return 1; - } - - /* Close the original descriptor */ - if (close(fd)) { - perror("close(fd)"); - return 1; - } - - return 0; -} diff --git a/examples/speed.c b/examples/speed.c index 5898aaa..a46cedb 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -26,7 +26,6 @@ #include <sys/stat.h> #include <signal.h> #include <unistd.h> -#include "../cryptodev.h" #include "../ncr.h" static double udifftimeval(struct timeval start, struct timeval end) @@ -68,55 +67,6 @@ static void value2human(double bytes, double time, double* data, double* speed,c } -int encrypt_data(struct session_op *sess, int fdc, int chunksize) -{ - struct crypt_op cop; - char *buffer, iv[32]; - static int val = 23; - struct timeval start, end; - double total = 0; - double secs, ddata, dspeed; - char metric[16]; - - buffer = malloc(chunksize); - memset(iv, 0x23, 32); - - printf("\tEncrypting in chunks of %d bytes: ", chunksize); - fflush(stdout); - - memset(buffer, val++, chunksize); - - must_finish = 0; - alarm(5); - - gettimeofday(&start, NULL); - do { - memset(&cop, 0, sizeof(cop)); - cop.ses = sess->ses; - cop.len = chunksize; - cop.iv = (unsigned char *)iv; - cop.op = COP_ENCRYPT; - cop.flags = 0; - cop.src = cop.dst = (unsigned char *)buffer; - - if (ioctl(fdc, CIOCCRYPT, &cop)) { - perror("ioctl(CIOCCRYPT)"); - return 1; - } - total+=chunksize; - } while(must_finish==0); - gettimeofday(&end, NULL); - - secs = udifftimeval(start, end)/ 1000000.0; - - value2human(total, secs, &ddata, &dspeed, metric); - printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs); - printf ("%.2f %s/sec\n", dspeed, metric); - - return 0; -} - - int encrypt_data_ncr_direct(int cfd, int algo, int chunksize) { char *buffer, iv[32]; @@ -191,9 +141,7 @@ int encrypt_data_ncr_direct(int cfd, int algo, int chunksize) int main(void) { - int fd, i, fdc = -1; - struct session_op sess; - char keybuf[32]; + int fd, i; signal(SIGALRM, alarm_handler); @@ -201,57 +149,20 @@ int main(void) perror("open()"); return 1; } - if (ioctl(fd, CRIOGET, &fdc)) { - perror("ioctl(CRIOGET)"); - return 1; - } - - fprintf(stderr, "Testing NULL cipher: \n"); - memset(&sess, 0, sizeof(sess)); - sess.cipher = CRYPTO_NULL; - sess.keylen = 0; - sess.key = (unsigned char *)keybuf; - if (ioctl(fdc, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data(&sess, fdc, i)) - break; - } fprintf(stderr, "\nTesting NCR-DIRECT with NULL cipher: \n"); for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data_ncr_direct(fdc, NCR_ALG_NULL, i)) + if (encrypt_data_ncr_direct(fd, NCR_ALG_NULL, i)) break; } - fprintf(stderr, "\nTesting AES-128-CBC cipher: \n"); - memset(&sess, 0, sizeof(sess)); - sess.cipher = CRYPTO_AES_CBC; - sess.keylen = 16; - memset(keybuf, 0x42, 16); - sess.key = (unsigned char *)keybuf; - if (ioctl(fdc, CIOCGSESSION, &sess)) { - perror("ioctl(CIOCGSESSION)"); - return 1; - } - - for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data(&sess, fdc, i)) - break; - } - fprintf(stderr, "\nTesting NCR-DIRECT with AES-128-CBC cipher: \n"); for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data_ncr_direct(fdc, NCR_ALG_AES_CBC, i)) + if (encrypt_data_ncr_direct(fd, NCR_ALG_AES_CBC, i)) break; } - - close(fdc); close(fd); return 0; } diff --git a/extras/openssl-0.9.8k-cryptodev-linux.diff b/extras/openssl-0.9.8k-cryptodev-linux.diff deleted file mode 100644 index 0a43e63..0000000 --- a/extras/openssl-0.9.8k-cryptodev-linux.diff +++ /dev/null @@ -1,74 +0,0 @@ -diff -ur openssl-0.9.8k/crypto/engine/eng_all.c openssl-0.9.8k.new/crypto/engine/eng_all.c ---- openssl-0.9.8k/crypto/engine/eng_all.c 2008-06-04 21:01:39.000000000 +0300 -+++ openssl-0.9.8k.new/crypto/engine/eng_all.c 2009-11-24 13:41:49.000000000 +0200 -@@ -104,16 +104,15 @@ - #endif - #endif - #ifndef OPENSSL_NO_HW --#if defined(__OpenBSD__) || defined(__FreeBSD__) -+# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__linux__) - ENGINE_load_cryptodev(); --#endif -+# endif - #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) - ENGINE_load_capi(); - #endif - #endif - } - --#if defined(__OpenBSD__) || defined(__FreeBSD__) - void ENGINE_setup_bsd_cryptodev(void) { - static int bsd_cryptodev_default_loaded = 0; - if (!bsd_cryptodev_default_loaded) { -@@ -122,4 +121,3 @@ - } - bsd_cryptodev_default_loaded=1; - } --#endif -diff -ur openssl-0.9.8k/crypto/engine/eng_cryptodev.c openssl-0.9.8k.new/crypto/engine/eng_cryptodev.c ---- openssl-0.9.8k/crypto/engine/eng_cryptodev.c 2004-06-15 14:45:42.000000000 +0300 -+++ openssl-0.9.8k.new/crypto/engine/eng_cryptodev.c 2009-11-24 13:45:31.000000000 +0200 -@@ -34,14 +34,15 @@ - #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ - (defined(OpenBSD) || defined(__FreeBSD_version)) - #include <sys/param.h> --# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) --# define HAVE_CRYPTODEV --# endif - # if (OpenBSD >= 200110) - # define HAVE_SYSLOG_R - # endif - #endif - -+#if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__linux__) -+# define HAVE_CRYPTODEV -+#endif -+ - #ifndef HAVE_CRYPTODEV - - void -diff -ur openssl-0.9.8k/crypto/engine/engine.h openssl-0.9.8k.new/crypto/engine/engine.h ---- openssl-0.9.8k/crypto/engine/engine.h 2008-06-04 21:01:40.000000000 +0300 -+++ openssl-0.9.8k.new/crypto/engine/engine.h 2009-11-24 13:41:49.000000000 +0200 -@@ -703,9 +703,7 @@ - * values. */ - void *ENGINE_get_static_state(void); - --#if defined(__OpenBSD__) || defined(__FreeBSD__) - void ENGINE_setup_bsd_cryptodev(void); --#endif - - /* BEGIN ERROR CODES */ - /* The following lines are auto generated by the script mkerr.pl. Any changes -diff -ur openssl-0.9.8k/crypto/evp/c_all.c openssl-0.9.8k.new/crypto/evp/c_all.c ---- openssl-0.9.8k/crypto/evp/c_all.c 2004-08-29 19:36:04.000000000 +0300 -+++ openssl-0.9.8k.new/crypto/evp/c_all.c 2009-11-24 13:41:49.000000000 +0200 -@@ -83,8 +83,6 @@ - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); - #ifndef OPENSSL_NO_ENGINE --# if defined(__OpenBSD__) || defined(__FreeBSD__) - ENGINE_setup_bsd_cryptodev(); --# endif - #endif - } diff --git a/extras/openssl-0.9.8l-cryptodev-aes256.patch b/extras/openssl-0.9.8l-cryptodev-aes256.patch deleted file mode 100644 index cf9bbbc..0000000 --- a/extras/openssl-0.9.8l-cryptodev-aes256.patch +++ /dev/null @@ -1,112 +0,0 @@ -This is http://people.freebsd.org/~pjd/patches/hw_cryptodev.c.patch adopted for -openssl-0.9.8l. It makes AES192 and AES256 CBC known to the cryptodev engine. - -There's also http://people.freebsd.org/~pjd/patches/eng_cryptodev.c.patch, -which seems more current, also adds SHA digests and does somehting CTX-related -to cryptodev_rsa_nocrt_mod_exp(). But since digests are disabled in -cryptodev_usable_digests() anyway and cryptodev_rsa_nocrt_mod_exp() is used for -RSA only, I didn't bother with it. - ---- openssl-0.9.8l/crypto/engine/eng_cryptodev.caes256 2004-06-15 13:45:42.000000000 +0200 -+++ openssl-0.9.8l/crypto/engine/eng_cryptodev.c 2010-02-16 21:57:15.000000000 +0100 -@@ -133,11 +133,14 @@ - { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, - { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, - { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, -+ { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, }, -+ { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, }, - { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, - { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, - { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, - { 0, NID_undef, 0, 0, }, - }; -+#define NCIPHERS (sizeof(ciphers) / sizeof(ciphers[0])) - - static struct { - int id; -@@ -229,8 +232,8 @@ - int i; - - for (i = 0; ciphers[i].id; i++) -- if (ciphers[i].id == cipher) -- return (ciphers[i].keylen == len); -+ if (ciphers[i].id == cipher && ciphers[i].keylen == len) -+ return (1); - return (0); - } - -@@ -255,7 +258,7 @@ - static int - get_cryptodev_ciphers(const int **cnids) - { -- static int nids[CRYPTO_ALGORITHM_MAX]; -+ static int nids[NCIPHERS]; - struct session_op sess; - int fd, i, count = 0; - -@@ -266,7 +269,7 @@ - memset(&sess, 0, sizeof(sess)); - sess.key = (caddr_t)"123456781234567812345678"; - -- for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { -+ for (i = 0; ciphers[i].id && count < NCIPHERS; i++) { - if (ciphers[i].nid == NID_undef) - continue; - sess.cipher = ciphers[i].id; -@@ -550,7 +553,7 @@ - NULL - }; - --const EVP_CIPHER cryptodev_aes_cbc = { -+const EVP_CIPHER cryptodev_aes128_cbc = { - NID_aes_128_cbc, - 16, 16, 16, - EVP_CIPH_CBC_MODE, -@@ -563,6 +566,32 @@ - NULL - }; - -+const EVP_CIPHER cryptodev_aes192_cbc = { -+ NID_aes_192_cbc, -+ 16, 24, 16, -+ EVP_CIPH_CBC_MODE, -+ cryptodev_init_key, -+ cryptodev_cipher, -+ cryptodev_cleanup, -+ sizeof(struct dev_crypto_state), -+ EVP_CIPHER_set_asn1_iv, -+ EVP_CIPHER_get_asn1_iv, -+ NULL -+}; -+ -+const EVP_CIPHER cryptodev_aes256_cbc = { -+ NID_aes_256_cbc, -+ 16, 32, 16, -+ EVP_CIPH_CBC_MODE, -+ cryptodev_init_key, -+ cryptodev_cipher, -+ cryptodev_cleanup, -+ sizeof(struct dev_crypto_state), -+ EVP_CIPHER_set_asn1_iv, -+ EVP_CIPHER_get_asn1_iv, -+ NULL -+}; -+ - /* - * Registered by the ENGINE when used to find out how to deal with - * a particular NID in the ENGINE. this says what we'll do at the -@@ -589,7 +618,13 @@ - *cipher = &cryptodev_cast_cbc; - break; - case NID_aes_128_cbc: -- *cipher = &cryptodev_aes_cbc; -+ *cipher = &cryptodev_aes128_cbc; -+ break; -+ case NID_aes_192_cbc: -+ *cipher = &cryptodev_aes192_cbc; -+ break; -+ case NID_aes_256_cbc: -+ *cipher = &cryptodev_aes256_cbc; - break; - default: - *cipher = NULL; @@ -27,7 +27,6 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include <ncr.h> #include <ncr-int.h> @@ -104,8 +104,7 @@ struct ncr_lists { void* ncr_init_lists(void); void ncr_deinit_lists(struct ncr_lists *lst); -int ncr_ioctl(struct ncr_lists*, struct file *filp, - unsigned int cmd, unsigned long arg); +int ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg); /* key derivation */ int ncr_key_derive(struct ncr_lists *lst, void __user* arg); diff --git a/ncr-key-storage.c b/ncr-key-storage.c index fc6948f..f00bce8 100644 --- a/ncr-key-storage.c +++ b/ncr-key-storage.c @@ -26,7 +26,6 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include "ncr.h" #include "ncr-int.h" diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index 0c56def..7470508 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -28,7 +28,6 @@ #include <linux/highmem.h> #include <linux/random.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include "ncr.h" #include "ncr-int.h" @@ -27,7 +27,6 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include "ncr.h" #include "ncr-int.h" diff --git a/ncr-limits.c b/ncr-limits.c index 34acac7..0c12824 100644 --- a/ncr-limits.c +++ b/ncr-limits.c @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <linux/highmem.h> #include <linux/random.h> -#include "cryptodev.h" #include <asm/atomic.h> #include <linux/version.h> #include <linux/file.h> @@ -27,7 +27,6 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include "ncr.h" #include "ncr-int.h" diff --git a/ncr-sessions.c b/ncr-sessions.c index 2916729..ee9e042 100644 --- a/ncr-sessions.c +++ b/ncr-sessions.c @@ -25,7 +25,6 @@ #include <linux/crypto.h> #include <linux/mutex.h> -#include "cryptodev.h" #include "ncr.h" #include "ncr-int.h" #include <linux/mm_types.h> @@ -28,7 +28,6 @@ #include <linux/highmem.h> #include <linux/random.h> #include <linux/uaccess.h> -#include "cryptodev.h" #include <linux/scatterlist.h> #include <linux/cred.h> #include <linux/capability.h> @@ -117,8 +116,7 @@ struct ncr_master_key_st st; } int -ncr_ioctl(struct ncr_lists* lst, struct file *filp, - unsigned int cmd, unsigned long arg_) +ncr_ioctl(struct ncr_lists *lst, unsigned int cmd, unsigned long arg_) { void __user *arg = (void __user *)arg_; |