summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README5
-rw-r--r--examples/ncr.c68
-rw-r--r--ncr-key-wrap.c34
-rw-r--r--ncr-key.c109
-rw-r--r--ncr-pk.c105
-rw-r--r--ncr-sessions.c84
-rw-r--r--ncr.h12
-rw-r--r--ncr_int.h36
-rw-r--r--userspace/Makefile13
-rw-r--r--userspace/setkey.c5
10 files changed, 343 insertions, 128 deletions
diff --git a/README b/README
index d32b28a..8e80fcb 100644
--- a/README
+++ b/README
@@ -3,7 +3,10 @@ designed. The ioctl() API is in ncr.h and the userspace in ncrypto.h.
For the new API to fully operate, root must load a system key (constant
per system) using the setkey program. After this stage the new API should
-be fully operational.
+be fully operational. Example:
+$ dd if=/dev/urandom of=/boot/key count=1 bs=16
+$ chmod 600 /boot/key
+$ userspace/ncr-setkey /boot/key
The main concept of the new API is disallow userspace applications
access to cryptographic keys. Operations should be possible (such
diff --git a/examples/ncr.c b/examples/ncr.c
index 3cfc206..cc7b463 100644
--- a/examples/ncr.c
+++ b/examples/ncr.c
@@ -385,7 +385,6 @@ test_ncr_wrap_key(int cfd)
{
int i;
struct ncr_data_init_st dinit;
- struct ncr_key_generate_st kgen;
ncr_key_t key, key2;
struct ncr_key_data_st keydata;
struct ncr_data_st kdata;
@@ -572,7 +571,6 @@ test_ncr_store_wrap_key(int cfd)
{
int i;
struct ncr_data_init_st dinit;
- struct ncr_key_generate_st kgen;
ncr_key_t key2;
struct ncr_key_data_st keydata;
struct ncr_data_st kdata;
@@ -709,29 +707,29 @@ struct aes_vectors_st {
const uint8_t* ciphertext;
} aes_vectors[] = {
{
- .key = "\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .ciphertext = "\x4b\xc3\xf8\x83\x45\x0c\x11\x3c\x64\xca\x42\xe1\x11\x2a\x9e\x87",
+ .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 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .plaintext = "\xf3\x44\x81\xec\x3c\xc6\x27\xba\xcd\x5d\xc3\xfb\x08\xf2\x73\xe6",
- .ciphertext = "\x03\x36\x76\x3e\x96\x6d\x92\x59\x5a\x56\x7c\xc9\xce\x53\x7f\x5e",
+ .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 = "\x10\xa5\x88\x69\xd7\x4b\xe5\xa3\x74\xcf\x86\x7c\xfb\x47\x38\x59",
- .plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .ciphertext = "\x6d\x25\x1e\x69\x44\xb0\x51\xe0\x4e\xaa\x6f\xb4\xdb\xf7\x84\x65",
+ .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 = "\xca\xea\x65\xcd\xbb\x75\xe9\x16\x9e\xcd\x22\xeb\xe6\xe5\x46\x75",
- .plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .ciphertext = "\x6e\x29\x20\x11\x90\x15\x2d\xf4\xee\x05\x81\x39\xde\xf6\x10\xbb",
+ .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 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe",
- .plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .ciphertext = "\x9b\xa4\xa9\x14\x3f\x4e\x5d\x40\x48\x52\x1c\x4f\x88\x77\xd8\x8e",
+ .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",
},
};
@@ -740,7 +738,6 @@ static int
test_ncr_aes(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;
@@ -961,20 +958,20 @@ struct hash_vectors_st {
.name = "SHA1",
.algorithm = NCR_ALG_SHA1,
.key = NULL,
- .plaintext = "what do ya want for nothing?",
+ .plaintext = (uint8_t*)"what do ya want for nothing?",
.plaintext_size = sizeof("what do ya want for nothing?")-1,
- .output = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32",
+ .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,
},
{
.name = "HMAC-MD5",
.algorithm = NCR_ALG_HMAC_MD5,
- .key = "Jefe",
+ .key = (uint8_t*)"Jefe",
.key_size = 4,
- .plaintext = "what do ya want for nothing?",
+ .plaintext = (uint8_t*)"what do ya want for nothing?",
.plaintext_size = sizeof("what do ya want for nothing?")-1,
- .output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
+ .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_MAC,
},
@@ -982,44 +979,44 @@ struct hash_vectors_st {
{
.name = "HMAC-SHA224",
.algorithm = NCR_ALG_HMAC_SHA2_224,
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .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 = "Hi There",
+ .plaintext = (uint8_t*)"Hi There",
.plaintext_size = sizeof("Hi There")-1,
- .output = "\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 = (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_MAC,
},
{
.name = "HMAC-SHA256",
.algorithm = NCR_ALG_HMAC_SHA2_256,
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .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 = "Hi There",
+ .plaintext = (uint8_t*)"Hi There",
.plaintext_size = sizeof("Hi There")-1,
- .output = "\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 = (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_MAC,
},
{
.name = "HMAC-SHA384",
.algorithm = NCR_ALG_HMAC_SHA2_384,
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .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 = "Hi There",
+ .plaintext = (uint8_t*)"Hi There",
.plaintext_size = sizeof("Hi There")-1,
- .output = "\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 = (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_MAC,
},
{
.name = "HMAC-SHA512",
.algorithm = NCR_ALG_HMAC_SHA2_512,
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .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 = "Hi There",
+ .plaintext = (uint8_t*)"Hi There",
.plaintext_size = sizeof("Hi There")-1,
- .output = "\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 = (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_MAC,
},
@@ -1032,7 +1029,6 @@ static int
test_ncr_hash(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;
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c
index 5fda82c..5510436 100644
--- a/ncr-key-wrap.c
+++ b/ncr-key-wrap.c
@@ -428,10 +428,10 @@ int ret;
return ret;
}
- wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
- if (wkey == NULL) {
+ ret = ncr_key_item_get_read( &wkey, key_lst, wrap.keytowrap);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
if (!(wkey->flags & NCR_KEY_FLAG_WRAPPABLE)) {
@@ -439,10 +439,9 @@ int ret;
return -EPERM;
}
- key = ncr_key_item_get( key_lst, wrap.key.key);
- if (key == NULL) {
+ ret = ncr_key_item_get_read( &key, key_lst, wrap.key.key);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
@@ -492,16 +491,15 @@ int ret;
return ret;
}
- wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
- if (wkey == NULL) {
+ ret = ncr_key_item_get_write( &wkey, key_lst, wrap.keytowrap);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
- key = ncr_key_item_get( key_lst, wrap.key.key);
- if (key == NULL) {
+ ret = ncr_key_item_get_read( &key, key_lst, wrap.key.key);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
@@ -554,10 +552,10 @@ int ret;
return ret;
}
- wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
- if (wkey == NULL) {
+ ret = ncr_key_item_get_read( &wkey, key_lst, wrap.keytowrap);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
if (!(wkey->flags & NCR_KEY_FLAG_WRAPPABLE)) {
@@ -613,10 +611,10 @@ int ret;
return ret;
}
- wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
- if (wkey == NULL) {
+ ret = ncr_key_item_get_write( &wkey, key_lst, wrap.keytowrap);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
data = ncr_data_item_get(data_lst, wrap.data);
diff --git a/ncr-key.c b/ncr-key.c
index 20dd6a5..ff5af6c 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -61,21 +61,80 @@ int mx = 1;
}
/* returns the data item corresponding to desc */
-struct key_item_st* ncr_key_item_get( struct list_sem_st* lst, ncr_key_t desc)
+int ncr_key_item_get_read(struct key_item_st**st, struct list_sem_st* lst,
+ ncr_key_t desc)
{
struct key_item_st* item;
+int ret;
+
+ *st = NULL;
+
down(&lst->sem);
list_for_each_entry(item, &lst->list, list) {
if (item->desc == desc) {
atomic_inc(&item->refcnt);
- up(&lst->sem);
- return item;
+
+ if (atomic_read(&item->writer) != 0) {
+ /* writer in place busy */
+ atomic_dec(&item->refcnt);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ *st = item;
+ ret = 0;
+ goto exit;
}
}
+
+ err();
+ ret = -EINVAL;
+exit:
up(&lst->sem);
+ return ret;
+}
+
+/* as above but will never return anything that
+ * is in use.
+ */
+int ncr_key_item_get_write( struct key_item_st** st,
+ struct list_sem_st* lst, ncr_key_t desc)
+{
+struct key_item_st* item;
+int ret;
+
+ *st = NULL;
+
+ down(&lst->sem);
+ list_for_each_entry(item, &lst->list, list) {
+ if (item->desc == desc) {
+ /* do not return items that are in use already */
+
+ if (atomic_add_unless(&item->writer, 1, 1)==0) {
+ /* another writer so busy */
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ if (atomic_add_unless(&item->refcnt, 1, 2)==0) {
+ /* some reader is active so busy */
+ atomic_dec(&item->writer);
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ *st = item;
+ ret = 0;
+ goto exit;
+ }
+ }
err();
- return NULL;
+ ret = -EINVAL;
+
+exit:
+ up(&lst->sem);
+ return ret;
}
void _ncr_key_item_put( struct key_item_st* item)
@@ -85,6 +144,8 @@ void _ncr_key_item_put( struct key_item_st* item)
ncr_key_clear(item);
kfree(item);
}
+ if (atomic_read(&item->writer) > 0)
+ atomic_dec(&item->writer);
}
int ncr_key_init(struct list_sem_st* lst, void __user* arg)
@@ -108,6 +169,7 @@ int ncr_key_init(struct list_sem_st* lst, void __user* arg)
memset(key, 0, sizeof(*key));
atomic_set(&key->refcnt, 1);
+ atomic_set(&key->writer, 0);
down(&lst->sem);
@@ -169,10 +231,10 @@ int ret;
return ret;
}
- item = ncr_key_item_get( key_lst, data.key);
- if (item == NULL) {
+ ret = ncr_key_item_get_read( &item, key_lst, data.key);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
ditem = ncr_data_item_get( data_lst, data.data);
@@ -250,12 +312,12 @@ int ret;
return ret;
}
- item = ncr_key_item_get( key_lst, data.key);
- if (item == NULL) {
+ ret = ncr_key_item_get_write( &item, key_lst, data.key);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
-
+
ditem = ncr_data_item_get( data_lst, data.data);
if (ditem == NULL) {
err();
@@ -331,6 +393,8 @@ static void ncr_key_clear(struct key_item_st* item)
ncr_pk_clear(item);
}
memset(&item->key, 0, sizeof(item->key));
+
+ return;
}
/* Generate a secret key
@@ -348,10 +412,10 @@ size_t size;
return ret;
}
- item = ncr_key_item_get( lst, gen.desc);
- if (item == NULL) {
+ ret = ncr_key_item_get_write( &item, lst, gen.desc);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
ncr_key_clear(item);
@@ -404,10 +468,10 @@ int ret;
return ret;
}
- item = ncr_key_item_get( lst, info.key);
- if (item == NULL) {
+ ret = ncr_key_item_get_read(&item, lst, info.key);
+ if (ret < 0) {
err();
- return -EINVAL;
+ return ret;
}
info.flags = item->flags;
@@ -432,16 +496,15 @@ int ret;
return ret;
}
- private = ncr_key_item_get( lst, gen.desc);
- if (private == NULL) {
+ ret = ncr_key_item_get_write( &private, lst, gen.desc);
+ if (ret < 0) {
err();
- return -EINVAL;
+ goto fail;
}
- public = ncr_key_item_get( lst, gen.desc2);
- if (public == NULL) {
+ ret = ncr_key_item_get_write( &public, lst, gen.desc2);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
diff --git a/ncr-pk.c b/ncr-pk.c
index 6422229..4cfd185 100644
--- a/ncr-pk.c
+++ b/ncr-pk.c
@@ -283,7 +283,6 @@ struct keygen_st st;
return 0;
}
-
int ncr_pk_queue_init(void)
{
pk_wq =
@@ -301,3 +300,107 @@ void ncr_pk_queue_deinit(void)
flush_workqueue(pk_wq);
destroy_workqueue(pk_wq);
}
+
+/* Encryption/Decryption
+ */
+
+void ncr_pk_cipher_deinit(struct ncr_pk_ctx* ctx)
+{
+ ctx->key = NULL;
+}
+
+int ncr_pk_cipher_init(ncr_algorithm_t algo,
+ struct ncr_pk_ctx* ctx, struct ncr_key_params_st* params,
+ struct key_item_st *key)
+{
+ memset(ctx, 0, sizeof(*ctx));
+
+ if (key->algorithm != algo) {
+ err();
+ return -EINVAL;
+ }
+
+ ctx->algorithm = algo;
+ ctx->key = key;
+
+ switch(algo) {
+ case NCR_ALG_RSA:
+ if (params->params.rsa.type == RSA_PKCS1_V1_5)
+ ctx->type = LTC_LTC_PKCS_1_V1_5;
+ else
+ ctx->type = LTC_LTC_PKCS_1_OAEP;
+
+ ctx->hash = params->params.rsa.hash;
+ break;
+ case NCR_ALG_DSA:
+ break;
+ default:
+ err();
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+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 cret;
+unsigned long osize = *output_size;
+
+ switch(ctx->algorithm) {
+ case NCR_ALG_RSA:
+ cret = rsa_encrypt_key_ex( input, input_size, output, &osize,
+ NULL, 0, ctx->hash, ctx->type, &ctx->key->key.pk.rsa);
+
+ if (cret != CRYPT_OK) {
+ err();
+ return tomerr(cret);
+ }
+ *output_size = osize;
+ break;
+ case NCR_ALG_DSA:
+ return -EINVAL;
+ break;
+ default:
+ err();
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+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 cret;
+unsigned long osize = *output_size;
+int stat;
+
+ switch(ctx->algorithm) {
+ case NCR_ALG_RSA:
+ cret = rsa_decrypt_key_ex( input, input_size, output, &osize,
+ NULL, 0, ctx->hash, ctx->type, &stat, &ctx->key->key.pk.rsa);
+
+ if (cret != CRYPT_OK) {
+ err();
+ return tomerr(cret);
+ }
+
+ if (stat==0) {
+ err();
+ return -EINVAL;
+ }
+ *output_size = osize;
+ break;
+ case NCR_ALG_DSA:
+ return -EINVAL;
+ break;
+ default:
+ err();
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/ncr-sessions.c b/ncr-sessions.c
index f8157fb..a461bf1 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -180,7 +180,6 @@ int i = 0;
static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* session)
{
struct session_item_st* ns = NULL;
- struct key_item_st *key = NULL;
int ret;
const char* str;
@@ -202,57 +201,63 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
case NCR_OP_ENCRYPT:
case NCR_OP_DECRYPT:
/* read key */
- key = ncr_key_item_get( &lists->key, session->params.key);
- if (key == NULL) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- if (key->type != NCR_KEY_TYPE_SECRET) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = cryptodev_cipher_init(&ns->ctx, str, key->key.secret.data, key->key.secret.size);
+ ret = ncr_key_item_get_read( &ns->key, &lists->key, session->params.key);
if (ret < 0) {
err();
goto fail;
}
- if (algo_needs_iv(session->algorithm)) {
- if (session->params.params.cipher.iv_size > sizeof(session->params.params.cipher.iv)) {
+ if (ns->key->type == NCR_KEY_TYPE_SECRET) {
+ ret = cryptodev_cipher_init(&ns->ctx.cipher, str,
+ ns->key->key.secret.data, ns->key->key.secret.size);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ if (algo_needs_iv(session->algorithm)) {
+ if (session->params.params.cipher.iv_size > sizeof(session->params.params.cipher.iv)) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+ cryptodev_cipher_set_iv(&ns->ctx.cipher, session->params.params.cipher.iv, session->params.params.cipher.iv_size);
+ }
+ } else if (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC) {
+ ret = ncr_pk_cipher_init(ns->algo, &ns->ctx.pk,
+ &session->params, ns->key);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
- cryptodev_cipher_set_iv(&ns->ctx, session->params.params.cipher.iv, session->params.params.cipher.iv_size);
+ } else {
+ err();
+ ret = -EINVAL;
+ goto fail;
}
break;
case NCR_OP_MAC:
/* read key */
- key = ncr_key_item_get( &lists->key, session->params.key);
- if (key == NULL) {
+ ret = ncr_key_item_get_read( &ns->key, &lists->key, session->params.key);
+ if (ret < 0) {
err();
- ret = -EINVAL;
goto fail;
}
- if (key->type != NCR_KEY_TYPE_SECRET) {
+ if (ns->key->type != NCR_KEY_TYPE_SECRET) {
err();
ret = -EINVAL;
goto fail;
}
- ret = cryptodev_hash_init(&ns->hctx, str, 1, key->key.secret.data, key->key.secret.size);
+ ret = cryptodev_hash_init(&ns->ctx.hash, str, 1, ns->key->key.secret.data, ns->key->key.secret.size);
if (ret < 0) {
err();
goto fail;
}
- ret = cryptodev_hash_reset(&ns->hctx);
+ ret = cryptodev_hash_reset(&ns->ctx.hash);
if (ret < 0) {
err();
goto fail;
@@ -260,13 +265,13 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
break;
case NCR_OP_DIGEST:
- ret = cryptodev_hash_init(&ns->hctx, str, 0, NULL, 0);
+ ret = cryptodev_hash_init(&ns->ctx.hash, str, 0, NULL, 0);
if (ret < 0) {
err();
goto fail;
}
- ret = cryptodev_hash_reset(&ns->hctx);
+ ret = cryptodev_hash_reset(&ns->ctx.hash);
if (ret < 0) {
err();
goto fail;
@@ -283,12 +288,12 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
session->ses = ns->desc;
fail:
- if (key) _ncr_key_item_put(key);
if (ret < 0) {
- if (ns->ctx.init)
- cryptodev_cipher_deinit(&ns->ctx);
- if (ns->hctx.init)
- cryptodev_hash_deinit(&ns->hctx);
+ if (ns->key) _ncr_key_item_put(ns->key);
+ if (ns->ctx.cipher.init)
+ cryptodev_cipher_deinit(&ns->ctx.cipher);
+ if (ns->ctx.hash.init)
+ cryptodev_hash_deinit(&ns->ctx.hash);
_ncr_session_remove(&lists->sessions, ns->desc);
}
@@ -353,7 +358,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
}
/* read key */
- ret = _cryptodev_cipher_encrypt(&sess->ctx, data->data, data->data_size, odata->data, data->data_size);
+ ret = _cryptodev_cipher_encrypt(&sess->ctx.cipher, data->data, data->data_size, odata->data, data->data_size);
if (ret < 0) {
err();
goto fail;
@@ -385,7 +390,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
}
/* read key */
- ret = _cryptodev_cipher_decrypt(&sess->ctx, data->data, data->data_size, odata->data, data->data_size);
+ ret = _cryptodev_cipher_decrypt(&sess->ctx.cipher, data->data, data->data_size, odata->data, data->data_size);
if (ret < 0) {
err();
goto fail;
@@ -405,7 +410,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
goto fail;
}
- ret = _cryptodev_hash_update(&sess->hctx, data->data, data->data_size);
+ ret = _cryptodev_hash_update(&sess->ctx.hash, data->data, data->data_size);
if (ret < 0) {
err();
goto fail;
@@ -451,6 +456,7 @@ static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
list_for_each_entry_safe(item, tmp, &lst->list, list) {
if(item->desc == desc) {
list_del(&item->list);
+ if (item->key) _ncr_key_item_put(item->key);
_ncr_sessions_item_put( item); /* decrement ref count */
break;
}
@@ -463,7 +469,6 @@ static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
{
- struct key_item_st *key = NULL;
int ret;
struct session_item_st* sess;
struct data_item_st* data = NULL;
@@ -484,7 +489,7 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
op->data.cipher.ciphertext != NCR_DATA_INVALID) {
_ncr_session_update(lists, op);
}
- cryptodev_cipher_deinit(&sess->ctx);
+ cryptodev_cipher_deinit(&sess->ctx.cipher);
break;
case NCR_OP_MAC:
case NCR_OP_DIGEST:
@@ -505,10 +510,10 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
ret = -EINVAL;
goto fail;
}
- ret = cryptodev_hash_final(&sess->hctx, odata->data);
+ ret = cryptodev_hash_final(&sess->ctx.hash, odata->data);
odata->data_size = digest_size;
- cryptodev_hash_deinit(&sess->hctx);
+ cryptodev_hash_deinit(&sess->ctx.hash);
break;
default:
err();
@@ -519,7 +524,6 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
ret = 0;
fail:
- if (key) _ncr_key_item_put(key);
if (odata) _ncr_data_item_put(odata);
if (data) _ncr_data_item_put(data);
_ncr_sessions_item_put(sess);
diff --git a/ncr.h b/ncr.h
index 4b4053d..49d32a6 100644
--- a/ncr.h
+++ b/ncr.h
@@ -8,6 +8,7 @@
#define NCR_CIPHER_MAX_BLOCK_LEN 32
#define NCR_CIPHER_MAX_KEY_LEN 64
#define NCR_HASH_MAX_OUTPUT_SIZE 64
+#define NCR_PK_MAX_OBJECT 640
typedef enum {
NCR_ALG_NONE,
@@ -126,6 +127,11 @@ struct ncr_key_generate_st {
struct ncr_key_generate_params_st params;
};
+typedef enum {
+ RSA_PKCS1_V1_5,
+ RSA_PKCS1_OAEP,
+} ncr_rsa_type_t;
+
/* used in derivation/encryption
*/
struct ncr_key_params_st {
@@ -137,9 +143,13 @@ struct ncr_key_params_st {
size_t iv_size;
} cipher;
struct {
- void * peer_public;
+ uint8_t peer_public[NCR_PK_MAX_OBJECT];
size_t peer_public_size;
} dh;
+ struct {
+ ncr_rsa_type_t type;
+ ncr_algorithm_t hash; /* for OAEP */
+ } rsa;
} params;
};
diff --git a/ncr_int.h b/ncr_int.h
index b21f667..49373ca 100644
--- a/ncr_int.h
+++ b/ncr_int.h
@@ -10,13 +10,26 @@
#define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__)
+struct ncr_pk_ctx {
+ ncr_algorithm_t algorithm; /* algorithm */
+ ncr_algorithm_t hash; /* if hash is required is of this type */
+ int type; /* libtomcrypt type */
+
+ struct key_item_st * key;
+};
+
struct session_item_st {
struct list_head list;
ncr_algorithm_t algo;
ncr_crypto_op_t op;
- struct cipher_data ctx;
- struct hash_data hctx;
+ union {
+ struct cipher_data cipher;
+ struct hash_data hash;
+ struct ncr_pk_ctx pk;
+ } ctx;
+
+ struct key_item_st* key;
atomic_t refcnt;
ncr_session_t desc;
@@ -64,6 +77,7 @@ struct key_item_st {
} key;
atomic_t refcnt;
+ atomic_t writer;
/* owner. The one charged with this */
uid_t uid;
@@ -116,7 +130,11 @@ int ncr_key_generate_pair(struct list_sem_st* lst, void __user* arg);
int ncr_key_derive(struct list_sem_st*, void __user* arg);
int ncr_key_get_public(struct list_sem_st* lst, void __user* arg);
-struct key_item_st* ncr_key_item_get( struct list_sem_st* lst, ncr_key_t desc);
+int ncr_key_item_get_read(struct key_item_st**st, struct list_sem_st* lst,
+ ncr_key_t desc);
+/* get key item for writing */
+int ncr_key_item_get_write( struct key_item_st** st,
+ struct list_sem_st* lst, ncr_key_t desc);
void _ncr_key_item_put( struct key_item_st* item);
typedef enum {
@@ -193,4 +211,16 @@ int ncr_pk_unpack( struct key_item_st * key, const void * packed, size_t packed_
int ncr_pk_queue_init(void);
void ncr_pk_queue_deinit(void);
+/* encryption/decryption */
+int ncr_pk_cipher_init(ncr_algorithm_t algo,
+ struct ncr_pk_ctx* ctx, struct ncr_key_params_st* params,
+ struct key_item_st *key);
+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);
+
+
+
#endif
diff --git a/userspace/Makefile b/userspace/Makefile
index 1a95ac7..fddefb3 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -1,9 +1,12 @@
-KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
+CC = gcc
+CFLAGS = -Wall -g -O2
-hostprogs := setkey
-setkey-objs := setkey.o
+progs := ncr-setkey
-all: $(hostprogs)
+all: $(progs)
+
+ncr-setkey: setkey.c
+ $(CC) $(CFLAGS) $< -o $@
clean:
- rm -f *.o *~ setkey
+ rm -f *.o *~ ncr-setkey
diff --git a/userspace/setkey.c b/userspace/setkey.c
index 535773d..d0a2b62 100644
--- a/userspace/setkey.c
+++ b/userspace/setkey.c
@@ -47,6 +47,11 @@ int main(int argc, char** argv)
memset(&key, 0, sizeof(key));
fp = fopen(argv[1], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Cannot read %s\n", argv[1]);
+ exit(1);
+ }
+
size = fread(key.key, 1, sizeof(key.key), fp);
if (size < 16) {
fprintf(stderr, "Illegal key!\n");