diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-07-25 22:17:22 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-07-25 22:17:22 +0200 |
commit | 6a2560330da7bc05ccb9bc75e70ce745acba7d6c (patch) | |
tree | 2973ea99e08e08ff9119768ca40be21cfbbcd937 | |
parent | c2dda95767e03af277f4d7dab1334aa10e3ee10f (diff) | |
download | cryptodev-linux-6a2560330da7bc05ccb9bc75e70ce745acba7d6c.tar.gz cryptodev-linux-6a2560330da7bc05ccb9bc75e70ce745acba7d6c.tar.xz cryptodev-linux-6a2560330da7bc05ccb9bc75e70ce745acba7d6c.zip |
No need for ncr-direct. All session operations are being done on keys or on userspace data.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | examples/Makefile | 3 | ||||
-rw-r--r-- | examples/ncr-direct.c | 443 | ||||
-rw-r--r-- | examples/ncr.c | 116 | ||||
-rw-r--r-- | examples/pk.c | 185 | ||||
-rw-r--r-- | ncr-sessions-direct.c | 375 | ||||
-rw-r--r-- | ncr-sessions.c | 412 | ||||
-rw-r--r-- | ncr.h | 9 |
9 files changed, 407 insertions, 1141 deletions
@@ -10,7 +10,6 @@ modules.order examples/cipher examples/hmac examples/ncr -examples/ncr-direct examples/pk examples/speed releases @@ -67,8 +67,8 @@ 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-sessions-direct.o \ + ncr-data.o ncr-key.o ncr-limits.o ncr-pk.o \ + ncr-sessions-direct.o ncr-sessions.o \ ncr-key-wrap.o ncr-key-storage.o $(TOMMATH_OBJECTS) \ $(TOMCRYPT_OBJECTS) diff --git a/examples/Makefile b/examples/Makefile index f482649..ff5381d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -17,9 +17,6 @@ hmac: hmac.c ncr: ncr.c $(CC) $(CFLAGS) $< -o $@ -ncr-direct: ncr-direct.c - $(CC) $(CFLAGS) $< -o $@ - pk: pk.c $(CC) $(CFLAGS) $< -o $@ -L/usr/local/lib -lgnutls diff --git a/examples/ncr-direct.c b/examples/ncr-direct.c deleted file mode 100644 index 0908e2c..0000000 --- a/examples/ncr-direct.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Demo on how to use /dev/crypto device for HMAC. - * - * Placed under public domain. - * - */ -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include "../ncr.h" -#include <stdlib.h> - -#define DATA_SIZE 4096 -#define KEY_DATA_SIZE 16 - - -struct aes_vectors_st { - const uint8_t* key; - const uint8_t* plaintext; - const uint8_t* ciphertext; -} aes_vectors[] = { - { - .key = (uint8_t*)"\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .plaintext = (uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .ciphertext = (uint8_t*)"\x4b\xc3\xf8\x83\x45\x0c\x11\x3c\x64\xca\x42\xe1\x11\x2a\x9e\x87", - }, - { - .key = (uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .plaintext = (uint8_t*)"\xf3\x44\x81\xec\x3c\xc6\x27\xba\xcd\x5d\xc3\xfb\x08\xf2\x73\xe6", - .ciphertext = (uint8_t*)"\x03\x36\x76\x3e\x96\x6d\x92\x59\x5a\x56\x7c\xc9\xce\x53\x7f\x5e", - }, - { - .key = (uint8_t*)"\x10\xa5\x88\x69\xd7\x4b\xe5\xa3\x74\xcf\x86\x7c\xfb\x47\x38\x59", - .plaintext = (uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .ciphertext = (uint8_t*)"\x6d\x25\x1e\x69\x44\xb0\x51\xe0\x4e\xaa\x6f\xb4\xdb\xf7\x84\x65", - }, - { - .key = (uint8_t*)"\xca\xea\x65\xcd\xbb\x75\xe9\x16\x9e\xcd\x22\xeb\xe6\xe5\x46\x75", - .plaintext = (uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .ciphertext = (uint8_t*)"\x6e\x29\x20\x11\x90\x15\x2d\xf4\xee\x05\x81\x39\xde\xf6\x10\xbb", - }, - { - .key = (uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe", - .plaintext = (uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - .ciphertext = (uint8_t*)"\x9b\xa4\xa9\x14\x3f\x4e\x5d\x40\x48\x52\x1c\x4f\x88\x77\xd8\x8e", - }, -}; - -/* AES cipher */ -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; - - /* 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 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; - if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_IMPORT)"); - 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.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__); - perror("ioctl(NCRIO_SESSION_ONCE)"); - return 1; - } - - /* verify */ - - if (nop.op.data.udata.output_size != 16 || memcmp(data, aes_vectors[i].ciphertext, 16) != 0) { - fprintf(stderr, "AES test vector %d failed!\n", i); - - fprintf(stderr, "Cipher[%d]: ", (int)nop.op.data.udata.output_size); - for(j=0;j<nop.op.data.udata.output_size;j++) - fprintf(stderr, "%.2x:", (int)data[j]); - fprintf(stderr, "\n"); - - fprintf(stderr, "Expected[%d]: ", 16); - for(j=0;j<16;j++) - fprintf(stderr, "%.2x:", (int)aes_vectors[i].ciphertext[j]); - fprintf(stderr, "\n"); - return 1; - } - } - - 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; - if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_IMPORT)"); - 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.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; - } - - if (nop.op.data.udata.output_size != 16 || memcmp(data, aes_vectors[i].plaintext, 16) != 0) { - fprintf(stderr, "AES test vector %d failed!\n", i); - - fprintf(stderr, "Plain[%d]: ", (int)nop.op.data.udata.output_size); - for(j=0;j<nop.op.data.udata.output_size;j++) - fprintf(stderr, "%.2x:", (int)data[j]); - fprintf(stderr, "\n"); - - fprintf(stderr, "Expected[%d]: ", 16); - for(j=0;j<16;j++) - fprintf(stderr, "%.2x:", (int)aes_vectors[i].plaintext[j]); - fprintf(stderr, "\n"); - return 1; - } - } - - - fprintf(stdout, "\n"); - - return 0; - -} - -struct hash_vectors_st { - const char* name; - ncr_algorithm_t algorithm; - const uint8_t* key; /* if hmac */ - int key_size; - const uint8_t* plaintext; - int plaintext_size; - const uint8_t* output; - int output_size; - ncr_crypto_op_t op; -} hash_vectors[] = { - { - .name = "SHA1", - .algorithm = NCR_ALG_SHA1, - .key = NULL, - .plaintext = (uint8_t*)"what do ya want for nothing?", - .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_SIGN, - }, - { - .name = "HMAC-MD5", - .algorithm = NCR_ALG_HMAC_MD5, - .key = (uint8_t*)"Jefe", - .key_size = 4, - .plaintext = (uint8_t*)"what do ya want for nothing?", - .plaintext_size = sizeof("what do ya want for nothing?")-1, - .output = (uint8_t*)"\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38", - .output_size = 16, - .op = NCR_OP_SIGN, - }, - /* from rfc4231 */ - { - .name = "HMAC-SHA224", - .algorithm = NCR_ALG_HMAC_SHA2_224, - .key = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - .key_size = 20, - .plaintext = (uint8_t*)"Hi There", - .plaintext_size = sizeof("Hi There")-1, - .output = (uint8_t*)"\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22", - .output_size = 28, - .op = NCR_OP_SIGN, - }, - { - .name = "HMAC-SHA256", - .algorithm = NCR_ALG_HMAC_SHA2_256, - .key = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - .key_size = 20, - .plaintext = (uint8_t*)"Hi There", - .plaintext_size = sizeof("Hi There")-1, - .output = (uint8_t*)"\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7", - .output_size = 32, - .op = NCR_OP_SIGN, - }, - { - .name = "HMAC-SHA384", - .algorithm = NCR_ALG_HMAC_SHA2_384, - .key = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - .key_size = 20, - .plaintext = (uint8_t*)"Hi There", - .plaintext_size = sizeof("Hi There")-1, - .output = (uint8_t*)"\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6", - .output_size = 48, - .op = NCR_OP_SIGN, - }, - { - .name = "HMAC-SHA512", - .algorithm = NCR_ALG_HMAC_SHA2_512, - .key = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - .key_size = 20, - .plaintext = (uint8_t*)"Hi There", - .plaintext_size = sizeof("Hi There")-1, - .output = (uint8_t*)"\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54", - .output_size = 64, - .op = NCR_OP_SIGN, - }, -}; - -#define HASH_DATA_SIZE 64 - -/* SHA1 and other hashes */ -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; - 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)"); - 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\n"); - for (i=0;i<sizeof(hash_vectors)/sizeof(hash_vectors[0]);i++) { - - 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; - if (ioctl(cfd, NCRIO_KEY_IMPORT, &keydata)) { - fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); - perror("ioctl(NCRIO_KEY_IMPORT)"); - return 1; - } - } - - /* encrypt */ - memset(&nop, 0, sizeof(nop)); - nop.init.algorithm = hash_vectors[i].algorithm; - if (hash_vectors[i].key != NULL) - nop.init.key = key; - nop.init.op = hash_vectors[i].op; - 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; - } - - if (nop.op.data.udata.output_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)nop.op.data.udata.output_size); - for(j=0;j<nop.op.data.udata.output_size;j++) - fprintf(stderr, "%.2x:", (int)data[j]); - fprintf(stderr, "\n"); - - fprintf(stderr, "Expected[%d]: ", hash_vectors[i].output_size); - for(j=0;j<hash_vectors[i].output_size;j++) - fprintf(stderr, "%.2x:", (int)hash_vectors[i].output[j]); - fprintf(stderr, "\n"); - return 1; - } - } - - 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_aes(fd)) - return 1; - - if (test_ncr_hash(fd)) - return 1; - - /* Close the original descriptor */ - if (close(fd)) { - perror("close(fd)"); - return 1; - } - - return 0; -} diff --git a/examples/ncr.c b/examples/ncr.c index be3dec9..f2c4b72 100644 --- a/examples/ncr.c +++ b/examples/ncr.c @@ -734,6 +734,7 @@ test_ncr_aes(int cfd) uint8_t data[KEY_DATA_SIZE]; int i, j; struct ncr_session_once_op_st nop; + int data_size; dinit.max_object_size = KEY_DATA_SIZE; dinit.flags = NCR_DATA_FLAG_EXPORTABLE; @@ -791,26 +792,17 @@ test_ncr_aes(int cfd) 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.ndata.input = dd; - nop.op.data.ndata.output = dd2; - nop.op.type = NCR_DATA; + 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 +810,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"); @@ -867,49 +851,31 @@ test_ncr_aes(int cfd) 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.ndata.input = dd; - nop.op.data.ndata.output = dd2; - nop.op.type = NCR_DATA; + 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"); @@ -1019,7 +985,7 @@ test_ncr_hash(int cfd) 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; @@ -1081,17 +1047,6 @@ test_ncr_hash(int cfd) 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)); @@ -1099,34 +1054,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.ndata.input = dd; - nop.op.data.ndata.output = dd2; - nop.op.type = NCR_DATA; + 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"); diff --git a/examples/pk.c b/examples/pk.c index 287e9f3..a529e9a 100644 --- a/examples/pk.c +++ b/examples/pk.c @@ -297,35 +297,14 @@ 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); @@ -333,33 +312,6 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae 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; - /* do encryption */ memset(&nop, 0, sizeof(nop)); nop.init.algorithm = NCR_ALG_RSA; @@ -371,15 +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.ndata.input = datad; - nop.op.data.ndata.output = encd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = RSA_ENCRYPT_SIZE; + nop.op.data.udata.output = vdata; + nop.op.data.udata.output_size = sizeof(vdata); + 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)); @@ -392,9 +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.ndata.input = encd; - nop.op.data.ndata.output = encd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = vdata; + nop.op.data.udata.input_size = enc_size; + nop.op.data.udata.output = vdata; + nop.op.data.udata.output_size = sizeof(vdata); + nop.op.type = NCR_DIRECT_DATA; + if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); @@ -402,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"); @@ -422,44 +375,16 @@ static int rsa_key_encrypt(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int oae 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; @@ -468,15 +393,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.ndata.input = datad; - nop.op.data.ndata.output = signd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = sizeof(data); + 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)); @@ -486,9 +415,11 @@ 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_VERIFY; - nop.op.data.ndata.input = datad; - nop.op.data.ndata.output = signd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = sizeof(data); + 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__); @@ -496,7 +427,10 @@ 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 0; @@ -504,44 +438,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; @@ -549,15 +455,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.ndata.input = datad; - nop.op.data.ndata.output = signd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = sizeof(data); + 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)); @@ -566,9 +476,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.ndata.input = datad; - nop.op.data.ndata.output = signd; - nop.op.type = NCR_DATA; + nop.op.data.udata.input = data; + nop.op.data.udata.input_size = sizeof(data); + 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__); @@ -576,7 +488,10 @@ 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 0; diff --git a/ncr-sessions-direct.c b/ncr-sessions-direct.c index 97d5ad7..3d41f12 100644 --- a/ncr-sessions-direct.c +++ b/ncr-sessions-direct.c @@ -27,379 +27,4 @@ #include <linux/scatterlist.h> #include <ncr-sessions.h> -/* Only the output buffer is given as scatterlist */ -static int get_userbuf1(struct session_item_st* ses, - struct ncr_session_op_st* op, struct scatterlist **dst_sg, unsigned *dst_cnt) -{ - int pagecount = 0; - - if (op->data.udata.output == NULL) { - return -EINVAL; - } - - pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size); - - - ses->available_pages = 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.output, op->data.udata.output_size, 1, - pagecount, ses->pages, ses->sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); - return -EINVAL; - } - (*dst_sg) = ses->sg; - *dst_cnt = 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; - - if (op->data.udata.input == NULL) { - return -EINVAL; - } - - src_pagecount = PAGECOUNT(op->data.udata.input, op->data.udata.input_size); - - if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */ - if (op->data.udata.output != NULL) { - dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size); - write_src = 0; - } else { - dst_pagecount = 0; - } - } - - ses->available_pages = 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, op->data.udata.input_size, write_src, - src_pagecount, ses->pages, ses->sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); - return -EINVAL; - } - (*src_sg) = 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)) { - dprintk(1, KERN_ERR, "failed to get user pages for data output\n"); - 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; - } - } - - return 0; -} - -/* Called when userspace buffers are used */ -int _ncr_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op) -{ - int ret; - struct session_item_st* sess; - 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) { - err(); - 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: - if (osg == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - - ret = _ncr_session_encrypt(sess, isg, isg_cnt, isg_size, - osg, osg_cnt, &osg_size); - if (ret < 0) { - err(); - goto fail; - } - op->data.udata.output_size = osg_size; - - break; - case NCR_OP_DECRYPT: - if (osg == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - - if (osg_size < isg_size) { - err(); - ret = -EINVAL; - goto fail; - } - - ret = _ncr_session_decrypt(sess, isg, isg_cnt, isg_size, - osg, osg_cnt, &osg_size); - if (ret < 0) { - err(); - goto fail; - } - op->data.udata.output_size = osg_size; - - break; - - case NCR_OP_SIGN: - case NCR_OP_VERIFY: - ret = cryptodev_hash_update(&sess->hash, isg, isg_size); - if (ret < 0) { - err(); - goto fail; - } - break; - default: - err(); - ret = -EINVAL; - goto fail; - } - - ret = 0; - -fail: - 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; -} - -static int try_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op) -{ - if (op->data.udata.input != NULL) { - return _ncr_session_direct_update(lists, op); - } - - return 0; -} - -int _ncr_session_direct_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; - - sess = ncr_sessions_item_get( &lists->sessions, op->ses); - if (sess == NULL) { - err(); - return -EINVAL; - } - - ret = try_session_direct_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; - } - - switch(sess->op) { - case NCR_OP_ENCRYPT: - case NCR_OP_DECRYPT: - break; - case NCR_OP_VERIFY: - ret = get_userbuf1(sess, op, &osg, &osg_cnt); - if (ret < 0) { - err(); - goto fail; - } - orig_osg_size = osg_size = op->data.udata.output_size; - - digest_size = sess->hash.digestsize; - if (digest_size == 0 || sizeof(digest) < digest_size) { - err(); - ret = -EINVAL; - goto fail; - } - ret = cryptodev_hash_final(&sess->hash, digest); - if (ret < 0) { - err(); - goto fail; - } - - if (sess->algorithm->is_hmac) { - ret = sg_copy_to_buffer(osg, osg_cnt, vdigest, digest_size); - if (ret != digest_size) { - err(); - ret = -EINVAL; - goto fail; - } - - if (digest_size != odata->data_size || - memcmp(vdigest, digest, digest_size) != 0) { - - op->err = NCR_VERIFICATION_FAILED; - } else { - op->err = NCR_SUCCESS; - } - } else { - /* PK signature */ - ret = ncr_pk_cipher_verify(&sess->pk, osg, osg_cnt, osg_size, - digest, digest_size, &op->err); - if (ret < 0) { - err(); - goto fail; - } - } - break; - - case NCR_OP_SIGN: - ret = get_userbuf1(sess, op, &osg, &osg_cnt); - if (ret < 0) { - err(); - goto fail; - } - orig_osg_size = osg_size = op->data.udata.output_size; - - digest_size = sess->hash.digestsize; - if (digest_size == 0 || osg_size < digest_size) { - err(); - ret = -EINVAL; - goto fail; - } - - 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; - } - osg_size = digest_size; - - cryptodev_hash_deinit(&sess->hash); - - if (sess->algorithm->is_pk) { - /* PK signature */ - - ret = ncr_pk_cipher_sign(&sess->pk, osg, osg_cnt, osg_size, - osg, osg_cnt, &orig_osg_size); - if (ret < 0) { - err(); - goto fail; - } - osg_size = orig_osg_size; - } - break; - default: - err(); - ret = -EINVAL; - goto fail; - } - - if (osg_size > 0) - op->data.udata.output_size = osg_size; - - ret = 0; - -fail: - 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); - } else { - ncr_pk_cipher_deinit(&sess->pk); - } - - _ncr_sessions_item_put(sess); - _ncr_session_remove(&lists->sessions, op->ses); - - return ret; -} - diff --git a/ncr-sessions.c b/ncr-sessions.c index 3202e69..f0aebc5 100644 --- a/ncr-sessions.c +++ b/ncr-sessions.c @@ -27,6 +27,8 @@ #include <linux/scatterlist.h> #include <ncr-sessions.h> +static int _ncr_session_direct_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op); + void ncr_sessions_list_deinit(struct list_sem_st* lst) { if(lst) { @@ -468,15 +470,147 @@ int ret; return 0; } -/* Main update function - */ -static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op) +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, + struct ncr_session_op_st* op, struct scatterlist **dst_sg, unsigned *dst_cnt) +{ + int pagecount = 0; + + if (op->data.udata.output == NULL) { + return -EINVAL; + } + + pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size); + + + ses->available_pages = 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.output, op->data.udata.output_size, 1, + pagecount, ses->pages, ses->sg)) { + dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); + return -EINVAL; + } + (*dst_sg) = ses->sg; + *dst_cnt = 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; + + if (op->data.udata.input == NULL) { + return -EINVAL; + } + + src_pagecount = PAGECOUNT(op->data.udata.input, op->data.udata.input_size); + + if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */ + if (op->data.udata.output != NULL) { + dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size); + write_src = 0; + } else { + dst_pagecount = 0; + } + } + + ses->available_pages = 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, op->data.udata.input_size, write_src, + src_pagecount, ses->pages, ses->sg)) { + dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); + return -EINVAL; + } + (*src_sg) = 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)) { + dprintk(1, KERN_ERR, "failed to get user pages for data output\n"); + 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; + } + } + + return 0; +} + +/* Called when userspace buffers are used */ +int _ncr_session_direct_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; - size_t new_size; + 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) { @@ -484,65 +618,63 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st return -EINVAL; } - /* obtain data item */ - data = ncr_data_item_get( &lists->data, op->data.ndata.input); - if (data == NULL) { + 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(); - ret = -EINVAL; goto fail; } + isg_size = op->data.udata.input_size; + osg_size = op->data.udata.output_size; switch(sess->op) { case NCR_OP_ENCRYPT: - odata = ncr_data_item_get( &lists->data, op->data.ndata.output); - if (odata == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - - if (odata->max_data_size < data->data_size) { + if (osg == NULL) { err(); ret = -EINVAL; goto fail; } - odata->data_size = odata->max_data_size; - ret = _ncr_session_encrypt(sess, &data->sg, 1, data->data_size, - &odata->sg, 1, &odata->data_size); + ret = _ncr_session_encrypt(sess, isg, isg_cnt, isg_size, + osg, osg_cnt, &osg_size); if (ret < 0) { err(); goto fail; } + op->data.udata.output_size = osg_size; + break; case NCR_OP_DECRYPT: - odata = ncr_data_item_get( &lists->data, op->data.ndata.output); - if (odata == NULL) { + if (osg == NULL) { err(); ret = -EINVAL; goto fail; } - if (odata->max_data_size < data->data_size) { + if (osg_size < isg_size) { err(); ret = -EINVAL; goto fail; } - new_size = odata->max_data_size; - ret = _ncr_session_decrypt(sess, &data->sg, 1, data->data_size, - &odata->sg, 1, &new_size); + ret = _ncr_session_decrypt(sess, isg, isg_cnt, isg_size, + osg, osg_cnt, &osg_size); if (ret < 0) { err(); goto fail; } - odata->data_size = new_size; + op->data.udata.output_size = osg_size; break; case NCR_OP_SIGN: case NCR_OP_VERIFY: - ret = cryptodev_hash_update(&sess->hash, &data->sg, data->data_size); + ret = cryptodev_hash_update(&sess->hash, isg, isg_size); if (ret < 0) { err(); goto fail; @@ -557,48 +689,41 @@ 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; } -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; -} - -static int try_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op) +static int try_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op) { - if (op->data.ndata.input != NCR_DATA_INVALID) { - return _ncr_session_update(lists, op); + if (op->type == NCR_KEY_DATA) { + if (op->data.kdata.input != NCR_KEY_INVALID) + return _ncr_session_direct_update_key(lists, op); + } else if (op->type == NCR_DIRECT_DATA) { + if (op->data.udata.input != NULL) + return _ncr_session_direct_update(lists, op); } return 0; } -static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op) +int _ncr_session_direct_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; sess = ncr_sessions_item_get( &lists->sessions, op->ses); if (sess == NULL) { @@ -606,18 +731,31 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* return -EINVAL; } - ret = try_session_update(lists, op); + ret = try_session_direct_update(lists, op); if (ret < 0) { err(); - goto fail; + _ncr_sessions_item_put(sess); + return ret; + } + + if (down_interruptible(&sess->mem_mutex)) { + err(); + _ncr_sessions_item_put(sess); + return -ERESTARTSYS; } switch(sess->op) { case NCR_OP_ENCRYPT: case NCR_OP_DECRYPT: break; - case NCR_OP_VERIFY: + ret = get_userbuf1(sess, op, &osg, &osg_cnt); + if (ret < 0) { + err(); + goto fail; + } + orig_osg_size = osg_size = op->data.udata.output_size; + digest_size = sess->hash.digestsize; if (digest_size == 0 || sizeof(digest) < digest_size) { err(); @@ -630,16 +768,16 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* goto fail; } - odata = ncr_data_item_get( &lists->data, op->data.ndata.output); - if (odata == NULL) { - err(); - ret = -EINVAL; - goto fail; - } - if (sess->algorithm->is_hmac) { + ret = sg_copy_to_buffer(osg, osg_cnt, vdigest, digest_size); + if (ret != digest_size) { + err(); + ret = -EINVAL; + goto fail; + } + if (digest_size != odata->data_size || - memcmp(odata->data, digest, digest_size) != 0) { + memcmp(vdigest, digest, digest_size) != 0) { op->err = NCR_VERIFICATION_FAILED; } else { @@ -647,7 +785,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->sg, 1, odata->data_size, + ret = ncr_pk_cipher_verify(&sess->pk, osg, osg_cnt, osg_size, digest, digest_size, &op->err); if (ret < 0) { err(); @@ -657,34 +795,46 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* break; case NCR_OP_SIGN: - odata = ncr_data_item_get( &lists->data, op->data.ndata.output); - if (odata == NULL) { + ret = get_userbuf1(sess, op, &osg, &osg_cnt); + if (ret < 0) { err(); - ret = -EINVAL; goto fail; } + orig_osg_size = osg_size = op->data.udata.output_size; digest_size = sess->hash.digestsize; - if (digest_size == 0 || odata->max_data_size < digest_size) { + if (digest_size == 0 || osg_size < digest_size) { + err(); + ret = -EINVAL; + goto fail; + } + + 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->algorithm->is_pk) { /* PK signature */ - size_t new_size = odata->max_data_size; - ret = ncr_pk_cipher_sign(&sess->pk, &odata->sg, 1, odata->data_size, - &odata->sg, 1, &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: @@ -693,10 +843,18 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* goto fail; } + if (osg_size > 0) + op->data.udata.output_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); @@ -710,6 +868,85 @@ fail: return ret; } +/* Direct with key: Allows to hash a key */ +/* Called when userspace buffers are used */ +static int _ncr_session_direct_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; + struct scatterlist *osg; + unsigned osg_cnt=0; + size_t osg_size; + + 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; + } + + if (down_interruptible(&sess->mem_mutex)) { + err(); + _ncr_sessions_item_put(sess); + return -ERESTARTSYS; + } + + ret = get_userbuf1(sess, op, &osg, &osg_cnt); + if (ret < 0) { + err(); + goto fail; + } + + osg_size = op->data.kdata.output_size; + + 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 (sess->available_pages) { + release_user_pages(sess->pages, sess->available_pages); + sess->available_pages = 0; + } + up(&sess->mem_mutex); + 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; @@ -722,8 +959,8 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg) if (op.type == NCR_DIRECT_DATA) ret = _ncr_session_direct_update(lists, &op); - else if (op.type == NCR_DATA) - ret = _ncr_session_update(lists, &op); + else if (op.type == NCR_KEY_DATA) + ret = _ncr_session_direct_update_key(lists, &op); else ret = -EINVAL; @@ -750,14 +987,7 @@ int ncr_session_final(struct ncr_lists* lists, void __user* arg) return -EFAULT; } - if (op.type == NCR_DATA) { - ret = _ncr_session_final(lists, &op); - } else if (op.type == NCR_DIRECT_DATA) { - ret = _ncr_session_direct_final(lists, &op); - } else { - ret = -EINVAL; - } - + ret = _ncr_session_direct_final(lists, &op); if (unlikely(ret)) { err(); return ret; @@ -787,13 +1017,7 @@ int ncr_session_once(struct ncr_lists* lists, void __user* arg) } kop.op.ses = kop.init.ses; - if (kop.op.type == NCR_DIRECT_DATA) - ret = _ncr_session_direct_final(lists, &kop.op); - else if (kop.op.type == NCR_DATA) - ret = _ncr_session_final(lists, &kop.op); - else - ret = -EINVAL; - + ret = _ncr_session_direct_final(lists, &kop.op); if (ret < 0) { err(); return ret; @@ -281,7 +281,7 @@ typedef enum { } ncr_error_t; typedef enum { - NCR_DATA, + NCR_KEY_DATA, NCR_DIRECT_DATA, } ncr_data_type_t; @@ -291,11 +291,12 @@ struct ncr_session_op_st { union { struct { - ncr_data_t input; - ncr_data_t output; /* when verifying signature this is + ncr_key_t input; + void* output; /* when verifying signature this is * the place of the signature. */ - } ndata; + size_t output_size; + } kdata; struct { void* input; size_t input_size; |