summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--cryptodev_cipher.c8
-rw-r--r--cryptodev_int.h16
-rw-r--r--cryptodev_main.c16
-rw-r--r--examples/Makefile2
-rw-r--r--examples/ncr.c657
-rw-r--r--examples/pk.c305
-rw-r--r--examples/speed.c59
-rw-r--r--libtomcrypt/hashes/hash_get_oid.c2
-rw-r--r--libtomcrypt/hashes/hash_memory.c2
-rw-r--r--libtomcrypt/hashes/hash_memory_multi.c2
-rw-r--r--libtomcrypt/pk/pkcs1/pkcs_1_mgf1.c2
-rw-r--r--libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.c2
-rw-r--r--libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.c2
-rw-r--r--libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.c6
-rw-r--r--libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.c6
-rw-r--r--libtomcrypt/pk/rsa/rsa_decrypt_key.c2
-rw-r--r--libtomcrypt/pk/rsa/rsa_encrypt_key.c2
-rw-r--r--libtomcrypt/pk/rsa/rsa_export.c2
-rw-r--r--libtomcrypt/pk/rsa/rsa_sign_hash.c2
-rw-r--r--libtomcrypt/pk/rsa/rsa_verify_hash.c2
-rw-r--r--ncr-data.c301
-rw-r--r--ncr-int.h (renamed from ncr_int.h)71
-rw-r--r--ncr-key-storage.c2
-rw-r--r--ncr-key-wrap.c173
-rw-r--r--ncr-key.c102
-rw-r--r--ncr-limits.c4
-rw-r--r--ncr-pk.c218
-rw-r--r--ncr-pk.h22
-rw-r--r--ncr-sessions.c724
-rw-r--r--ncr.c25
-rw-r--r--ncr.h77
32 files changed, 1258 insertions, 1572 deletions
diff --git a/Makefile b/Makefile
index 0b031d4..41c82c4 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
-}
diff --git a/ncr_int.h b/ncr-int.h
index 506dfa3..03fab19 100644
--- a/ncr_int.h
+++ b/ncr-int.h
@@ -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;
diff --git a/ncr-key.c b/ncr-key.c
index db5d458..9e67b52 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -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 {
diff --git a/ncr-pk.c b/ncr-pk.c
index bfe575d..947eec0 100644
--- a/ncr-pk.c
+++ b/ncr-pk.c
@@ -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;
}
diff --git a/ncr-pk.h b/ncr-pk.h
index 873ee83..fdc5e1c 100644
--- a/ncr-pk.h
+++ b/ncr-pk.h
@@ -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;
}
-
diff --git a/ncr.c b/ncr.c
index 7014a30..1d91456 100644
--- a/ncr.c
+++ b/ncr.c
@@ -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:
diff --git a/ncr.h b/ncr.h
index f6c8f9f..ee6d502 100644
--- a/ncr.h
+++ b/ncr.h
@@ -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)