diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-07-26 19:08:44 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-07-26 19:08:44 +0200 |
commit | afed807b11199877214ec2e5d81e96c230237759 (patch) | |
tree | 8b01ef8a6f881656d78e4f54b60a9ea41187a175 | |
parent | d750b60952619af570ac4d91cd650ffa6bbe311d (diff) | |
parent | 935be4945512eb37461a226c51ede5e8b05cbe24 (diff) | |
download | cryptodev-linux-afed807b11199877214ec2e5d81e96c230237759.tar.gz cryptodev-linux-afed807b11199877214ec2e5d81e96c230237759.tar.xz cryptodev-linux-afed807b11199877214ec2e5d81e96c230237759.zip |
Merge branch 'master' into algorithm-speedup
Conflicts:
libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c
libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c
libtomcrypt/pk/rsa/rsa_decrypt_key.c
libtomcrypt/pk/rsa/rsa_encrypt_key.c
libtomcrypt/pk/rsa/rsa_sign_hash.c
libtomcrypt/pk/rsa/rsa_verify_hash.c
ncr-int.h
ncr-key.c
ncr-pk.c
ncr-sessions.c
32 files changed, 1258 insertions, 1572 deletions
@@ -67,7 +67,7 @@ TOMCRYPT_OBJECTS = libtomcrypt/misc/zeromem.o libtomcrypt/misc/crypt/crypt_argch libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.o cryptodev-objs = cryptodev_main.o cryptodev_cipher.o ncr.o \ - ncr-data.o ncr-key.o ncr-limits.o ncr-sessions.o ncr-pk.o \ + ncr-key.o ncr-limits.o ncr-pk.o ncr-sessions.o \ ncr-key-wrap.o ncr-key-storage.o $(TOMMATH_OBJECTS) \ $(TOMCRYPT_OBJECTS) @@ -75,22 +75,22 @@ cryptodev-objs = cryptodev_main.o cryptodev_cipher.o ncr.o \ obj-m += cryptodev.o build: - @make version.h - make -C $(KERNEL_DIR) SUBDIRS=`pwd` modules + @$(MAKE) version.h + $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules install: - make -C $(KERNEL_DIR) SUBDIRS=`pwd` modules_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 @install -D ncr.h /usr/include/crypto/ncr.h clean: - make -C $(KERNEL_DIR) SUBDIRS=`pwd` clean + $(MAKE) -C $(KERNEL_DIR) SUBDIRS=`pwd` clean rm -f $(hostprogs) - KERNEL_DIR=$(KERNEL_DIR) make -C examples clean + KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C examples clean check: - KERNEL_DIR=$(KERNEL_DIR) make -C examples check + KERNEL_DIR=$(KERNEL_DIR) $(MAKE) -C examples check FILEBASE = cryptodev-linux-$(VERSION) TMPDIR ?= /tmp diff --git a/cryptodev_cipher.c b/cryptodev_cipher.c index fa5aab2..0dd0db7 100644 --- a/cryptodev_cipher.c +++ b/cryptodev_cipher.c @@ -188,24 +188,24 @@ struct scatterlist sg, sg2; } -ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len) +ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len) { int ret; INIT_COMPLETION(cdata->async.result->completion); - ablkcipher_request_set_crypt(cdata->async.request, sg1, sg2, + ablkcipher_request_set_crypt(cdata->async.request, (struct scatterlist*)sg1, sg2, len, cdata->async.iv); ret = crypto_ablkcipher_encrypt(cdata->async.request); return waitfor(cdata->async.result,ret); } -ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len) +ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len) { int ret; INIT_COMPLETION(cdata->async.result->completion); - ablkcipher_request_set_crypt(cdata->async.request, sg1, sg2, + ablkcipher_request_set_crypt(cdata->async.request, (struct scatterlist*)sg1, sg2, len, cdata->async.iv); ret = crypto_ablkcipher_decrypt(cdata->async.request); diff --git a/cryptodev_int.h b/cryptodev_int.h index a0d3073..3c6eca4 100644 --- a/cryptodev_int.h +++ b/cryptodev_int.h @@ -24,6 +24,18 @@ extern int cryptodev_verbosity; +/* For zero copy */ +int __get_userbuf(uint8_t *addr, uint32_t len, int write, + int pgcount, struct page **pg, struct scatterlist *sg); +void release_user_pages(struct page **pg, int pagecount); + +/* last page - first page + 1 */ +#define PAGECOUNT(buf, buflen) \ + ((((unsigned long)(buf + buflen - 1) & PAGE_MASK) >> PAGE_SHIFT) - \ + (((unsigned long) buf & PAGE_MASK) >> PAGE_SHIFT) + 1) + +#define DEFAULT_PREALLOC_PAGES 32 + struct cipher_data { int init; /* 0 uninitialized */ @@ -39,8 +51,8 @@ struct cipher_data int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t * key, size_t keylen); void cryptodev_cipher_deinit(struct cipher_data* cdata); -ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len); -ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len); +ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len); +ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len); void cryptodev_cipher_set_iv(struct cipher_data* cdata, void* iv, size_t iv_size); int _cryptodev_cipher_decrypt(struct cipher_data* cdata, const void* ciphertext, diff --git a/cryptodev_main.c b/cryptodev_main.c index 0316a74..7ed0911 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -41,7 +41,7 @@ #include <asm/ioctl.h> #include <linux/scatterlist.h> #include "cryptodev_int.h" -#include "ncr_int.h" +#include "ncr-int.h" #include <linux/version.h> #include "version.h" @@ -65,8 +65,6 @@ module_param(enable_stats, int, 0644); MODULE_PARM_DESC(enable_stats, "collect statictics about cryptodev usage"); #endif -#define DEFAULT_PREALLOC_PAGES 16 - /* ====== CryptoAPI ====== */ struct fcrypt { struct list_head list; @@ -138,6 +136,9 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) 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; @@ -495,7 +496,7 @@ __crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop) #ifndef DISABLE_ZCOPY -static void release_user_pages(struct page **pg, int pagecount) +void release_user_pages(struct page **pg, int pagecount) { while (pagecount--) { if (!PageReserved(pg[pagecount])) @@ -504,16 +505,11 @@ static void release_user_pages(struct page **pg, int pagecount) } } -/* last page - first page + 1 */ -#define PAGECOUNT(buf, buflen) \ - ((((unsigned long)(buf + buflen - 1) & PAGE_MASK) >> PAGE_SHIFT) - \ - (((unsigned long) buf & PAGE_MASK) >> PAGE_SHIFT) + 1) - /* offset of buf in it's first page */ #define PAGEOFFSET(buf) ((unsigned long)buf & ~PAGE_MASK) /* fetch the pages addr resides in into pg and initialise sg with them */ -static int __get_userbuf(uint8_t *addr, uint32_t len, int write, +int __get_userbuf(uint8_t *addr, uint32_t len, int write, int pgcount, struct page **pg, struct scatterlist *sg) { int ret, pglen, i = 0; diff --git a/examples/Makefile b/examples/Makefile index c65297f..100cc49 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -28,4 +28,4 @@ check: $(progs) ./speed clean: - rm -f *.o *~ hmac cipher ncr pk speed + rm -f *.o *~ hmac cipher ncr pk speed
\ No newline at end of file diff --git a/examples/ncr.c b/examples/ncr.c index 234e8bd..4231ffa 100644 --- a/examples/ncr.c +++ b/examples/ncr.c @@ -32,11 +32,9 @@ int i; static int test_ncr_key(int cfd) { - struct ncr_data_init_st dinit; struct ncr_key_generate_st kgen; ncr_key_t key; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; uint8_t data[KEY_DATA_SIZE]; uint8_t data_bak[KEY_DATA_SIZE]; @@ -51,17 +49,6 @@ test_ncr_key(int cfd) randomize_data(data, sizeof(data)); memcpy(data_bak, data, sizeof(data)); - dinit.max_object_size = KEY_DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = data; - dinit.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { perror("ioctl(NCRIO_KEY_INIT)"); @@ -76,7 +63,8 @@ test_ncr_key(int cfd) keydata.flags = NCR_KEY_FLAG_EXPORTABLE; keydata.key = key; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -86,43 +74,21 @@ test_ncr_key(int cfd) /* now try to read it */ fprintf(stdout, "\tKey export...\n"); - if (ioctl(cfd, NCRIO_DATA_DEINIT, &dinit.desc)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_DEINIT)"); - return 1; - } - - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = NULL; - dinit.initial_data_size = 0; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } memset(&keydata, 0, sizeof(keydata)); keydata.key = key; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - - /* now read data */ - memset(&kdata, 0, sizeof(kdata)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { + + if (keydata.idata_size != sizeof(data)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); + fprintf(stderr, "data returned but differ!\n"); return 1; } @@ -162,9 +128,12 @@ test_ncr_key(int cfd) return 1; } + memset(data, 0, sizeof(data)); + memset(&keydata, 0, sizeof(keydata)); keydata.key = key; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -172,27 +141,16 @@ test_ncr_key(int cfd) return 1; } - /* now read data */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { + if (keydata.idata_size == 0 || (data[0] == 0 && data[1] == 0 && data[2] == 0 && data[4] == 0)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); + fprintf(stderr, "Generated key: %.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x." + "%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x\n", data[0], data[1], + data[2], data[3], data[4], data[5], data[6], data[7], data[8], + data[9], data[10], data[11], data[12], data[13], data[14], + data[15]); return 1; } -#if 0 - fprintf(stderr, "Generated key: %.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x." - "%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x.%.2x\n", data[0], data[1], - data[2], data[3], data[4], data[5], data[6], data[7], data[8], - data[9], data[10], data[11], data[12], data[13], data[14], - data[15]); -#endif - if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_DEINIT)"); @@ -219,24 +177,16 @@ test_ncr_key(int cfd) return 1; } + memset(data, 0, sizeof(data)); + memset(&keydata, 0, sizeof(keydata)); keydata.key = key; - keydata.data = dinit.desc; - - if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_EXPORT)"); - return 1; - } + keydata.idata = data; + keydata.idata_size = sizeof(data); /* try to get the output data - should fail */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)==0) { + if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)==0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "Data were exported, but shouldn't be!\n"); return 1; @@ -252,138 +202,17 @@ test_ncr_key(int cfd) } -static int test_ncr_data(int cfd) -{ - struct ncr_data_init_st init; - struct ncr_data_st kdata; - uint8_t data[DATA_SIZE]; - uint8_t data_bak[DATA_SIZE]; - int i; - - fprintf(stdout, "Tests on Data:\n"); - - randomize_data(data, sizeof(data)); - memcpy(data_bak, data, sizeof(data)); - - init.max_object_size = DATA_SIZE; - init.flags = NCR_DATA_FLAG_EXPORTABLE; - init.initial_data = data; - init.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &init)) { - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - fprintf(stdout, "\tData Import...\n"); - - memset(data, 0, sizeof(data)); - - kdata.desc = init.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - if (memcmp(data, data_bak, sizeof(data))!=0) { - fprintf(stderr, "data returned but differ!\n"); - return 1; - } - - fprintf(stdout, "\tData Export...\n"); - - /* test set */ - memset(data, 0xf1, sizeof(data)); - - kdata.desc = init.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } - - /* test get after set */ - memset(data, 0, sizeof(data)); - - kdata.desc = init.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - for(i=0;i<kdata.data_size;i++) { - if (((uint8_t*)kdata.data)[i] != 0xf1) { - fprintf(stderr, "data returned but differ!\n"); - return 1; - } - } - fprintf(stdout, "\t2nd Data Import/Export...\n"); - - if (ioctl(cfd, NCRIO_DATA_DEINIT, &kdata.desc)) { - perror("ioctl(NCRIO_DATA_DEINIT)"); - return 1; - } - - fprintf(stdout, "\tProtection of non-exportable data...\n"); - randomize_data(data, sizeof(data)); - - init.max_object_size = DATA_SIZE; - init.flags = 0; - init.initial_data = data; - init.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &init)) { - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - kdata.desc = init.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)==0) { - fprintf(stderr, "Unexportable data were exported!?\n"); - return 1; - } - - fprintf(stdout, "\tLimits on maximum allowed data...\n"); - for (i=0;i<256;i++ ) { - init.max_object_size = DATA_SIZE; - init.flags = 0; - init.initial_data = data; - init.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &init)) { - //fprintf(stderr, "Reached maximum limit at: %d data items\n", i); - break; - } - } - - /* shouldn't run any other tests after that */ - - return 0; -} /* Key wrapping */ static int test_ncr_wrap_key(int cfd) { int i; - struct ncr_data_init_st dinit; ncr_key_t key, key2; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; struct ncr_key_wrap_st kwrap; uint8_t data[WRAPPED_KEY_DATA_SIZE]; - + int data_size; fprintf(stdout, "Tests on Keys:\n"); @@ -393,17 +222,6 @@ test_ncr_wrap_key(int cfd) fprintf(stdout, "\tKey Wrap test...\n"); - dinit.max_object_size = WRAPPED_KEY_DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; - dinit.initial_data_size = 16; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { perror("ioctl(NCRIO_KEY_INIT)"); @@ -418,7 +236,8 @@ test_ncr_wrap_key(int cfd) keydata.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; keydata.key = key; - keydata.data = dinit.desc; + keydata.idata = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + keydata.idata_size = 16; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -426,17 +245,6 @@ test_ncr_wrap_key(int cfd) return 1; } -#define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" - /* now key data */ - kdata.data = DKEY; - kdata.data_size = 16; - kdata.desc = dinit.desc; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key2)) { @@ -452,7 +260,9 @@ test_ncr_wrap_key(int cfd) keydata.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; keydata.key = key2; - keydata.data = kdata.desc; +#define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + keydata.idata = DKEY; + keydata.idata_size = 16; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -465,29 +275,23 @@ test_ncr_wrap_key(int cfd) kwrap.algorithm = NCR_WALG_AES_RFC3394; kwrap.keytowrap = key2; kwrap.key = key; - kwrap.data = kdata.desc; + kwrap.io = data; + kwrap.io_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_WRAP, &kwrap)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_WRAP)"); return 1; } + + data_size = kwrap.io_size; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - if (kdata.data_size != 24 || memcmp(kdata.data, + if (kwrap.io_size != 24 || memcmp(data, "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24) != 0) { fprintf(stderr, "Wrapped data do not match.\n"); - fprintf(stderr, "Data[%d]: ",(int) kdata.data_size); - for(i=0;i<kdata.data_size;i++) + fprintf(stderr, "Data[%d]: ",(int) kwrap.io_size); + for(i=0;i<kwrap.io_size;i++) fprintf(stderr, "%.2x:", data[i]); fprintf(stderr, "\n"); return 1; @@ -514,7 +318,8 @@ test_ncr_wrap_key(int cfd) kwrap.algorithm = NCR_WALG_AES_RFC3394; kwrap.keytowrap = key2; kwrap.key = key; - kwrap.data = kdata.desc; + kwrap.io = data; + kwrap.io_size = data_size; if (ioctl(cfd, NCRIO_KEY_UNWRAP, &kwrap)) { perror("ioctl(NCRIO_KEY_UNWRAP)"); @@ -561,13 +366,11 @@ static int test_ncr_store_wrap_key(int cfd) { int i; - struct ncr_data_init_st dinit; ncr_key_t key2; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; struct ncr_key_storage_wrap_st kwrap; uint8_t data[DATA_SIZE]; - int dd; + int data_size; fprintf(stdout, "Tests on Key storage:\n"); @@ -577,30 +380,6 @@ test_ncr_store_wrap_key(int cfd) fprintf(stdout, "\tKey Storage wrap test...\n"); - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - dd = dinit.desc; - -#define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" - /* now key data */ - kdata.data = DKEY; - kdata.data_size = 16; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } - /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key2)) { perror("ioctl(NCRIO_KEY_INIT)"); @@ -615,7 +394,9 @@ test_ncr_store_wrap_key(int cfd) keydata.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; keydata.key = key2; - keydata.data = dd; +#define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + keydata.idata = DKEY; + keydata.idata_size = 16; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -626,7 +407,8 @@ test_ncr_store_wrap_key(int cfd) /* now try wrapping key2 using key */ memset(&kwrap, 0, sizeof(kwrap)); kwrap.keytowrap = key2; - kwrap.data = dd; + kwrap.io = data; + kwrap.io_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_STORAGE_WRAP, &kwrap)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -635,6 +417,7 @@ test_ncr_store_wrap_key(int cfd) } /* test unwrapping */ + data_size = kwrap.io_size; fprintf(stdout, "\tKey Storage Unwrap test...\n"); /* reset key2 */ @@ -652,7 +435,8 @@ test_ncr_store_wrap_key(int cfd) memset(&kwrap, 0, sizeof(kwrap)); kwrap.keytowrap = key2; - kwrap.data = dd; + kwrap.io = data; + kwrap.io_size = data_size; if (ioctl(cfd, NCRIO_KEY_STORAGE_UNWRAP, &kwrap)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -663,25 +447,21 @@ test_ncr_store_wrap_key(int cfd) /* now export the unwrapped */ memset(&keydata, 0, sizeof(keydata)); keydata.key = key2; - keydata.data = dd; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } + + data_size = keydata.idata_size; - kdata.data = data; - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - if (kdata.data_size != 16 || memcmp(kdata.data, DKEY, 16) != 0) { + if (data_size != 16 || memcmp(data, DKEY, 16) != 0) { fprintf(stderr, "Unwrapped data do not match.\n"); - fprintf(stderr, "Data[%d]: ", (int) kdata.data_size); - for(i=0;i<kdata.data_size;i++) + fprintf(stderr, "Data[%d]: ", (int) data_size); + for(i=0;i<data_size;i++) fprintf(stderr, "%.2x:", data[i]); fprintf(stderr, "\n"); return 1; @@ -727,35 +507,12 @@ struct aes_vectors_st { static int test_ncr_aes(int cfd) { - struct ncr_data_init_st dinit; ncr_key_t key; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; - ncr_data_t dd, dd2; uint8_t data[KEY_DATA_SIZE]; int i, j; struct ncr_session_once_op_st nop; - - dinit.max_object_size = KEY_DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = NULL; - dinit.initial_data_size = 0; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - dd = dinit.desc; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - dd2 = dinit.desc; + int data_size; /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { @@ -774,43 +531,25 @@ test_ncr_aes(int cfd) fprintf(stdout, "Tests on AES Encryption\n"); for (i=0;i<sizeof(aes_vectors)/sizeof(aes_vectors[0]);i++) { - /* import key */ - kdata.data = (void*)aes_vectors[i].key; - kdata.data_size = 16; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } - keydata.key = key; - keydata.data = dd; + keydata.idata = (void*)aes_vectors[i].key; + keydata.idata_size = 16; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - /* import data */ - - kdata.data = (void*)aes_vectors[i].plaintext; - kdata.data_size = 16; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } /* encrypt */ memset(&nop, 0, sizeof(nop)); nop.init.algorithm = NCR_ALG_AES_ECB; nop.init.key = key; nop.init.op = NCR_OP_ENCRYPT; - nop.op.data.cipher.plaintext = dd; - nop.op.data.cipher.ciphertext = dd2; + nop.op.data.udata.input = (void*)aes_vectors[i].plaintext; + nop.op.data.udata.input_size = 16; + nop.op.data.udata.output = data; + nop.op.data.udata.output_size = sizeof(data); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -818,22 +557,14 @@ test_ncr_aes(int cfd) return 1; } + data_size = nop.op.data.udata.output_size; /* verify */ - kdata.desc = dd2; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - if (kdata.data_size != 16 || memcmp(kdata.data, aes_vectors[i].ciphertext, 16) != 0) { + if (data_size != 16 || memcmp(data, aes_vectors[i].ciphertext, 16) != 0) { fprintf(stderr, "AES test vector %d failed!\n", i); - fprintf(stderr, "Cipher[%d]: ", (int)kdata.data_size); - for(j=0;j<kdata.data_size;j++) + fprintf(stderr, "Cipher[%d]: ", (int)data_size); + for(j=0;j<data_size;j++) fprintf(stderr, "%.2x:", (int)data[j]); fprintf(stderr, "\n"); @@ -848,67 +579,40 @@ test_ncr_aes(int cfd) fprintf(stdout, "Tests on AES Decryption\n"); for (i=0;i<sizeof(aes_vectors)/sizeof(aes_vectors[0]);i++) { - /* import key */ - kdata.data = (void*)aes_vectors[i].key; - kdata.data_size = 16; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } - keydata.key = key; - keydata.data = dd; + keydata.idata = (void*)aes_vectors[i].key; + keydata.idata_size = 16; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - /* import ciphertext */ - - kdata.data = (void*)aes_vectors[i].ciphertext; - kdata.data_size = 16; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } - /* decrypt */ memset(&nop, 0, sizeof(nop)); nop.init.algorithm = NCR_ALG_AES_ECB; nop.init.key = key; nop.init.op = NCR_OP_DECRYPT; - nop.op.data.cipher.ciphertext = dd; - nop.op.data.cipher.plaintext = dd2; + nop.op.data.udata.input = (void*)aes_vectors[i].ciphertext; + nop.op.data.udata.input_size = 16; + nop.op.data.udata.output = data; + nop.op.data.udata.output_size = sizeof(data); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } + + data_size = nop.op.data.udata.output_size; - /* verify */ - kdata.desc = dd2; - kdata.data = data; - kdata.data_size = sizeof(data); - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - if (kdata.data_size != 16 || memcmp(kdata.data, aes_vectors[i].plaintext, 16) != 0) { + if (data_size != 16 || memcmp(data, aes_vectors[i].plaintext, 16) != 0) { fprintf(stderr, "AES test vector %d failed!\n", i); - fprintf(stderr, "Plain[%d]: ", (int)kdata.data_size); - for(j=0;j<kdata.data_size;j++) + fprintf(stderr, "Plain[%d]: ", (int)data_size); + for(j=0;j<data_size;j++) fprintf(stderr, "%.2x:", (int)data[j]); fprintf(stderr, "\n"); @@ -946,7 +650,7 @@ struct hash_vectors_st { .plaintext_size = sizeof("what do ya want for nothing?")-1, .output = (uint8_t*)"\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32", .output_size = 20, - .op = NCR_OP_DIGEST, + .op = NCR_OP_SIGN, }, { .name = "HMAC-MD5", @@ -1012,36 +716,12 @@ struct hash_vectors_st { static int test_ncr_hash(int cfd) { - struct ncr_data_init_st dinit; ncr_key_t key; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; - ncr_data_t dd, dd2; uint8_t data[HASH_DATA_SIZE]; - int i, j; + int i, j, data_size; struct ncr_session_once_op_st nop; - dinit.max_object_size = HASH_DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = NULL; - dinit.initial_data_size = 0; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - dd = dinit.desc; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - dd2 = dinit.desc; - /* convert it to key */ if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { perror("ioctl(NCRIO_KEY_INIT)"); @@ -1062,35 +742,16 @@ test_ncr_hash(int cfd) fprintf(stdout, "\t%s:\n", hash_vectors[i].name); /* import key */ if (hash_vectors[i].key != NULL) { - kdata.data = (void*)hash_vectors[i].key; - kdata.data_size = hash_vectors[i].key_size; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } keydata.key = key; - keydata.data = dd; + keydata.idata = (void*)hash_vectors[i].key; + keydata.idata_size = hash_vectors[i].key_size; if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } } - /* import data */ - - kdata.data = (void*)hash_vectors[i].plaintext; - kdata.data_size = hash_vectors[i].plaintext_size; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_SET)"); - return 1; - } /* encrypt */ memset(&nop, 0, sizeof(nop)); @@ -1098,33 +759,27 @@ test_ncr_hash(int cfd) if (hash_vectors[i].key != NULL) nop.init.key = key; nop.init.op = hash_vectors[i].op; - nop.op.data.sign.text = dd; - nop.op.data.sign.output = dd2; + nop.op.data.udata.input = (void*)hash_vectors[i].plaintext; + nop.op.data.udata.input_size = hash_vectors[i].plaintext_size; + nop.op.data.udata.output = data; + nop.op.data.udata.output_size = sizeof(data); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } + + data_size = nop.op.data.udata.output_size; - /* verify */ - memset(&kdata, 0, sizeof(kdata)); - kdata.desc = dd2; - kdata.data = data; - kdata.data_size = sizeof(data); - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - if (kdata.data_size != hash_vectors[i].output_size || - memcmp(kdata.data, hash_vectors[i].output, hash_vectors[i].output_size) != 0) { + if (data_size != hash_vectors[i].output_size || + memcmp(data, hash_vectors[i].output, hash_vectors[i].output_size) != 0) { fprintf(stderr, "HASH test vector %d failed!\n", i); - fprintf(stderr, "Output[%d]: ", (int)kdata.data_size); - for(j=0;j<kdata.data_size;j++) + fprintf(stderr, "Output[%d]: ", (int)data_size); + for(j=0;j<data_size;j++) fprintf(stderr, "%.2x:", (int)data[j]); fprintf(stderr, "\n"); @@ -1142,37 +797,132 @@ test_ncr_hash(int cfd) } - -int -main() +static int +test_ncr_hash_key(int cfd) { - int fd = -1; + ncr_key_t key; + struct ncr_key_data_st keydata; + uint8_t data[HASH_DATA_SIZE]; + int j, data_size; + struct ncr_session_op_st op; + struct ncr_session_st op_init; + const uint8_t *output = (void*)"\xe2\xd7\x2c\x2e\x14\xad\x97\xc8\xd2\xdb\xce\xd8\xb3\x52\x9f\x1c\xb3\x2c\x5c\xec"; - /* Open the crypto device */ - fd = open("/dev/crypto", O_RDWR, 0); - if (fd < 0) { - perror("open(/dev/crypto)"); + /* convert it to key */ + if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { + perror("ioctl(NCRIO_KEY_INIT)"); + return 1; + } + + keydata.key_id[0] = 'a'; + keydata.key_id[2] = 'b'; + keydata.key_id_size = 2; + keydata.type = NCR_KEY_TYPE_SECRET; + keydata.algorithm = NCR_ALG_AES_CBC; + keydata.flags = NCR_KEY_FLAG_EXPORTABLE; + + fprintf(stdout, "Tests on Hashes of Keys\n"); + + fprintf(stdout, "\t%s:\n", hash_vectors[0].name); + /* import key */ + keydata.key = key; + keydata.idata = (void*)hash_vectors[0].plaintext; + keydata.idata_size = hash_vectors[0].plaintext_size; + if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - /* Run the test itself */ - if (test_ncr_data(fd)) + /* encrypt */ + memset(&op_init, 0, sizeof(op_init)); + op_init.algorithm = hash_vectors[0].algorithm; + op_init.op = hash_vectors[0].op; + + if (ioctl(cfd, NCRIO_SESSION_INIT, &op_init)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_SESSION_INIT)"); return 1; + } - /* Close the original descriptor */ - if (close(fd)) { - perror("close(fd)"); + memset(&op, 0, sizeof(op)); + op.ses = op_init.ses; + op.data.udata.input = (void*)hash_vectors[0].plaintext; + op.data.udata.input_size = hash_vectors[0].plaintext_size; + op.data.udata.output = NULL; + op.data.udata.output_size = 0; + op.type = NCR_DIRECT_DATA; + + if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_SESSION_UPDATE)"); + return 1; + } + + memset(&op, 0, sizeof(op)); + op.ses = op_init.ses; + op.data.kdata.input = key; + op.data.kdata.output = NULL; + op.data.kdata.output_size = 0; + op.type = NCR_KEY_DATA; + + if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_SESSION_UPDATE)"); + return 1; + } + + op.data.udata.input = NULL; + op.data.udata.input_size = 0; + op.data.udata.output = data; + op.data.udata.output_size = sizeof(data); + op.type = NCR_DIRECT_DATA; + + if (ioctl(cfd, NCRIO_SESSION_FINAL, &op)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_SESSION_FINAL)"); return 1; + } + + data_size = op.data.udata.output_size; + + + if (data_size != hash_vectors[0].output_size || + memcmp(data, output, hash_vectors[0].output_size) != 0) { + fprintf(stderr, "HASH test vector %d failed!\n", 0); + + fprintf(stderr, "Output[%d]: ", (int)data_size); + for(j=0;j<data_size;j++) + fprintf(stderr, "%.2x:", (int)data[j]); + fprintf(stderr, "\n"); + + fprintf(stderr, "Expected[%d]: ", hash_vectors[0].output_size); + for(j=0;j<hash_vectors[0].output_size;j++) + fprintf(stderr, "%.2x:", (int)output[j]); + fprintf(stderr, "\n"); + return 1; } - /* actually test if the initial close - * will really delete all used lists */ + fprintf(stdout, "\n"); + + return 0; + +} + + +int +main() +{ + int fd = -1; + + /* Open the crypto device */ fd = open("/dev/crypto", O_RDWR, 0); if (fd < 0) { perror("open(/dev/crypto)"); return 1; } + if (test_ncr_key(fd)) return 1; @@ -1182,6 +932,9 @@ main() if (test_ncr_hash(fd)) return 1; + if (test_ncr_hash_key(fd)) + return 1; + if (test_ncr_wrap_key(fd)) return 1; diff --git a/examples/pk.c b/examples/pk.c index fef695c..1aa4c5a 100644 --- a/examples/pk.c +++ b/examples/pk.c @@ -297,68 +297,20 @@ int pubkey_info(void* data, int data_size, int verbose) return 0; } -static int data_get(int cfd, ncr_data_t dd, void* data, size_t data_size) -{ -struct ncr_data_st kdata; - - memset(&kdata, 0, sizeof(kdata)); - kdata.desc = dd; - kdata.data = data; - kdata.data_size = data_size; - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return -1; - } - - return 0; -} - #define RSA_ENCRYPT_SIZE 32 static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oaep) { - struct ncr_data_init_st dinit; - ncr_data_t datad; - ncr_data_t encd; struct ncr_session_once_op_st nop; uint8_t data[DATA_SIZE]; uint8_t vdata[RSA_ENCRYPT_SIZE]; - int ret; + int enc_size; fprintf(stdout, "Tests on RSA (%s) key encryption:", (oaep!=0)?"OAEP":"PKCS V1.5"); fflush(stdout); memset(data, 0x3, sizeof(data)); - memset(vdata, 0x0, sizeof(vdata)); - - /* data to sign */ - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = data; - dinit.initial_data_size = RSA_ENCRYPT_SIZE; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - datad = dinit.desc; - - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - encd = dinit.desc; + memcpy(vdata, data, sizeof(vdata)); /* do encryption */ memset(&nop, 0, sizeof(nop)); @@ -371,14 +323,19 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae nop.init.params.params.rsa.type = RSA_PKCS1_V1_5; } nop.init.op = NCR_OP_ENCRYPT; - nop.op.data.cipher.plaintext = datad; - nop.op.data.cipher.ciphertext = encd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = RSA_ENCRYPT_SIZE; + nop.op.data.udata.output = data; + nop.op.data.udata.output_size = sizeof(data); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } + + enc_size = nop.op.data.udata.output_size; /* decrypt data */ memset(&nop, 0, sizeof(nop)); @@ -391,8 +348,12 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae } else { nop.init.params.params.rsa.type = RSA_PKCS1_V1_5; } - nop.op.data.cipher.plaintext = encd; - nop.op.data.cipher.ciphertext = encd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = enc_size; + nop.op.data.udata.output = data; + nop.op.data.udata.output_size = sizeof(data); + nop.op.type = NCR_DIRECT_DATA; + if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -400,12 +361,6 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae return 1; } - ret = data_get(cfd, encd, vdata, sizeof(vdata)); - if (ret < 0) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - return 1; - } - if (memcmp(vdata, data, sizeof(vdata)) != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "Decrypted data do not match!\n"); @@ -418,46 +373,20 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae } +#define DATA_TO_SIGN 52 + static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int pss) { - struct ncr_data_init_st dinit; - ncr_data_t datad; - ncr_data_t signd; struct ncr_session_once_op_st nop; uint8_t data[DATA_SIZE]; + uint8_t sig[DATA_SIZE]; + int sig_size; fprintf(stdout, "Tests on RSA (%s) key signature:", (pss!=0)?"PSS":"PKCS V1.5"); fflush(stdout); memset(data, 0x3, sizeof(data)); - /* data to sign */ - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = data; - dinit.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - datad = dinit.desc; - - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - signd = dinit.desc; - /* sign datad */ memset(&nop, 0, sizeof(nop)); nop.init.algorithm = NCR_ALG_RSA; @@ -466,14 +395,19 @@ static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int nop.init.params.params.rsa.sign_hash = NCR_ALG_SHA1; nop.init.op = NCR_OP_SIGN; - nop.op.data.sign.text = datad; - nop.op.data.sign.output = signd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = DATA_TO_SIGN; + nop.op.data.udata.output = sig; + nop.op.data.udata.output_size = sizeof(sig); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } + + sig_size = nop.op.data.udata.output_size; /* verify signature */ memset(&nop, 0, sizeof(nop)); @@ -482,9 +416,14 @@ static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int nop.init.params.params.rsa.type = (pss!=0)?RSA_PKCS1_PSS:RSA_PKCS1_V1_5; nop.init.params.params.rsa.sign_hash = NCR_ALG_SHA1; + memset(data, 0x3, sizeof(data)); + nop.init.op = NCR_OP_VERIFY; - nop.op.data.verify.text = datad; - nop.op.data.verify.signature = signd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = DATA_TO_SIGN; + nop.op.data.udata.output = sig; + nop.op.data.udata.output_size = sig_size; + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -492,7 +431,12 @@ static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int return 1; } - fprintf(stdout, " Success\n"); + if (nop.op.err == NCR_SUCCESS) + fprintf(stdout, " Success\n"); + else { + fprintf(stdout, " Verification Failed!\n"); + return 1; + } return 0; @@ -500,44 +444,16 @@ static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey) { - struct ncr_data_init_st dinit; - ncr_data_t datad; - ncr_data_t signd; struct ncr_session_once_op_st nop; uint8_t data[DATA_SIZE]; + uint8_t sig[DATA_SIZE]; + int sig_size; fprintf(stdout, "Tests on DSA key signature:"); fflush(stdout); memset(data, 0x3, sizeof(data)); - /* data to sign */ - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = data; - dinit.initial_data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - datad = dinit.desc; - - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - - signd = dinit.desc; - /* sign datad */ memset(&nop, 0, sizeof(nop)); nop.init.algorithm = NCR_ALG_DSA; @@ -545,14 +461,19 @@ static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey) nop.init.params.params.dsa.sign_hash = NCR_ALG_SHA1; nop.init.op = NCR_OP_SIGN; - nop.op.data.sign.text = datad; - nop.op.data.sign.output = signd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = DATA_TO_SIGN; + nop.op.data.udata.output = sig; + nop.op.data.udata.output_size = sizeof(sig); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } + + sig_size = nop.op.data.udata.output_size; /* verify signature */ memset(&nop, 0, sizeof(nop)); @@ -561,8 +482,11 @@ static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey) nop.init.params.params.dsa.sign_hash = NCR_ALG_SHA1; nop.init.op = NCR_OP_VERIFY; - nop.op.data.verify.text = datad; - nop.op.data.verify.signature = signd; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = DATA_TO_SIGN; + nop.op.data.udata.output = sig; + nop.op.data.udata.output_size = sizeof(sig); + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -570,7 +494,12 @@ static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey) return 1; } - fprintf(stdout, " Success\n"); + if (nop.op.err == NCR_SUCCESS) + fprintf(stdout, " Success\n"); + else { + fprintf(stdout, " Verification Failed!\n"); + return 1; + } return 0; @@ -580,12 +509,11 @@ static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey) static int test_ncr_rsa(int cfd) { int ret; - struct ncr_data_init_st dinit; struct ncr_key_generate_st kgen; ncr_key_t pubkey, privkey; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; uint8_t data[DATA_SIZE]; + int data_size; fprintf(stdout, "Tests on RSA key generation:"); fflush(stdout); @@ -617,41 +545,21 @@ static int test_ncr_rsa(int cfd) } /* export the private key */ - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = NULL; - dinit.initial_data_size = 0; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - + memset(data, 0, sizeof(data)); memset(&keydata, 0, sizeof(keydata)); keydata.key = privkey; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_EXPORT)"); return 1; } + + data_size = keydata.idata_size; - /* now read data */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - ret = privkey_info(kdata.data, kdata.data_size, 0); + ret = privkey_info(data, data_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; @@ -659,30 +567,21 @@ static int test_ncr_rsa(int cfd) /* export the public key */ + memset(data, 0, sizeof(data)); memset(&keydata, 0, sizeof(keydata)); keydata.key = pubkey; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - - /* now read data */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - ret = pubkey_info(kdata.data, kdata.data_size, 0); + data_size = keydata.idata_size; + + ret = pubkey_info(data, data_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; @@ -690,13 +589,13 @@ static int test_ncr_rsa(int cfd) fprintf(stdout, " Success\n"); - ret = rsa_key_sign_verify(cfd, privkey, pubkey, 0); + ret = rsa_key_sign_verify(cfd, privkey, pubkey, 1); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } - ret = rsa_key_sign_verify(cfd, privkey, pubkey, 1); + ret = rsa_key_sign_verify(cfd, privkey, pubkey, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; @@ -721,12 +620,11 @@ static int test_ncr_rsa(int cfd) static int test_ncr_dsa(int cfd) { int ret; - struct ncr_data_init_st dinit; struct ncr_key_generate_st kgen; ncr_key_t pubkey, privkey; struct ncr_key_data_st keydata; - struct ncr_data_st kdata; uint8_t data[DATA_SIZE]; + int data_size; fprintf(stdout, "Tests on DSA key generation:"); fflush(stdout); @@ -758,42 +656,20 @@ static int test_ncr_dsa(int cfd) return 1; } - /* export the private key */ - dinit.max_object_size = DATA_SIZE; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = NULL; - dinit.initial_data_size = 0; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - memset(&keydata, 0, sizeof(keydata)); + memset(data, 0, sizeof(data)); keydata.key = privkey; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_EXPORT)"); return 1; } + data_size = keydata.idata_size; - /* now read data */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - - ret = privkey_info(kdata.data, kdata.data_size, 0); + ret = privkey_info(data, data_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; @@ -801,30 +677,21 @@ static int test_ncr_dsa(int cfd) /* export the public key */ + memset(data, 0, sizeof(data)); memset(&keydata, 0, sizeof(keydata)); keydata.key = pubkey; - keydata.data = dinit.desc; + keydata.idata = data; + keydata.idata_size = sizeof(data); if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } - - /* now read data */ - memset(data, 0, sizeof(data)); - - kdata.desc = dinit.desc; - kdata.data = data; - kdata.data_size = sizeof(data); - - if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_GET)"); - return 1; - } - ret = pubkey_info(kdata.data, kdata.data_size, 0); + data_size = keydata.idata_size; + + ret = pubkey_info(data, data_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; diff --git a/examples/speed.c b/examples/speed.c index 1c76eb6..5898aaa 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -116,7 +116,8 @@ int encrypt_data(struct session_op *sess, int fdc, int chunksize) return 0; } -int encrypt_data_ncr(int cfd, int algo, int chunksize) + +int encrypt_data_ncr_direct(int cfd, int algo, int chunksize) { char *buffer, iv[32]; static int val = 23; @@ -126,10 +127,7 @@ int encrypt_data_ncr(int cfd, int algo, int chunksize) char metric[16]; ncr_key_t key; struct ncr_key_generate_st kgen; - struct ncr_data_init_st dinit; - struct ncr_data_st kdata; struct ncr_session_once_op_st nop; - ncr_data_t dd; if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -152,19 +150,6 @@ int encrypt_data_ncr(int cfd, int algo, int chunksize) buffer = malloc(chunksize); memset(iv, 0x23, 32); - memset(&dinit, 0, sizeof(dinit)); - dinit.max_object_size = chunksize; - dinit.flags = NCR_DATA_FLAG_EXPORTABLE; - dinit.initial_data = buffer; - dinit.initial_data_size = chunksize; - - if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - dd = dinit.desc; - printf("\tEncrypting in chunks of %d bytes: ", chunksize); fflush(stdout); @@ -175,22 +160,15 @@ int encrypt_data_ncr(int cfd, int algo, int chunksize) gettimeofday(&start, NULL); do { - kdata.data = buffer; - kdata.data_size = chunksize; - kdata.desc = dd; - - if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - memset(&nop, 0, sizeof(nop)); nop.init.algorithm = algo; nop.init.key = key; nop.init.op = NCR_OP_ENCRYPT; - nop.op.data.cipher.plaintext = dd; - nop.op.data.cipher.ciphertext = dd; + nop.op.data.udata.input = buffer; + nop.op.data.udata.input_size = chunksize; + nop.op.data.udata.output = buffer; + nop.op.data.udata.output_size = chunksize; + nop.op.type = NCR_DIRECT_DATA; if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -202,12 +180,6 @@ int encrypt_data_ncr(int cfd, int algo, int chunksize) } while(must_finish==0); gettimeofday(&end, NULL); - if (ioctl(cfd, NCRIO_DATA_DEINIT, &dd)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_DATA_INIT)"); - return 1; - } - secs = udifftimeval(start, end)/ 1000000.0; value2human(total, secs, &ddata, &dspeed, metric); @@ -249,6 +221,13 @@ int main(void) 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)) + break; + } + + fprintf(stderr, "\nTesting AES-128-CBC cipher: \n"); memset(&sess, 0, sizeof(sess)); sess.cipher = CRYPTO_AES_CBC; @@ -265,15 +244,9 @@ int main(void) break; } - fprintf(stderr, "\nTesting NCR with NULL cipher: \n"); - for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data_ncr(fdc, NCR_ALG_NULL, i)) - break; - } - - fprintf(stderr, "\nTesting NCR with AES-128-CBC cipher: \n"); + fprintf(stderr, "\nTesting NCR-DIRECT with AES-128-CBC cipher: \n"); for (i = 256; i <= (64 * 1024); i *= 2) { - if (encrypt_data_ncr(fdc, NCR_ALG_AES_CBC, i)) + if (encrypt_data_ncr_direct(fdc, NCR_ALG_AES_CBC, i)) break; } diff --git a/libtomcrypt/hashes/hash_get_oid.c b/libtomcrypt/hashes/hash_get_oid.c index c6469ba..39f4372 100644 --- a/libtomcrypt/hashes/hash_get_oid.c +++ b/libtomcrypt/hashes/hash_get_oid.c @@ -8,7 +8,7 @@ * */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /* Returns the OID of the hash. diff --git a/libtomcrypt/hashes/hash_memory.c b/libtomcrypt/hashes/hash_memory.c index 5ba3bc6..a416de9 100644 --- a/libtomcrypt/hashes/hash_memory.c +++ b/libtomcrypt/hashes/hash_memory.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> #include <cryptodev_int.h> /** diff --git a/libtomcrypt/hashes/hash_memory_multi.c b/libtomcrypt/hashes/hash_memory_multi.c index d772492..a914916 100644 --- a/libtomcrypt/hashes/hash_memory_multi.c +++ b/libtomcrypt/hashes/hash_memory_multi.c @@ -10,7 +10,7 @@ */ #include "tomcrypt.h" #include <stdarg.h> -#include <ncr_int.h> +#include <ncr-int.h> #include <cryptodev_int.h> /** diff --git a/libtomcrypt/pk/pkcs1/pkcs_1_mgf1.c b/libtomcrypt/pk/pkcs1/pkcs_1_mgf1.c index b09dd11..58052eb 100644 --- a/libtomcrypt/pk/pkcs1/pkcs_1_mgf1.c +++ b/libtomcrypt/pk/pkcs1/pkcs_1_mgf1.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file pkcs_1_mgf1.c diff --git a/libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.c b/libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.c index 60f76a0..5214a29 100644 --- a/libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file pkcs_1_oaep_decode.c diff --git a/libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.c b/libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.c index c56e3b1..ef644f9 100644 --- a/libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file pkcs_1_oaep_encode.c diff --git a/libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c b/libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c index 293d84f..b9ade4b 100644 --- a/libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c +++ b/libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file pkcs_1_pss_decode.c @@ -130,8 +130,10 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, goto LBL_ERR; } + zeromem(mask, 8); + /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - err = hash_memory_multi(hash_algo, mask, &hLen, mask, 8, msghash, (unsigned long)msghashlen, DB+x, (unsigned long)saltlen, NULL, 0); + err = hash_memory_multi(hash_algo, mask, &hLen, mask, (unsigned long)8, msghash, (unsigned long)msghashlen, DB+x, (unsigned long)saltlen, NULL, 0); if (err != CRYPT_OK) { goto LBL_ERR; } diff --git a/libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c b/libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c index d747b49..f8f763b 100644 --- a/libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c +++ b/libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file pkcs_1_pss_encode.c @@ -81,9 +81,11 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, if (saltlen > 0) { get_random_bytes(salt, saltlen); } + + zeromem(DB, 8); /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ - err = hash_memory_multi(hash_algo, hash, &hLen, DB, 8, msghash, (unsigned long)msghashlen, salt, (unsigned long)saltlen, NULL, 0); + err = hash_memory_multi(hash_algo, hash, &hLen, DB, (unsigned long)8, msghash, (unsigned long)msghashlen, salt, (unsigned long)saltlen, NULL, 0); if (err != CRYPT_OK) { goto LBL_ERR; } diff --git a/libtomcrypt/pk/rsa/rsa_decrypt_key.c b/libtomcrypt/pk/rsa/rsa_decrypt_key.c index 989c935..a8f3ac4 100644 --- a/libtomcrypt/pk/rsa/rsa_decrypt_key.c +++ b/libtomcrypt/pk/rsa/rsa_decrypt_key.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include "ncr_int.h" +#include "ncr-int.h" /** @file rsa_decrypt_key.c diff --git a/libtomcrypt/pk/rsa/rsa_encrypt_key.c b/libtomcrypt/pk/rsa/rsa_encrypt_key.c index 4ce51a4..8d3f2db 100644 --- a/libtomcrypt/pk/rsa/rsa_encrypt_key.c +++ b/libtomcrypt/pk/rsa/rsa_encrypt_key.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include "ncr_int.h" +#include "ncr-int.h" /** @file rsa_encrypt_key.c diff --git a/libtomcrypt/pk/rsa/rsa_export.c b/libtomcrypt/pk/rsa/rsa_export.c index 33c222d..905bb6f 100644 --- a/libtomcrypt/pk/rsa/rsa_export.c +++ b/libtomcrypt/pk/rsa/rsa_export.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <ncr_int.h> +#include <ncr-int.h> /** @file rsa_export.c Export RSA LTC_PKCS keys, Tom St Denis diff --git a/libtomcrypt/pk/rsa/rsa_sign_hash.c b/libtomcrypt/pk/rsa/rsa_sign_hash.c index 5a32d33..f27789d 100644 --- a/libtomcrypt/pk/rsa/rsa_sign_hash.c +++ b/libtomcrypt/pk/rsa/rsa_sign_hash.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include "ncr_int.h" +#include "ncr-int.h" /** @file rsa_sign_hash.c diff --git a/libtomcrypt/pk/rsa/rsa_verify_hash.c b/libtomcrypt/pk/rsa/rsa_verify_hash.c index 20f852e..c8a113d 100644 --- a/libtomcrypt/pk/rsa/rsa_verify_hash.c +++ b/libtomcrypt/pk/rsa/rsa_verify_hash.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include "ncr_int.h" +#include "ncr-int.h" /** @file rsa_verify_hash.c diff --git a/ncr-data.c b/ncr-data.c deleted file mode 100644 index 21aabe4..0000000 --- a/ncr-data.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * New driver for /dev/crypto device (aka CryptoDev) - - * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org> - * - * This file is part of linux cryptodev. - * - * cryptodev is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * cryptodev is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/crypto.h> -#include <linux/mm.h> -#include <linux/highmem.h> -#include "cryptodev.h" -#include <asm/uaccess.h> -#include <asm/ioctl.h> -#include <linux/scatterlist.h> -#include "ncr.h" -#include "ncr_int.h" - -/* must be called with data semaphore down */ -static void _ncr_data_unlink_item(struct data_item_st *item) -{ - list_del(&item->list); - _ncr_data_item_put( item); /* decrement ref count */ -} - -void ncr_data_list_deinit(struct list_sem_st* lst) -{ - if(lst) { - struct data_item_st * item, *tmp; - - down(&lst->sem); - - list_for_each_entry_safe(item, tmp, &lst->list, list) { - _ncr_data_unlink_item(item); - } - up(&lst->sem); - - } -} - -/* must be called with data semaphore down - */ -static ncr_data_t _ncr_data_get_new_desc( struct list_sem_st* lst) -{ -struct data_item_st* item; -int mx = 1; - - list_for_each_entry(item, &lst->list, list) { - mx = max(mx, item->desc); - } - mx++; - - return mx; -} - -/* returns the data item corresponding to desc */ -struct data_item_st* ncr_data_item_get( struct list_sem_st* lst, ncr_data_t desc) -{ -struct data_item_st* item; - - down(&lst->sem); - list_for_each_entry(item, &lst->list, list) { - if (item->desc == desc) { - atomic_inc(&item->refcnt); - up(&lst->sem); - return item; - } - } - up(&lst->sem); - - err(); - return NULL; -} - -static void* data_alloc(size_t size) -{ - /* FIXME: enforce a maximum memory limit per process and per user */ - /* ncr_data_set() relies this function enforcing a reasonable upper - limit. */ - if (size > 64*1024) { - err(); - return NULL; - } - return kmalloc(size, GFP_KERNEL); -} - -void _ncr_data_item_put( struct data_item_st* item) -{ - if (atomic_dec_and_test(&item->refcnt)) { - ncr_limits_remove(item->uid, item->pid, LIMIT_TYPE_DATA); - kfree(item->data); - kfree(item); - } -} - -int ncr_data_init(struct list_sem_st* lst, void __user* arg) -{ - struct ncr_data_init_st init; - struct data_item_st* data; - int ret; - - ret = ncr_limits_add_and_check(current_euid(), task_pid_nr(current), LIMIT_TYPE_DATA); - if (ret < 0) { - err(); - return ret; - } - - if (unlikely(copy_from_user(&init, arg, sizeof(init)))) { - err(); - ret = -EFAULT; - goto err_limits; - } - - data = kmalloc(sizeof(*data), GFP_KERNEL); - if (data == NULL) { - err(); - ret = -ENOMEM; - goto err_limits; - } - - memset(data, 0, sizeof(*data)); - - data->flags = init.flags; - data->uid = current_euid(); - data->pid = task_pid_nr(current); - - atomic_set(&data->refcnt, 1); - - data->data = data_alloc(init.max_object_size); - if (data->data == NULL) { - err(); - ret = -ENOMEM; - goto err_data; - } - data->max_data_size = init.max_object_size; - - if (init.initial_data != NULL) { - if (unlikely(copy_from_user(data->data, init.initial_data, - init.initial_data_size))) { - err(); - _ncr_data_item_put(data); - return -EFAULT; - } - data->data_size = init.initial_data_size; - } - - down(&lst->sem); - - data->desc = _ncr_data_get_new_desc(lst); - - list_add(&data->list, &lst->list); - - up(&lst->sem); - - init.desc = data->desc; - ret = copy_to_user(arg, &init, sizeof(init)); - if (unlikely(ret)) { - down(&lst->sem); - _ncr_data_unlink_item(data); - up(&lst->sem); - return -EFAULT; - } - return ret; - - err_data: - kfree(data); - err_limits: - ncr_limits_remove(current_euid(), task_pid_nr(current), - LIMIT_TYPE_DATA); - return ret; -} - - -int ncr_data_deinit(struct list_sem_st* lst, void __user* arg) -{ - ncr_data_t desc; - struct data_item_st * item, *tmp; - - if (unlikely(copy_from_user(&desc, arg, sizeof(desc)))) { - err(); - return -EFAULT; - } - down(&lst->sem); - - list_for_each_entry_safe(item, tmp, &lst->list, list) { - if(item->desc == desc) { - _ncr_data_unlink_item(item); - break; - } - } - - up(&lst->sem); - - return 0; -} - -int ncr_data_get(struct list_sem_st* lst, void __user* arg) -{ - struct ncr_data_st get; - struct data_item_st * data; - size_t len; - int ret; - - if (unlikely(copy_from_user(&get, arg, sizeof(get)))) { - err(); - return -EFAULT; - } - - data = ncr_data_item_get( lst, get.desc); - - if (data == NULL) { - err(); - return -EINVAL; - } - - if (!(data->flags & NCR_DATA_FLAG_EXPORTABLE)) { - err(); - ret = -EPERM; - goto cleanup; - } - - len = min(get.data_size, data->data_size); - - /* update length */ - get.data_size = len; - - ret = copy_to_user(arg, &get, sizeof(get)); - if (unlikely(ret)) { - err(); - ret = -EFAULT; - } - - if (ret == 0 && len > 0) { - ret = copy_to_user(get.data, data->data, len); - if (unlikely(ret)) { - err(); - ret = -EFAULT; - } - } - -cleanup: - _ncr_data_item_put( data); - - return ret; -} - -int ncr_data_set(struct list_sem_st* lst, void __user* arg) -{ - struct ncr_data_st get; - struct data_item_st * data; - int ret; - - if (unlikely(copy_from_user(&get, arg, sizeof(get)))) { - err(); - return -EFAULT; - } - - data = ncr_data_item_get( lst, get.desc); - - if (data == NULL) { - err(); - return -EINVAL; - } - - if ((get.data_size > data->max_data_size) || - (get.data == NULL && get.data_size != 0)) { - err(); - ret = -EINVAL; - goto cleanup; - } - - if (get.data != NULL) { - if (unlikely(copy_from_user(data->data, get.data, - get.data_size))) { - err(); - ret = -EFAULT; - goto cleanup; - } - } - data->data_size = get.data_size; - - ret = 0; - -cleanup: - _ncr_data_item_put( data); - - return ret; -} @@ -19,6 +19,7 @@ struct algo_properties_st { unsigned can_digest:1; unsigned can_encrypt:1; unsigned is_symmetric:1; + unsigned is_pk:1; int digest_size; /* NCR_KEY_TYPE_SECRET if for a secret key algorithm or MAC, * NCR_KEY_TYPE_PUBLIC for a public key algorithm. @@ -40,32 +41,20 @@ struct session_item_st { struct ncr_pk_ctx pk; struct hash_data hash; + struct scatterlist *sg; + struct page **pages; + unsigned array_size; + unsigned available_pages; + struct semaphore mem_mutex; /* down when the + * values above are changed. + */ + struct key_item_st* key; atomic_t refcnt; ncr_session_t desc; }; -struct data_item_st { - struct list_head list; - /* This object is not protected from concurrent access. - * I see no reason to allow concurrent writes (reads are - * not an issue). - */ - - uint8_t* data; - size_t data_size; - size_t max_data_size; - unsigned int flags; - atomic_t refcnt; - - /* owner. The one charged with this */ - uid_t uid; - pid_t pid; - - ncr_data_t desc; -}; - struct key_item_st { struct list_head list; /* This object is also not protected from concurrent access. @@ -119,20 +108,10 @@ 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_data_set(struct list_sem_st*, void __user* arg); -int ncr_data_get(struct list_sem_st*, void __user* arg); -int ncr_data_deinit(struct list_sem_st*, void __user* arg); -int ncr_data_init(struct list_sem_st*, void __user* arg); -void ncr_data_list_deinit(struct list_sem_st*); -struct data_item_st* ncr_data_item_get( struct list_sem_st* lst, ncr_data_t desc); -void _ncr_data_item_put( struct data_item_st* item); - int ncr_key_init(struct list_sem_st*, void __user* arg); int ncr_key_deinit(struct list_sem_st*, void __user* arg); -int ncr_key_export(struct list_sem_st* data_lst, - struct list_sem_st* key_lst,void __user* arg); -int ncr_key_import(struct list_sem_st* data_lst, - struct list_sem_st* key_lst,void __user* arg); +int ncr_key_export(struct list_sem_st* key_lst,void __user* arg); +int ncr_key_import(struct list_sem_st* key_lst,void __user* arg); void ncr_key_list_deinit(struct list_sem_st* lst); int ncr_key_generate(struct list_sem_st* data_lst, void __user* arg); int ncr_key_info(struct list_sem_st*, void __user* arg); @@ -150,7 +129,6 @@ void _ncr_key_item_put( struct key_item_st* item); typedef enum { LIMIT_TYPE_KEY, - LIMIT_TYPE_DATA } limits_type_t; void ncr_limits_remove(uid_t uid, pid_t pid, limits_type_t type); @@ -158,10 +136,10 @@ int ncr_limits_add_and_check(uid_t uid, pid_t pid, limits_type_t type); void ncr_limits_init(void); void ncr_limits_deinit(void); -int ncr_key_wrap(struct list_sem_st* keys, struct list_sem_st* data, void __user* arg); -int ncr_key_unwrap(struct list_sem_st*, struct list_sem_st* data, void __user* arg); -int ncr_key_storage_wrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg); -int ncr_key_storage_unwrap(struct list_sem_st*, struct list_sem_st* data, void __user* arg); +int ncr_key_wrap(struct list_sem_st* keys, void __user* arg); +int ncr_key_unwrap(struct list_sem_st*, void __user* arg); +int ncr_key_storage_wrap(struct list_sem_st* key_lst, void __user* arg); +int ncr_key_storage_unwrap(struct list_sem_st*, void __user* arg); /* sessions */ struct session_item_st* ncr_session_new(struct list_sem_st* lst); @@ -185,25 +163,6 @@ int key_to_storage_data( uint8_t** data, size_t * data_size, const struct key_it /* misc helper macros */ -inline static unsigned int key_flags_to_data(unsigned int key_flags) -{ - unsigned int flags = 0; - - if (key_flags & NCR_KEY_FLAG_EXPORTABLE) - flags |= NCR_DATA_FLAG_EXPORTABLE; - - return flags; -} - -inline static unsigned int data_flags_to_key(unsigned int data_flags) -{ - unsigned int flags = 0; - - if (data_flags & NCR_DATA_FLAG_EXPORTABLE) - flags |= NCR_KEY_FLAG_EXPORTABLE; - - return flags; -} const struct algo_properties_st *_ncr_algo_to_properties(ncr_algorithm_t algo); const struct algo_properties_st *ncr_key_params_get_sign_hash(const struct algo_properties_st *algo, struct ncr_key_params_st * params); diff --git a/ncr-key-storage.c b/ncr-key-storage.c index 90d3f74..a1788dc 100644 --- a/ncr-key-storage.c +++ b/ncr-key-storage.c @@ -25,7 +25,7 @@ #include <asm/ioctl.h> #include <linux/scatterlist.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" #include "cryptodev_int.h" struct packed_key { diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index 939c136..2edcefb 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -27,7 +27,7 @@ #include <asm/ioctl.h> #include <linux/scatterlist.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" #include "cryptodev_int.h" typedef uint8_t val64_t[8]; @@ -44,13 +44,13 @@ static void val64_xor( val64_t val, uint32_t x) } static int rfc3394_wrap(val64_t R[], unsigned int n, struct cipher_data* ctx, - struct data_item_st* output, const uint8_t iv[8]) + uint8_t* output, size_t *output_size, const uint8_t iv[8]) { val64_t A; uint8_t aes_block[16]; int i,j; - if (output->max_data_size < (n+1)*8) { + if (*output_size < (n+1)*8) { err(); return -EINVAL; } @@ -72,15 +72,15 @@ int i,j; memcpy(R[n-1], &aes_block[8], 8); /* R[n-1] = LSB64(AES(A^{t-1}|R_{1}^{t-1})) */ } - memcpy(output->data, A, sizeof(A)); + memcpy(output, A, sizeof(A)); for (j=0;j<n;j++) - memcpy(&output->data[(j+1)*8], R[j], 8); - output->data_size = (n+1)*8; + memcpy(&output[(j+1)*8], R[j], 8); + *output_size = (n+1)*8; return 0; } -static int rfc3394_unwrap(uint8_t *wrapped_key, val64_t R[], unsigned int n, val64_t A, struct cipher_data *ctx) +static int rfc3394_unwrap(const uint8_t *wrapped_key, val64_t R[], unsigned int n, val64_t A, struct cipher_data *ctx) { int i, j; uint8_t aes_block[16]; @@ -111,7 +111,7 @@ static int rfc3394_unwrap(uint8_t *wrapped_key, val64_t R[], unsigned int n, val #define RFC5649_IV "\xA6\x59\x59\xA6" static int _wrap_aes_rfc5649(void* kdata, size_t kdata_size, struct key_item_st* kek, - struct data_item_st* output, const void* _iv, size_t iv_size) + void* output, size_t* output_size, const void* _iv, size_t iv_size) { size_t n; int i, ret; @@ -157,7 +157,7 @@ uint8_t iv[8]; for (;i<n*8;i++) { R[i/8][i%8] = 0; } - ret = rfc3394_wrap( R, n, &ctx, output, iv); + ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); kfree(R); if (ret < 0) { err(); @@ -174,10 +174,9 @@ cleanup: } static int _unwrap_aes_rfc5649(void* kdata, size_t *kdata_size, struct key_item_st* kek, - struct data_item_st *wrapped, const void* _iv, size_t iv_size) + const void *wrapped_key, size_t wrapped_key_size, const void* _iv, size_t iv_size) { -size_t wrapped_key_size, n; -uint8_t *wrapped_key; +size_t n; int i, ret; struct cipher_data ctx; uint8_t iv[4]; @@ -196,9 +195,6 @@ size_t size; return ret; } - wrapped_key = wrapped->data; - wrapped_key_size = wrapped->data_size; - if (wrapped_key_size % 8 != 0) { err(); ret = -EINVAL; @@ -263,7 +259,7 @@ cleanup: static int wrap_aes_rfc5649(struct key_item_st* tobewrapped, struct key_item_st *kek, - struct data_item_st* output, const void* iv, size_t iv_size) + void* output, size_t* output_size, const void* iv, size_t iv_size) { if (tobewrapped->type != NCR_KEY_TYPE_SECRET) { err(); @@ -271,23 +267,24 @@ static int wrap_aes_rfc5649(struct key_item_st* tobewrapped, struct key_item_st } return _wrap_aes_rfc5649(tobewrapped->key.secret.data, tobewrapped->key.secret.size, - kek, output, iv, iv_size); + kek, output, output_size, iv, iv_size); } static int unwrap_aes_rfc5649(struct key_item_st* output, struct key_item_st *kek, - struct data_item_st* wrapped, const void* iv, size_t iv_size) + void* wrapped, size_t wrapped_size, const void* iv, size_t iv_size) { output->type = NCR_KEY_TYPE_SECRET; - return _unwrap_aes_rfc5649(output->key.secret.data, &output->key.secret.size, kek, wrapped, iv, iv_size); + return _unwrap_aes_rfc5649(output->key.secret.data, &output->key.secret.size, kek, + wrapped, wrapped_size, iv, iv_size); } /* Wraps using the RFC3394 way. */ static int wrap_aes(struct key_item_st* tobewrapped, struct key_item_st *kek, - struct data_item_st* output, const void* iv, size_t iv_size) + void* output, size_t *output_size, const void* iv, size_t iv_size) { size_t key_size, n; uint8_t *raw_key; @@ -330,7 +327,7 @@ struct cipher_data ctx; memcpy(R[i], &raw_key[i*8], 8); } - ret = rfc3394_wrap( R, n, &ctx, output, iv); + ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); if (ret < 0) { err(); goto cleanup; @@ -359,10 +356,9 @@ void print_val64(char* str, val64_t val) #endif static int unwrap_aes(struct key_item_st* output, struct key_item_st *kek, - struct data_item_st* wrapped, const void* iv, size_t iv_size) + void* wrapped_key, size_t wrapped_key_size, const void* iv, size_t iv_size) { -size_t wrapped_key_size, n; -uint8_t *wrapped_key; +size_t n; val64_t A; int i, ret; struct cipher_data ctx; @@ -380,9 +376,6 @@ struct cipher_data ctx; output->type = NCR_KEY_TYPE_SECRET; - wrapped_key = wrapped->data; - wrapped_key_size = wrapped->data_size; - if (wrapped_key_size % 8 != 0) { err(); ret = -EINVAL; @@ -431,12 +424,13 @@ cleanup: return ret; } -int ncr_key_wrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) +int ncr_key_wrap(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_wrap_st wrap; struct key_item_st* wkey = NULL; struct key_item_st* key = NULL; -struct data_item_st * data = NULL; +void* data = NULL; +size_t data_size; int ret; if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) { @@ -462,31 +456,50 @@ int ret; goto fail; } - data = ncr_data_item_get(data_lst, wrap.data); + data_size = wrap.io_size; + data = kmalloc(data_size, GFP_KERNEL); if (data == NULL) { err(); - ret = -EINVAL; + ret = -ENOMEM; goto fail; } - - data->flags = key_flags_to_data(wkey->flags) | NCR_DATA_FLAG_EXPORTABLE; - + switch(wrap.algorithm) { case NCR_WALG_AES_RFC3394: - ret = wrap_aes(wkey, key, data, wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); + ret = wrap_aes(wkey, key, data, &data_size, + wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); break; case NCR_WALG_AES_RFC5649: - ret = wrap_aes_rfc5649(wkey, key, data, wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); + ret = wrap_aes_rfc5649(wkey, key, data, &data_size, + wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); break; default: err(); ret = -EINVAL; } + + if (ret < 0) { + err(); + goto fail; + } + + ret = copy_to_user(wrap.io, data, data_size); + if (unlikely(ret)) { + ret = -EFAULT; + goto fail; + } + + wrap.io_size = data_size; + + ret = copy_to_user(arg, &wrap, sizeof(wrap)); + if (unlikely(ret)) { + ret = -EFAULT; + } fail: if (wkey != NULL) _ncr_key_item_put(wkey); if (key != NULL) _ncr_key_item_put(key); - if (data != NULL) _ncr_data_item_put(data); + kfree(data); return ret; } @@ -494,12 +507,13 @@ fail: /* Unwraps keys. All keys unwrapped are not accessible by * userspace. */ -int ncr_key_unwrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) +int ncr_key_unwrap(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_wrap_st wrap; struct key_item_st* wkey = NULL; struct key_item_st* key = NULL; -struct data_item_st * data = NULL; +void* data = NULL; +size_t data_size; int ret; if (unlikely(copy_from_user(&wrap, arg, sizeof(wrap)))) { @@ -519,40 +533,48 @@ int ret; goto fail; } - data = ncr_data_item_get(data_lst, wrap.data); + data_size = wrap.io_size; + data = kmalloc(data_size, GFP_KERNEL); if (data == NULL) { err(); - ret = -EINVAL; + ret = -ENOMEM; goto fail; } - wkey->flags = data_flags_to_key(data->flags) | NCR_KEY_FLAG_WRAPPABLE; + if (unlikely(copy_from_user(data, wrap.io, data_size))) { + err(); + ret = -EFAULT; + goto fail; + } switch(wrap.algorithm) { case NCR_WALG_AES_RFC3394: - ret = unwrap_aes(wkey, key, data, wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); + ret = unwrap_aes(wkey, key, data, data_size, + wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); break; case NCR_WALG_AES_RFC5649: - ret = unwrap_aes_rfc5649(wkey, key, data, wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); + ret = unwrap_aes_rfc5649(wkey, key, data, data_size, + wrap.params.params.cipher.iv, wrap.params.params.cipher.iv_size); break; default: err(); ret = -EINVAL; } - + fail: if (wkey != NULL) _ncr_key_item_put(wkey); if (key != NULL) _ncr_key_item_put(key); - if (data != NULL) _ncr_data_item_put(data); + if (data != NULL) kfree(data); return ret; } -int ncr_key_storage_wrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) +int ncr_key_storage_wrap(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_storage_wrap_st wrap; struct key_item_st* wkey = NULL; -struct data_item_st * data = NULL; +void* data = NULL; +size_t data_size; uint8_t * sdata = NULL; size_t sdata_size = 0; int ret; @@ -579,26 +601,42 @@ int ret; goto fail; } - data = ncr_data_item_get(data_lst, wrap.data); + data_size = wrap.io_size; + data = kmalloc(data_size, GFP_KERNEL); if (data == NULL) { err(); - ret = -EINVAL; + ret = -ENOMEM; goto fail; } - - data->flags = key_flags_to_data(wkey->flags) | NCR_DATA_FLAG_EXPORTABLE; - + ret = key_to_storage_data(&sdata, &sdata_size, wkey); if (ret < 0) { err(); goto fail; } - ret = _wrap_aes_rfc5649(sdata, sdata_size, &master_key, data, NULL, 0); + ret = _wrap_aes_rfc5649(sdata, sdata_size, &master_key, data, &data_size, NULL, 0); + if (ret < 0) { + err(); + goto fail; + } + + ret = copy_to_user(wrap.io, data, data_size); + if (unlikely(ret)) { + ret = -EFAULT; + goto fail; + } + + wrap.io_size = data_size; + + ret = copy_to_user(arg, &wrap, sizeof(wrap)); + if (unlikely(ret)) { + ret = -EFAULT; + } fail: if (wkey != NULL) _ncr_key_item_put(wkey); - if (data != NULL) _ncr_data_item_put(data); + if (data != NULL) kfree(data); if (sdata != NULL) kfree(sdata); return ret; @@ -607,13 +645,13 @@ fail: /* Unwraps keys. All keys unwrapped are not accessible by * userspace. */ -int ncr_key_storage_unwrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) +int ncr_key_storage_unwrap(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_storage_wrap_st wrap; struct key_item_st* wkey = NULL; -struct data_item_st * data = NULL; +void* data = NULL; uint8_t * sdata = NULL; -size_t sdata_size = 0; +size_t sdata_size = 0, data_size; int ret; if (master_key.type != NCR_KEY_TYPE_SECRET) { @@ -632,14 +670,21 @@ int ret; return ret; } - data = ncr_data_item_get(data_lst, wrap.data); + data_size = wrap.io_size; + data = kmalloc(data_size, GFP_KERNEL); if (data == NULL) { err(); - ret = -EINVAL; + ret = -ENOMEM; + goto fail; + } + + if (unlikely(copy_from_user(data, wrap.io, data_size))) { + err(); + ret = -EFAULT; goto fail; } - sdata_size = data->data_size; + sdata_size = data_size; sdata = kmalloc(sdata_size, GFP_KERNEL); if (sdata == NULL) { err(); @@ -647,9 +692,9 @@ int ret; goto fail; } - wkey->flags = data_flags_to_key(data->flags) | NCR_KEY_FLAG_WRAPPABLE; + wkey->flags = NCR_KEY_FLAG_WRAPPABLE; - ret = _unwrap_aes_rfc5649(sdata, &sdata_size, &master_key, data, NULL, 0); + ret = _unwrap_aes_rfc5649(sdata, &sdata_size, &master_key, data, data_size, NULL, 0); if (ret < 0) { err(); goto fail; @@ -664,7 +709,7 @@ int ret; fail: if (wkey != NULL) _ncr_key_item_put(wkey); - if (data != NULL) _ncr_data_item_put(data); + if (data != NULL) kfree(data); if (sdata != NULL) kfree(sdata); return ret; @@ -26,7 +26,7 @@ #include <asm/ioctl.h> #include <linux/scatterlist.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" static void ncr_key_clear(struct key_item_st* item); @@ -231,13 +231,12 @@ int ncr_key_deinit(struct list_sem_st* lst, void __user* arg) /* "exports" a key to a data item. If the key is not exportable * to userspace then the data item will also not be. */ -int ncr_key_export(struct list_sem_st* data_lst, - struct list_sem_st* key_lst, void __user* arg) +int ncr_key_export(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_data_st data; struct key_item_st* item = NULL; -struct data_item_st* ditem = NULL; -uint32_t size; +void* tmp = NULL; +uint32_t tmp_size; int ret; if (unlikely(copy_from_user(&data, arg, sizeof(data)))) { @@ -251,18 +250,15 @@ int ret; return ret; } - ditem = ncr_data_item_get( data_lst, data.data); - if (ditem == NULL) { + if (!(item->flags & NCR_KEY_FLAG_EXPORTABLE)) { err(); - ret = -EINVAL; + ret = -EPERM; goto fail; } - ditem->flags = key_flags_to_data(item->flags); - switch (item->type) { case NCR_KEY_TYPE_SECRET: - if (item->key.secret.size > ditem->max_data_size) { + if (item->key.secret.size > data.idata_size) { err(); ret = -EINVAL; goto fail; @@ -270,21 +266,40 @@ int ret; /* found */ if (item->key.secret.size > 0) { - memcpy(ditem->data, item->key.secret.data, item->key.secret.size); + ret = copy_to_user(data.idata, item->key.secret.data, item->key.secret.size); + if (unlikely(ret)) { + err(); + ret = -EFAULT; + goto fail; + } } - ditem->data_size = item->key.secret.size; + data.idata_size = item->key.secret.size; break; case NCR_KEY_TYPE_PUBLIC: case NCR_KEY_TYPE_PRIVATE: - size = ditem->max_data_size; - ret = ncr_pk_pack(item, ditem->data, &size); + tmp_size = data.idata_size; - ditem->data_size = size; + tmp = kmalloc(tmp_size, GFP_KERNEL); + if (tmp == NULL) { + err(); + ret = -ENOMEM; + goto fail; + } + + ret = ncr_pk_pack(item, tmp, &tmp_size); + data.idata_size = tmp_size; if (ret < 0) { err(); goto fail; } + + ret = copy_to_user(data.idata, tmp, tmp_size); + if (unlikely(ret)) { + err(); + ret = -EFAULT; + goto fail; + } break; default: @@ -293,16 +308,16 @@ int ret; goto fail; } - _ncr_key_item_put( item); - _ncr_data_item_put( ditem); - - return 0; + if (unlikely(copy_to_user(arg, &data, sizeof(data)))) { + err(); + ret = -EFAULT; + } else + ret = 0; fail: + kfree(tmp); if (item) _ncr_key_item_put(item); - if (ditem) - _ncr_data_item_put(ditem); return ret; } @@ -310,13 +325,13 @@ fail: /* "imports" a key from a data item. If the key is not exportable * to userspace then the key item will also not be. */ -int ncr_key_import(struct list_sem_st* data_lst, - struct list_sem_st* key_lst, void __user* arg) +int ncr_key_import(struct list_sem_st* key_lst, void __user* arg) { struct ncr_key_data_st data; struct key_item_st* item = NULL; -struct data_item_st* ditem = NULL; int ret; +void* tmp = NULL; +size_t tmp_size; if (unlikely(copy_from_user(&data, arg, sizeof(data)))) { err(); @@ -329,13 +344,20 @@ int ret; return ret; } - ditem = ncr_data_item_get( data_lst, data.data); - if (ditem == NULL) { + tmp = kmalloc(data.idata_size, GFP_KERNEL); + if (tmp == NULL) { err(); - ret = -EINVAL; + ret = -ENOMEM; goto fail; } - + + if (unlikely(copy_from_user(tmp, data.idata, data.idata_size))) { + err(); + ret = -EFAULT; + goto fail; + } + tmp_size = data.idata_size; + item->type = data.type; item->algorithm = _ncr_algo_to_properties(data.algorithm); if (item->algorithm == NULL) { @@ -344,11 +366,6 @@ int ret; goto fail; } item->flags = data.flags; - /* if data cannot be exported then the flags above - * should be overriden */ - if (!(ditem->flags & NCR_DATA_FLAG_EXPORTABLE)) { - item->flags &= ~NCR_KEY_FLAG_EXPORTABLE; - } if (data.key_id_size > MAX_KEY_ID_SIZE) { err(); @@ -363,18 +380,18 @@ int ret; switch(item->type) { case NCR_KEY_TYPE_SECRET: - if (ditem->data_size > NCR_CIPHER_MAX_KEY_LEN) { + if (tmp_size > NCR_CIPHER_MAX_KEY_LEN) { err(); ret = -EINVAL; goto fail; } - memcpy(item->key.secret.data, ditem->data, ditem->data_size); - item->key.secret.size = ditem->data_size; + memcpy(item->key.secret.data, tmp, tmp_size); + item->key.secret.size = tmp_size; break; case NCR_KEY_TYPE_PRIVATE: case NCR_KEY_TYPE_PUBLIC: - ret = ncr_pk_unpack( item, ditem->data, ditem->data_size); + ret = ncr_pk_unpack( item, tmp, tmp_size); if (ret < 0) { err(); goto fail; @@ -387,16 +404,13 @@ int ret; goto fail; } - _ncr_key_item_put( item); - _ncr_data_item_put( ditem); - - return 0; + ret = 0; fail: if (item) _ncr_key_item_put(item); - if (ditem) - _ncr_data_item_put(ditem); + kfree(tmp); + return ret; } diff --git a/ncr-limits.c b/ncr-limits.c index 746434c..7a98f3c 100644 --- a/ncr-limits.c +++ b/ncr-limits.c @@ -29,17 +29,15 @@ #include <linux/file.h> #include <linux/cred.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" /* arbitrary now */ static unsigned int max_per_user[] = { [LIMIT_TYPE_KEY] = 128, - [LIMIT_TYPE_DATA] = 128, }; static unsigned int max_per_process[] = { [LIMIT_TYPE_KEY] = 64, - [LIMIT_TYPE_DATA] = 64, }; struct limit_user_item_st { @@ -26,7 +26,7 @@ #include <asm/ioctl.h> #include <linux/scatterlist.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" #include <tomcrypt.h> static struct workqueue_struct * pk_wq = NULL; @@ -359,9 +359,13 @@ int ncr_pk_cipher_init(const struct algo_properties_st *algo, err(); return -EINVAL; } - } else if (params->params.rsa.type == RSA_PKCS1_PSS) + } else if (params->params.rsa.type == RSA_PKCS1_PSS) { ctx->type = LTC_LTC_PKCS_1_PSS; - + } else { + err(); + return -EINVAL; + } + ctx->salt_len = params->params.rsa.pss_salt; break; case NCR_ALG_DSA: @@ -377,75 +381,158 @@ int ncr_pk_cipher_init(const struct algo_properties_st *algo, } int ncr_pk_cipher_encrypt(const struct ncr_pk_ctx* ctx, - const void* input, size_t input_size, - void* output, size_t *output_size) + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size) { -int cret; -unsigned long osize = *output_size; +int cret, ret; +unsigned long osize = *osg_size; +uint8_t* tmp; +void * input, *output; + + tmp = kmalloc(isg_size + *osg_size, GFP_KERNEL); + if (tmp == NULL) { + err(); + return -ENOMEM; + } + + ret = sg_copy_to_buffer((struct scatterlist*)isg, isg_cnt, tmp, isg_size); + if (ret != isg_size) { + err(); + ret = -EINVAL; + goto fail; + } + + input = tmp; + output = &tmp[isg_size]; + switch(ctx->algorithm->algo) { case NCR_ALG_RSA: - cret = rsa_encrypt_key_ex( input, input_size, output, &osize, + cret = rsa_encrypt_key_ex( input, isg_size, output, &osize, NULL, 0, ctx->oaep_hash, ctx->type, &ctx->key->key.pk.rsa); if (cret != CRYPT_OK) { - printk("cret: %d type: %d\n", cret, ctx->type); err(); - return tomerr(cret); + ret = tomerr(cret); + goto fail; } - *output_size = osize; + *osg_size = osize; + break; case NCR_ALG_DSA: - return -EINVAL; - break; + ret = -EINVAL; + goto fail; default: err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } - - return 0; + + ret = sg_copy_from_buffer(osg, osg_cnt, output, *osg_size); + if (ret != *osg_size) { + err(); + ret = -EINVAL; + goto fail; + } + + ret = 0; + +fail: + kfree(tmp); + return ret; } -int ncr_pk_cipher_decrypt(const struct ncr_pk_ctx* ctx, const void* input, size_t input_size, - void* output, size_t *output_size) +int ncr_pk_cipher_decrypt(const struct ncr_pk_ctx* ctx, + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size) { -int cret; -unsigned long osize = *output_size; +int cret, ret; int stat; +unsigned long osize = *osg_size; +uint8_t* tmp; +void * input, *output; + + tmp = kmalloc(isg_size + *osg_size, GFP_KERNEL); + if (tmp == NULL) { + err(); + return -ENOMEM; + } + + input = tmp; + output = &tmp[isg_size]; + + ret = sg_copy_to_buffer((struct scatterlist*)isg, isg_cnt, input, isg_size); + if (ret != isg_size) { + err(); + ret = -EINVAL; + goto fail; + } switch(ctx->algorithm->algo) { case NCR_ALG_RSA: - cret = rsa_decrypt_key_ex( input, input_size, output, &osize, + cret = rsa_decrypt_key_ex( input, isg_size, output, &osize, NULL, 0, ctx->oaep_hash, ctx->type, &stat, &ctx->key->key.pk.rsa); if (cret != CRYPT_OK) { err(); - return tomerr(cret); + ret = tomerr(cret); + goto fail; } if (stat==0) { err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } - *output_size = osize; + *osg_size = osize; break; case NCR_ALG_DSA: - return -EINVAL; - break; + ret = -EINVAL; + goto fail; default: err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } + + ret = sg_copy_from_buffer(osg, osg_cnt, output, *osg_size); + if (ret != *osg_size) { + err(); + ret = -EINVAL; + goto fail; + } + + ret = 0; +fail: + kfree(tmp); - return 0; + return ret; } int ncr_pk_cipher_sign(const struct ncr_pk_ctx* ctx, - const void* input, size_t input_size, - void* output, size_t *output_size) + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size) { -int cret; -unsigned long osize = *output_size; +int cret, ret; +unsigned long osize = *osg_size; +uint8_t* tmp; +void * input, *output; + + tmp = kmalloc(isg_size + *osg_size, GFP_KERNEL); + if (tmp == NULL) { + err(); + return -ENOMEM; + } + + input = tmp; + output = &tmp[isg_size]; + + ret = sg_copy_to_buffer((struct scatterlist*)isg, isg_cnt, input, isg_size); + if (ret != isg_size) { + err(); + ret = -EINVAL; + goto fail; + } switch(ctx->algorithm->algo) { case NCR_ALG_RSA: @@ -453,39 +540,63 @@ unsigned long osize = *output_size; err(); return -EINVAL; } - cret = rsa_sign_hash_ex( input, input_size, output, &osize, + cret = rsa_sign_hash_ex( input, isg_size, output, &osize, ctx->type, ctx->sign_hash, ctx->salt_len, &ctx->key->key.pk.rsa); - if (cret != CRYPT_OK) { err(); return tomerr(cret); } - *output_size = osize; + *osg_size = osize; break; case NCR_ALG_DSA: - cret = dsa_sign_hash( input, input_size, output, &osize, + cret = dsa_sign_hash( input, isg_size, output, &osize, &ctx->key->key.pk.dsa); if (cret != CRYPT_OK) { err(); return tomerr(cret); } - *output_size = osize; + *osg_size = osize; break; default: err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } + + ret = sg_copy_from_buffer(osg, osg_cnt, output, *osg_size); + if (ret != *osg_size) { + err(); + ret = -EINVAL; + goto fail; + } + ret = 0; +fail: + kfree(tmp); - return 0; + return ret; } int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx, - const void* signature, size_t signature_size, + const struct scatterlist* sign_sg, unsigned int sign_sg_cnt, size_t sign_sg_size, const void* hash, size_t hash_size, ncr_error_t* err) { -int cret; -int stat; +int cret, ret; +int stat = 0; +uint8_t* sig; + + sig = kmalloc(sign_sg_size, GFP_KERNEL); + if (sig == NULL) { + err(); + return -ENOMEM; + } + + ret = sg_copy_to_buffer((struct scatterlist*)sign_sg, sign_sg_cnt, sig, sign_sg_size); + if (ret != sign_sg_size) { + err(); + ret = -EINVAL; + goto fail; + } switch(ctx->algorithm->algo) { case NCR_ALG_RSA: @@ -493,15 +604,15 @@ int stat; err(); return -EINVAL; } - cret = rsa_verify_hash_ex( signature, signature_size, + cret = rsa_verify_hash_ex( sig, sign_sg_size, hash, hash_size, ctx->type, ctx->sign_hash, ctx->salt_len, &stat, &ctx->key->key.pk.rsa); - if (cret != CRYPT_OK) { err(); - return tomerr(cret); + ret = tomerr(cret); + goto fail; } - + if (stat == 1) *err = 0; else @@ -509,11 +620,12 @@ int stat; break; case NCR_ALG_DSA: - cret = dsa_verify_hash( signature, signature_size, + cret = dsa_verify_hash( sig, sign_sg_size, hash, hash_size, &stat, &ctx->key->key.pk.dsa); if (cret != CRYPT_OK) { err(); - return tomerr(cret); + ret = tomerr(cret); + goto fail; } if (stat == 1) @@ -524,8 +636,12 @@ int stat; break; default: err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } - - return 0; + + ret = 0; +fail: + kfree(sig); + return ret; } @@ -34,15 +34,21 @@ int ncr_pk_cipher_init(const struct algo_properties_st *algo, struct ncr_pk_ctx* ctx, struct ncr_key_params_st* params, struct key_item_st *key, const struct algo_properties_st *sign_hash); void ncr_pk_cipher_deinit(struct ncr_pk_ctx* ctx); -int ncr_pk_cipher_encrypt(const struct ncr_pk_ctx* ctx, const void* input, - size_t input_size, void* output, size_t *output_size); -int ncr_pk_cipher_decrypt(const struct ncr_pk_ctx* ctx, const void* input, - size_t input_size, void* output, size_t *output_size); -int ncr_pk_cipher_sign(const struct ncr_pk_ctx* ctx, const void* input, - size_t input_size, void* output, size_t *output_size); +int ncr_pk_cipher_encrypt(const struct ncr_pk_ctx* ctx, + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size); + +int ncr_pk_cipher_decrypt(const struct ncr_pk_ctx* ctx, + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size); + +int ncr_pk_cipher_sign(const struct ncr_pk_ctx* ctx, + const struct scatterlist* isg, unsigned int isg_cnt, size_t isg_size, + struct scatterlist *osg, unsigned int osg_cnt, size_t* osg_size); + int ncr_pk_cipher_verify(const struct ncr_pk_ctx* ctx, - const void* signature, size_t signature_size, - const void* hash, size_t hash_size, ncr_error_t*); + const struct scatterlist* sign_sg, unsigned int sign_sg_cnt, size_t sign_sg_size, + const void* hash, size_t hash_size, ncr_error_t* err); #endif diff --git a/ncr-sessions.c b/ncr-sessions.c index f768cb3..466558b 100644 --- a/ncr-sessions.c +++ b/ncr-sessions.c @@ -22,8 +22,11 @@ #include <linux/crypto.h> #include "cryptodev.h" #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" +#include <linux/mm_types.h> +#include <linux/scatterlist.h> +static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op); static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc); void ncr_sessions_list_deinit(struct list_sem_st* lst) @@ -84,6 +87,8 @@ void _ncr_sessions_item_put( struct session_item_st* item) cryptodev_hash_deinit(&item->hash); if (item->key) _ncr_key_item_put(item->key); + kfree(item->sg); + kfree(item->pages); kfree(item); } } @@ -92,13 +97,25 @@ struct session_item_st* ncr_session_new(struct list_sem_st* lst) { struct session_item_st* sess; - sess = kmalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc(sizeof(*sess), GFP_KERNEL); if (sess == NULL) { err(); return NULL; } - memset(sess, 0, sizeof(*sess)); + sess->array_size = DEFAULT_PREALLOC_PAGES; + sess->pages = kzalloc(sess->array_size * + sizeof(struct page *), GFP_KERNEL); + sess->sg = kzalloc(sess->array_size * + sizeof(struct scatterlist), GFP_KERNEL); + if (sess->sg == NULL || sess->pages == NULL) { + err(); + kfree(sess->sg); + kfree(sess->pages); + kfree(sess); + return NULL; + } + init_MUTEX(&sess->mem_mutex); atomic_set(&sess->refcnt, 1); @@ -176,9 +193,9 @@ static const struct algo_properties_st algo_properties[] = { { .algo = NCR_ALG_HMAC_SHA2_512, .is_hmac = 1, .kstr = "hmac(sha512)", .digest_size = 64, .can_sign=1, .key_type = NCR_KEY_TYPE_SECRET }, - { .algo = NCR_ALG_RSA, .kstr = NULL, + { .algo = NCR_ALG_RSA, .kstr = NULL, .is_pk = 1, .can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, - { .algo = NCR_ALG_DSA, .kstr = NULL, + { .algo = NCR_ALG_DSA, .kstr = NULL, .is_pk = 1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, { .algo = NCR_ALG_NONE } @@ -216,6 +233,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses ret = -EINVAL; goto fail; } + switch(session->op) { case NCR_OP_ENCRYPT: case NCR_OP_DECRYPT: @@ -273,85 +291,83 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses case NCR_OP_SIGN: case NCR_OP_VERIFY: - if (!ns->algorithm->can_sign) { + if (!ns->algorithm->can_sign && !ns->algorithm->can_digest) { err(); ret = -EINVAL; goto fail; } - /* read key */ - ret = ncr_key_item_get_read( &ns->key, &lists->key, session->key); - if (ret < 0) { - err(); - goto fail; - } - - if (ns->key->type == NCR_KEY_TYPE_SECRET) { + if (ns->algorithm->can_digest) { if (ns->algorithm->kstr == NULL) { err(); - return -EINVAL; - } - - ret = cryptodev_hash_init(&ns->hash, ns->algorithm->kstr, 1, - ns->key->key.secret.data, ns->key->key.secret.size); - if (ret < 0) { - err(); - goto fail; - } - - } else if (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC) { - sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params); - if (IS_ERR(sign_hash)) { - err(); - return PTR_ERR(sign_hash); - } - - if (!sign_hash->can_digest) { - err(); - ret = -EINVAL; - goto fail; - } - if (sign_hash->kstr == NULL) { - err(); ret = -EINVAL; goto fail; } - ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk, - &session->params, ns->key, sign_hash); + ret = cryptodev_hash_init(&ns->hash, ns->algorithm->kstr, 0, NULL, 0); if (ret < 0) { err(); goto fail; } - - ret = cryptodev_hash_init(&ns->hash, sign_hash->kstr, 0, NULL, 0); + + } else { + /* read key */ + ret = ncr_key_item_get_read( &ns->key, &lists->key, session->key); if (ret < 0) { err(); goto fail; } - } else { - err(); - ret = -EINVAL; - goto fail; - } - break; - case NCR_OP_DIGEST: - if (!ns->algorithm->can_digest) { - err(); - ret = -EINVAL; - goto fail; - } - if (ns->algorithm->kstr == NULL) { - err(); - ret = -EINVAL; - goto fail; - } + if (ns->algorithm->is_hmac && ns->key->type == NCR_KEY_TYPE_SECRET) { + if (ns->algorithm->kstr == NULL) { + err(); + ret = -EINVAL; + goto fail; + } - ret = cryptodev_hash_init(&ns->hash, ns->algorithm->kstr, 0, NULL, 0); - if (ret < 0) { - err(); - goto fail; + ret = cryptodev_hash_init(&ns->hash, ns->algorithm->kstr, 1, + ns->key->key.secret.data, ns->key->key.secret.size); + if (ret < 0) { + err(); + goto fail; + } + + } else if (ns->algorithm->is_pk && (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC)) { + sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params); + if (IS_ERR(sign_hash)) { + err(); + return PTR_ERR(sign_hash); + } + + if (!sign_hash->can_digest) { + err(); + ret = -EINVAL; + goto fail; + } + + if (sign_hash->kstr == NULL) { + err(); + ret = -EINVAL; + goto fail; + } + + ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk, + &session->params, ns->key, sign_hash); + if (ret < 0) { + err(); + goto fail; + } + + ret = cryptodev_hash_init(&ns->hash, sign_hash->kstr, 0, NULL, 0); + if (ret < 0) { + err(); + goto fail; + } + } else { + err(); + ret = -EINVAL; + goto fail; + } } break; @@ -397,14 +413,223 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg) return ret; } -/* Main update function - */ -static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op) +int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt, + size_t input_size, void *output, unsigned output_cnt, size_t *output_size) +{ +int ret; + + if (sess->algorithm->is_symmetric) { + /* read key */ + ret = cryptodev_cipher_encrypt(&sess->cipher, input, + output, input_size); + if (ret < 0) { + err(); + return ret; + } + /* FIXME: handle ciphers that do not require that */ + + } else { /* public key */ + ret = ncr_pk_cipher_encrypt(&sess->pk, input, input_cnt, input_size, + output, output_cnt, output_size); + + if (ret < 0) { + err(); + return ret; + } + } + + return 0; +} + +int _ncr_session_decrypt(struct session_item_st* sess, const struct scatterlist* input, + unsigned input_cnt, size_t input_size, + struct scatterlist *output, unsigned output_cnt, size_t *output_size) +{ +int ret; + + if (sess->algorithm->is_symmetric) { + /* read key */ + ret = cryptodev_cipher_decrypt(&sess->cipher, input, + output, input_size); + if (ret < 0) { + err(); + return ret; + } + /* FIXME: handle ciphers that do not require equality */ + + } else { /* public key */ + ret = ncr_pk_cipher_decrypt(&sess->pk, input, input_cnt, input_size, + output, output_cnt, output_size); + + if (ret < 0) { + err(); + return ret; + } + } + + return 0; +} + +void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc) +{ + struct session_item_st * item, *tmp; + + down(&lst->sem); + + list_for_each_entry_safe(item, tmp, &lst->list, list) { + if(item->desc == desc) { + list_del(&item->list); + _ncr_sessions_item_put( item); /* decrement ref count */ + break; + } + } + + up(&lst->sem); + + return; +} + +/* Only the output buffer is given as scatterlist */ +static int get_userbuf1(struct session_item_st* ses, + void __user * udata, size_t udata_size, struct scatterlist **dst_sg, unsigned *dst_cnt) +{ + int pagecount = 0; + + if (unlikely(udata == NULL)) { + err(); + return -EINVAL; + } + + if (unlikely(ses->sg == NULL || ses->pages == NULL)) { + err(); + return -ENOMEM; + } + + pagecount = PAGECOUNT(udata, udata_size); + + if (pagecount > ses->array_size) { + while (ses->array_size < pagecount) + ses->array_size *= 2; + + dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n", + __func__, ses->array_size); + ses->pages = krealloc(ses->pages, ses->array_size * + sizeof(struct page *), GFP_KERNEL); + ses->sg = krealloc(ses->sg, ses->array_size * + sizeof(struct scatterlist), GFP_KERNEL); + + if (unlikely(ses->sg == NULL || ses->pages == NULL)) { + return -ENOMEM; + } + } + + if (__get_userbuf(udata, udata_size, 1, + pagecount, ses->pages, ses->sg)) { + err(); + return -EINVAL; + } + (*dst_sg) = ses->sg; + *dst_cnt = pagecount; + + ses->available_pages = pagecount; + + return 0; +} + +/* make op->data.udata.input and op->data.udata.output available in scatterlists */ +static int get_userbuf2(struct session_item_st* ses, + struct ncr_session_op_st* op, struct scatterlist **src_sg, + unsigned *src_cnt, struct scatterlist **dst_sg, unsigned *dst_cnt) +{ + int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1; + size_t input_size = op->data.udata.input_size; + + if (unlikely(op->data.udata.input == NULL)) { + err(); + return -EINVAL; + } + + if (unlikely(ses->sg == NULL || ses->pages == NULL)) { + err(); + return -ENOMEM; + } + + src_pagecount = PAGECOUNT(op->data.udata.input, input_size); + + if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */ + write_src = 0; + if (op->data.udata.output != NULL) { + dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size); + } else { + dst_pagecount = 0; + } + } else { + src_pagecount = max((int)(PAGECOUNT(op->data.udata.output, op->data.udata.output_size)), + src_pagecount); + input_size = max(input_size, (size_t)op->data.udata.output_size); + } + + pagecount = src_pagecount + dst_pagecount; + + if (pagecount > ses->array_size) { + while (ses->array_size < pagecount) + ses->array_size *= 2; + + dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n", + __func__, ses->array_size); + ses->pages = krealloc(ses->pages, ses->array_size * + sizeof(struct page *), GFP_KERNEL); + ses->sg = krealloc(ses->sg, ses->array_size * + sizeof(struct scatterlist), GFP_KERNEL); + + if (ses->sg == NULL || ses->pages == NULL) { + return -ENOMEM; + } + } + + if (__get_userbuf(op->data.udata.input, input_size, write_src, + src_pagecount, ses->pages, ses->sg)) { + err(); + printk("write: %d\n", write_src); + return -EINVAL; + } + (*src_sg) = ses->sg; + *src_cnt = src_pagecount; + + if (dst_pagecount) { + *dst_cnt = dst_pagecount; + (*dst_sg) = ses->sg + src_pagecount; + + if (__get_userbuf(op->data.udata.output, op->data.udata.output_size, 1, dst_pagecount, + ses->pages + src_pagecount, *dst_sg)) { + err(); + release_user_pages(ses->pages, src_pagecount); + return -EINVAL; + } + } else { + if (op->data.udata.output != NULL) { + *dst_cnt = src_pagecount; + (*dst_sg) = (*src_sg); + } else { + *dst_cnt = 0; + *dst_sg = NULL; + } + } + + ses->available_pages = pagecount; + + return 0; +} + +/* Called when userspace buffers are used */ +int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op) { int ret; struct session_item_st* sess; - struct data_item_st* data = NULL; - struct data_item_st* odata = NULL; + struct scatterlist *isg; + struct scatterlist *osg; + unsigned osg_cnt=0, isg_cnt=0; + size_t isg_size, osg_size; sess = ncr_sessions_item_get( &lists->sessions, op->ses); if (sess == NULL) { @@ -412,131 +637,68 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st return -EINVAL; } + if (down_interruptible(&sess->mem_mutex)) { + err(); + _ncr_sessions_item_put(sess); + return -ERESTARTSYS; + } + + ret = get_userbuf2(sess, op, &isg, &isg_cnt, &osg, &osg_cnt); + if (ret < 0) { + err(); + goto fail; + } + isg_size = op->data.udata.input_size; + osg_size = op->data.udata.output_size; + switch(sess->op) { case NCR_OP_ENCRYPT: - /* obtain data item */ - data = ncr_data_item_get( &lists->data, op->data.cipher.plaintext); - if (data == NULL) { + if (osg == NULL) { err(); ret = -EINVAL; goto fail; } - odata = ncr_data_item_get( &lists->data, op->data.cipher.ciphertext); - if (odata == NULL) { + ret = _ncr_session_encrypt(sess, isg, isg_cnt, isg_size, + osg, osg_cnt, &osg_size); + if (ret < 0) { err(); - ret = -EINVAL; - goto fail; - } - - if (odata->max_data_size < data->data_size) { - err(); - ret = -EINVAL; goto fail; } + op->data.udata.output_size = osg_size; - if (sess->algorithm->is_symmetric) { - /* read key */ - ret = _cryptodev_cipher_encrypt(&sess->cipher, data->data, - data->data_size, odata->data, data->data_size); - if (ret < 0) { - err(); - goto fail; - } - /* FIXME: handle ciphers that do not require that */ - odata->data_size = data->data_size; - } else { /* public key */ - size_t new_size = odata->max_data_size; - ret = ncr_pk_cipher_encrypt(&sess->pk, data->data, data->data_size, - odata->data, &new_size); - - odata->data_size = new_size; - - if (ret < 0) { - err(); - goto fail; - } - } break; case NCR_OP_DECRYPT: - /* obtain data item */ - data = ncr_data_item_get( &lists->data, op->data.cipher.ciphertext); - if (data == NULL) { + if (osg == NULL) { err(); ret = -EINVAL; goto fail; } - odata = ncr_data_item_get( &lists->data, op->data.cipher.plaintext); - if (odata == NULL) { + if (osg_size < isg_size) { err(); ret = -EINVAL; goto fail; } - if (odata->max_data_size < data->data_size) { + ret = _ncr_session_decrypt(sess, isg, isg_cnt, isg_size, + osg, osg_cnt, &osg_size); + if (ret < 0) { err(); - ret = -EINVAL; goto fail; } - - /* read key */ - if (sess->algorithm->is_symmetric) { - ret = _cryptodev_cipher_decrypt(&sess->cipher, data->data, data->data_size, odata->data, data->data_size); - if (ret < 0) { - err(); - goto fail; - } - /* FIXME: handle ciphers that do not require that */ - odata->data_size = data->data_size; - } else { /* public key */ - size_t new_size = odata->max_data_size; - ret = ncr_pk_cipher_decrypt(&sess->pk, data->data, data->data_size, - odata->data, &new_size); - - odata->data_size = new_size; - - if (ret < 0) { - err(); - goto fail; - } - } + op->data.udata.output_size = osg_size; break; case NCR_OP_SIGN: - case NCR_OP_DIGEST: - /* obtain data item */ - data = ncr_data_item_get( &lists->data, op->data.sign.text); - if (data == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - - ret = _cryptodev_hash_update(&sess->hash, data->data, data->data_size); - if (ret < 0) { - err(); - goto fail; - } - break; - case NCR_OP_VERIFY: - /* obtain data item */ - data = ncr_data_item_get( &lists->data, op->data.verify.text); - if (data == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - - ret = _cryptodev_hash_update(&sess->hash, data->data, data->data_size); + ret = cryptodev_hash_update(&sess->hash, isg, isg_size); if (ret < 0) { err(); goto fail; } break; - default: err(); ret = -EINVAL; @@ -546,51 +708,42 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st ret = 0; fail: - if (odata) _ncr_data_item_put(odata); - if (data) _ncr_data_item_put(data); + if (sess->available_pages) { + release_user_pages(sess->pages, sess->available_pages); + sess->available_pages = 0; + } + up(&sess->mem_mutex); _ncr_sessions_item_put(sess); return ret; } -int ncr_session_update(struct ncr_lists* lists, void __user* arg) +static int try_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op) { - struct ncr_session_op_st op; - - if (unlikely(copy_from_user( &op, arg, sizeof(op)))) { - err(); - return -EFAULT; + if (op->type == NCR_KEY_DATA) { + if (op->data.kdata.input != NCR_KEY_INVALID) + return _ncr_session_update_key(lists, op); + } else if (op->type == NCR_DIRECT_DATA) { + if (op->data.udata.input != NULL) + return _ncr_session_update(lists, op); } - - return _ncr_session_update(lists, &op); -} -static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc) -{ - struct session_item_st * item, *tmp; - - down(&lst->sem); - - list_for_each_entry_safe(item, tmp, &lst->list, list) { - if(item->desc == desc) { - list_del(&item->list); - _ncr_sessions_item_put( item); /* decrement ref count */ - break; - } - } - - up(&lst->sem); - - return; + return 0; } -static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op) +int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op) { int ret; struct session_item_st* sess; - struct data_item_st* odata = NULL; int digest_size; uint8_t digest[NCR_HASH_MAX_OUTPUT_SIZE]; + uint8_t vdigest[NCR_HASH_MAX_OUTPUT_SIZE]; + struct scatterlist *osg; + unsigned osg_cnt=0; + size_t osg_size = 0; + size_t orig_osg_size; + void __user * udata = NULL; + size_t *udata_size; sess = ncr_sessions_item_get( &lists->sessions, op->ses); if (sess == NULL) { @@ -598,32 +751,42 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* return -EINVAL; } + ret = try_session_update(lists, op); + if (ret < 0) { + err(); + _ncr_sessions_item_put(sess); + return ret; + } + + if (down_interruptible(&sess->mem_mutex)) { + err(); + _ncr_sessions_item_put(sess); + return -ERESTARTSYS; + } + + if (op->type == NCR_DIRECT_DATA) { + udata = op->data.udata.output; + udata_size = &op->data.udata.output_size; + } else if (op->type == NCR_KEY_DATA) { + udata = op->data.kdata.output; + udata_size = &op->data.kdata.output_size; + } else { + err(); + ret = -EINVAL; + goto fail; + } + switch(sess->op) { case NCR_OP_ENCRYPT: case NCR_OP_DECRYPT: - /* obtain data item */ - if (op->data.cipher.plaintext != NCR_DATA_INVALID && - op->data.cipher.ciphertext != NCR_DATA_INVALID) { - ret = _ncr_session_update(lists, op); - if (ret < 0) - goto fail; - } break; - case NCR_OP_VERIFY: - /* obtain data item */ - if (op->data.sign.text != NCR_DATA_INVALID) { - ret = _ncr_session_update(lists, op); - if (ret < 0) - goto fail; - } - - odata = ncr_data_item_get( &lists->data, op->data.verify.signature); - if (odata == NULL) { + ret = get_userbuf1(sess, udata, *udata_size, &osg, &osg_cnt); + if (ret < 0) { err(); - ret = -EINVAL; goto fail; } + orig_osg_size = osg_size = *udata_size; digest_size = sess->hash.digestsize; if (digest_size == 0 || sizeof(digest) < digest_size) { @@ -636,11 +799,17 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* err(); goto fail; } - if (sess->algorithm->is_hmac) { - if (digest_size != odata->data_size || - memcmp(odata->data, digest, digest_size) != 0) { + ret = sg_copy_to_buffer(osg, osg_cnt, vdigest, digest_size); + if (ret != digest_size) { + err(); + ret = -EINVAL; + goto fail; + } + + if (digest_size != osg_size || + memcmp(vdigest, digest, digest_size) != 0) { op->err = NCR_VERIFICATION_FAILED; } else { @@ -648,7 +817,7 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* } } else { /* PK signature */ - ret = ncr_pk_cipher_verify(&sess->pk, odata->data, odata->data_size, + ret = ncr_pk_cipher_verify(&sess->pk, osg, osg_cnt, osg_size, digest, digest_size, &op->err); if (ret < 0) { err(); @@ -658,41 +827,46 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* break; case NCR_OP_SIGN: - case NCR_OP_DIGEST: - /* obtain data item */ - if (op->data.sign.text != NCR_DATA_INVALID) { - ret = _ncr_session_update(lists, op); - if (ret < 0) - goto fail; + ret = get_userbuf1(sess, udata, *udata_size, &osg, &osg_cnt); + if (ret < 0) { + err(); + goto fail; } - odata = ncr_data_item_get( &lists->data, op->data.sign.output); - if (odata == NULL) { + orig_osg_size = osg_size = *udata_size; + + digest_size = sess->hash.digestsize; + if (digest_size == 0 || osg_size < digest_size) { err(); ret = -EINVAL; goto fail; } - digest_size = sess->hash.digestsize; - if (digest_size == 0 || odata->max_data_size < digest_size) { + ret = cryptodev_hash_final(&sess->hash, digest); + if (ret < 0) { + err(); + goto fail; + } + + ret = sg_copy_from_buffer(osg, osg_cnt, digest, digest_size); + if (ret != digest_size) { err(); ret = -EINVAL; goto fail; } - ret = cryptodev_hash_final(&sess->hash, odata->data); - odata->data_size = digest_size; + osg_size = digest_size; cryptodev_hash_deinit(&sess->hash); - if (sess->op != NCR_OP_DIGEST && !sess->algorithm->is_hmac) { + if (sess->algorithm->is_pk) { /* PK signature */ - size_t new_size = odata->max_data_size; - ret = ncr_pk_cipher_sign(&sess->pk, odata->data, odata->data_size, - odata->data, &new_size); + + ret = ncr_pk_cipher_sign(&sess->pk, osg, osg_cnt, osg_size, + osg, osg_cnt, &orig_osg_size); if (ret < 0) { err(); goto fail; } - odata->data_size = new_size; + osg_size = orig_osg_size; } break; default: @@ -701,10 +875,18 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* goto fail; } + if (osg_size > 0) + *udata_size = osg_size; + ret = 0; fail: - if (odata) _ncr_data_item_put(odata); + if (sess->available_pages) { + release_user_pages(sess->pages, sess->available_pages); + sess->available_pages = 0; + } + up(&sess->mem_mutex); + cryptodev_hash_deinit(&sess->hash); if (sess->algorithm->is_symmetric) { cryptodev_cipher_deinit(&sess->cipher); @@ -718,6 +900,93 @@ fail: return ret; } +/* Direct with key: Allows to hash a key */ +/* Called when userspace buffers are used */ +static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op) +{ + int ret; + struct session_item_st* sess; + struct key_item_st* key = NULL; + + sess = ncr_sessions_item_get( &lists->sessions, op->ses); + if (sess == NULL) { + err(); + return -EINVAL; + } + + /* read key */ + ret = ncr_key_item_get_read( &key, &lists->key, op->data.kdata.input); + if (ret < 0) { + err(); + goto fail; + } + + if (key->type != NCR_KEY_TYPE_SECRET) { + err(); + ret = -EINVAL; + goto fail; + } + + switch(sess->op) { + case NCR_OP_ENCRYPT: + case NCR_OP_DECRYPT: + err(); + ret = -EINVAL; + goto fail; + case NCR_OP_SIGN: + case NCR_OP_VERIFY: + ret = _cryptodev_hash_update(&sess->hash, + key->key.secret.data, key->key.secret.size); + if (ret < 0) { + err(); + goto fail; + } + break; + default: + err(); + ret = -EINVAL; + goto fail; + } + + ret = 0; + +fail: + if (key) _ncr_key_item_put(key); + _ncr_sessions_item_put(sess); + + return ret; +} + +int ncr_session_update(struct ncr_lists* lists, void __user* arg) +{ + struct ncr_session_op_st op; + int ret; + + if (unlikely(copy_from_user( &op, arg, sizeof(op)))) { + err(); + return -EFAULT; + } + + if (op.type == NCR_DIRECT_DATA) + ret = _ncr_session_update(lists, &op); + else if (op.type == NCR_KEY_DATA) + ret = _ncr_session_update_key(lists, &op); + else + ret = -EINVAL; + + if (unlikely(ret)) { + err(); + return ret; + } + + if (unlikely(copy_to_user(arg, &op, sizeof(op)))) { + err(); + return -EFAULT; + } + + return 0; +} + int ncr_session_final(struct ncr_lists* lists, void __user* arg) { struct ncr_session_op_st op; @@ -768,4 +1037,3 @@ int ncr_session_once(struct ncr_lists* lists, void __user* arg) return -EFAULT; return 0; } - @@ -30,7 +30,7 @@ #include <linux/cred.h> #include <linux/capability.h> #include "ncr.h" -#include "ncr_int.h" +#include "ncr-int.h" #include <linux/workqueue.h> /* This is the master wrapping key for storage of keys @@ -64,7 +64,6 @@ void* ncr_init_lists(void) void ncr_deinit_lists(struct ncr_lists *lst) { if(lst) { - ncr_data_list_deinit(&lst->data); ncr_key_list_deinit(&lst->key); ncr_sessions_list_deinit(&lst->sessions); kfree(lst); @@ -124,15 +123,6 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp, BUG(); switch (cmd) { - case NCRIO_DATA_INIT: - return ncr_data_init(&lst->data, arg); - case NCRIO_DATA_GET: - return ncr_data_get(&lst->data, arg); - case NCRIO_DATA_SET: - return ncr_data_set(&lst->data, arg); - case NCRIO_DATA_DEINIT: - return ncr_data_deinit(&lst->data, arg); - case NCRIO_KEY_INIT: return ncr_key_init(&lst->key, arg); case NCRIO_KEY_DEINIT: @@ -140,19 +130,19 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp, case NCRIO_KEY_GENERATE: return ncr_key_generate(&lst->key, arg); case NCRIO_KEY_EXPORT: - return ncr_key_export(&lst->data, &lst->key, arg); + return ncr_key_export(&lst->key, arg); case NCRIO_KEY_IMPORT: - return ncr_key_import(&lst->data, &lst->key, arg); + return ncr_key_import(&lst->key, arg); case NCRIO_KEY_GET_INFO: return ncr_key_info(&lst->key, arg); case NCRIO_KEY_WRAP: - return ncr_key_wrap(&lst->key, &lst->data, arg); + return ncr_key_wrap(&lst->key, arg); case NCRIO_KEY_UNWRAP: - return ncr_key_unwrap(&lst->key, &lst->data, arg); + return ncr_key_unwrap(&lst->key, arg); case NCRIO_KEY_STORAGE_WRAP: - return ncr_key_storage_wrap(&lst->key, &lst->data, arg); + return ncr_key_storage_wrap(&lst->key, arg); case NCRIO_KEY_STORAGE_UNWRAP: - return ncr_key_storage_unwrap(&lst->key, &lst->data, arg); + return ncr_key_storage_unwrap(&lst->key, arg); case NCRIO_SESSION_INIT: return ncr_session_init(lst, arg); case NCRIO_SESSION_UPDATE: @@ -161,6 +151,7 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp, return ncr_session_final(lst, arg); case NCRIO_SESSION_ONCE: return ncr_session_once(lst, arg); + case NCRIO_MASTER_KEY_SET: return ncr_master_key_set(arg); case NCRIO_KEY_GENERATE_PAIR: @@ -55,34 +55,6 @@ typedef enum { NCR_KEY_TYPE_PRIVATE=3, } ncr_key_type_t; -/* Data Handling - */ -#define NCR_DATA_FLAG_EXPORTABLE 1 -#define NCR_DATA_FLAG_SIGN_ONLY 2 /* this object can only be used with hash/sign operations */ - -typedef int ncr_data_t; -#define NCR_DATA_INVALID (ncr_data_t)(0) - -struct ncr_data_init_st { - ncr_data_t desc; - size_t max_object_size; - unsigned int flags; - void __user *initial_data; /* can be null */ - size_t initial_data_size; -}; - -struct ncr_data_st { - ncr_data_t desc; - void __user* data; - size_t data_size; /* rw in get */ - unsigned int append_flag; /* only when used with NCRIO_DATA_SET */ -}; - -#define NCRIO_DATA_INIT _IOWR('c', 200, struct ncr_data_init_st) -#define NCRIO_DATA_GET _IOWR('c', 201, struct ncr_data_st) -#define NCRIO_DATA_SET _IOR('c', 202, struct ncr_data_st) -#define NCRIO_DATA_DEINIT _IOR('c', 203, ncr_data_t) - /* Key handling */ @@ -187,7 +159,10 @@ struct ncr_key_info_st { struct ncr_key_data_st { ncr_key_t key; - ncr_data_t data; + + void __user *idata; + size_t idata_size; /* rw in get */ + /* in case of import this will be used as key id */ uint8_t key_id[MAX_KEY_ID_SIZE]; size_t key_id_size; @@ -212,7 +187,7 @@ struct ncr_key_data_st { #define NCRIO_KEY_DEINIT _IOR ('c', 215, ncr_key_t) -/* FIXME key wrap ioctls +/* Key wrap ioctls */ struct ncr_key_wrap_st { ncr_wrap_algorithm_t algorithm; @@ -220,10 +195,12 @@ struct ncr_key_wrap_st { ncr_key_t key; struct ncr_key_params_st params; - ncr_data_t data; /* encrypted keytowrap */ + + void __user * io; /* encrypted keytowrap */ + size_t io_size; /* this will be updated by the actual size on wrap */ }; -#define NCRIO_KEY_WRAP _IOR ('c', 250, struct ncr_key_wrap_st) +#define NCRIO_KEY_WRAP _IOWR ('c', 250, struct ncr_key_wrap_st) #define NCRIO_KEY_UNWRAP _IOR ('c', 251, struct ncr_key_wrap_st) /* Internal ops */ @@ -238,10 +215,12 @@ struct ncr_master_key_st { * fields to be able to recover a key */ struct ncr_key_storage_wrap_st { ncr_key_t keytowrap; - ncr_data_t data; /* encrypted keytowrap */ + + void __user * io; /* encrypted keytowrap */ + size_t io_size; /* this will be updated by the actual size on wrap */ }; -#define NCRIO_KEY_STORAGE_WRAP _IOR ('c', 261, struct ncr_key_storage_wrap_st) +#define NCRIO_KEY_STORAGE_WRAP _IOWR ('c', 261, struct ncr_key_storage_wrap_st) #define NCRIO_KEY_STORAGE_UNWRAP _IOR ('c', 262, struct ncr_key_storage_wrap_st) /* Crypto Operations ioctls @@ -250,7 +229,6 @@ struct ncr_key_storage_wrap_st { typedef enum { NCR_OP_ENCRYPT=1, NCR_OP_DECRYPT, - NCR_OP_DIGEST, NCR_OP_SIGN, NCR_OP_VERIFY, } ncr_crypto_op_t; @@ -277,24 +255,31 @@ typedef enum { NCR_VERIFICATION_FAILED = -2, } ncr_error_t; +typedef enum { + NCR_KEY_DATA, + NCR_DIRECT_DATA, +} ncr_data_type_t; + struct ncr_session_op_st { /* input */ ncr_session_t ses; union { struct { - ncr_data_t plaintext; - ncr_data_t ciphertext; - } cipher; - struct { - ncr_data_t text; - ncr_data_t output; - } sign; /* mac/hash/sign */ + ncr_key_t input; + void __user * output; /* when verifying signature this is + * the place of the signature. + */ + size_t output_size; + } kdata; /* NCR_KEY_DATA */ struct { - ncr_data_t text; - ncr_data_t signature; - } verify; /* mac/sign */ + void __user * input; + size_t input_size; + void __user * output; + size_t output_size; + } udata; /* NCR_DIRECT_DATA */ } data; + ncr_data_type_t type; /* output of verification */ ncr_error_t err; @@ -307,7 +292,7 @@ struct ncr_session_once_op_st { #define NCRIO_SESSION_INIT _IOR ('c', 300, struct ncr_session_st) #define NCRIO_SESSION_UPDATE _IOWR ('c', 301, struct ncr_session_op_st) -#define NCRIO_SESSION_FINAL _IOR ('c', 302, struct ncr_session_op_st) +#define NCRIO_SESSION_FINAL _IOWR ('c', 302, struct ncr_session_op_st) /* everything in one call */ #define NCRIO_SESSION_ONCE _IOWR ('c', 303, struct ncr_session_once_op_st) |