summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile3
-rw-r--r--cryptodev.h154
-rw-r--r--cryptodev_cipher.c1
-rw-r--r--cryptodev_int.h41
-rw-r--r--cryptodev_main.c825
-rw-r--r--examples/Makefile10
-rw-r--r--examples/cipher.c230
-rw-r--r--examples/hmac.c210
-rw-r--r--examples/speed.c95
-rw-r--r--extras/openssl-0.9.8k-cryptodev-linux.diff74
-rw-r--r--extras/openssl-0.9.8l-cryptodev-aes256.patch112
-rw-r--r--ncr-dh.c1
-rw-r--r--ncr-int.h3
-rw-r--r--ncr-key-storage.c1
-rw-r--r--ncr-key-wrap.c1
-rw-r--r--ncr-key.c1
-rw-r--r--ncr-limits.c1
-rw-r--r--ncr-pk.c1
-rw-r--r--ncr-sessions.c1
-rw-r--r--ncr.c4
21 files changed, 25 insertions, 1746 deletions
diff --git a/.gitignore b/.gitignore
index e293651..9ea2609 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,8 +7,6 @@ Module.symvers
*.o
*.mod.c
modules.order
-examples/cipher
-examples/hmac
examples/ncr
examples/ncr_lib
examples/pk
diff --git a/Makefile b/Makefile
index 72439b2..fa221a9 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
diff --git a/ncr-dh.c b/ncr-dh.c
index 235d021..2c595f6 100644
--- a/ncr-dh.c
+++ b/ncr-dh.c
@@ -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-int.h b/ncr-int.h
index 84bca9e..2689804 100644
--- a/ncr-int.h
+++ b/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"
diff --git a/ncr-key.c b/ncr-key.c
index bf438fa..83e6a9e 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -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>
diff --git a/ncr-pk.c b/ncr-pk.c
index 1e83163..c4792c6 100644
--- a/ncr-pk.c
+++ b/ncr-pk.c
@@ -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>
diff --git a/ncr.c b/ncr.c
index 86c8c7a..99d2786 100644
--- a/ncr.c
+++ b/ncr.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 <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_;