diff options
-rw-r--r-- | examples/new.c | 157 | ||||
-rw-r--r-- | ncr-key-wrap.c | 58 | ||||
-rw-r--r-- | ncr-key.c | 3 |
3 files changed, 186 insertions, 32 deletions
diff --git a/examples/new.c b/examples/new.c index 7f223f5..72f1517 100644 --- a/examples/new.c +++ b/examples/new.c @@ -563,7 +563,146 @@ test_ncr_wrap_key(int cfd) } #endif + return 0; + +} + +static int +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; + struct ncr_key_storage_wrap_st kwrap; + uint8_t data[DATA_SIZE]; + int dd; + + fprintf(stdout, "Tests on Key storage:\n"); + + /* test 1: generate a key in userspace import it + * to kernel via data and export it. + */ + + 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; + kdata.append_flag = 0; + + if (ioctl(cfd, NCRIO_DATA_SET, &kdata)) { + 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, &key2)) { + perror("ioctl(NCRIO_KEY_INIT)"); + return 1; + } + + keydata.key_id[0] = 'b'; + keydata.key_id[2] = 'a'; + keydata.key_id_size = 2; + keydata.type = NCR_KEY_TYPE_SECRET; + keydata.algorithm = NCR_ALG_AES_CBC; + keydata.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; + + keydata.key = key2; + 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; + } + + /* now try wrapping key2 using key */ + memset(&kwrap, 0, sizeof(kwrap)); + kwrap.keytowrap = key2; + kwrap.data = dd; + + if (ioctl(cfd, NCRIO_KEY_STORAGE_WRAP, &kwrap)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_STORAGE_WRAP)"); + return 1; + } + + /* test unwrapping */ + fprintf(stdout, "\tKey Storage Unwrap test...\n"); + + /* reset key2 */ + if (ioctl(cfd, NCRIO_KEY_DEINIT, &key2)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_DEINIT)"); + return 1; + } + + if (ioctl(cfd, NCRIO_KEY_INIT, &key2)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_INIT)"); + return 1; + } + + memset(&kwrap, 0, sizeof(kwrap)); + kwrap.keytowrap = key2; + kwrap.data = dd; + + if (ioctl(cfd, NCRIO_KEY_STORAGE_UNWRAP, &kwrap)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_STORAGE_UNWRAP)"); + return 1; + } + + /* now export the unwrapped */ + /* this cannot be performed like that, because unwrap + * always sets keys as unexportable. Maybe we can implement + * a data comparison ioctl(). + */ + memset(&keydata, 0, sizeof(keydata)); + keydata.key = key2; + keydata.data = dd; + + if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_IMPORT)"); + return 1; + } + + 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) { + 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, "%.2x:", data[i]); + fprintf(stderr, "\n"); + return 1; + } + + return 0; } @@ -811,6 +950,7 @@ test_ncr_aes(int cfd) } struct hash_vectors_st { + const char* name; ncr_algorithm_t algorithm; const uint8_t* key; /* if hmac */ int key_size; @@ -821,6 +961,7 @@ struct hash_vectors_st { ncr_crypto_op_t op; } hash_vectors[] = { { + .name = "SHA1", .algorithm = NCR_ALG_SHA1, .key = NULL, .plaintext = "what do ya want for nothing?", @@ -830,6 +971,7 @@ struct hash_vectors_st { .op = NCR_OP_DIGEST, }, { + .name = "HMAC-MD5", .algorithm = NCR_ALG_HMAC_MD5, .key = "Jefe", .key_size = 4, @@ -841,6 +983,7 @@ struct hash_vectors_st { }, /* from rfc4231 */ { + .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_size = 20, @@ -851,6 +994,7 @@ struct hash_vectors_st { .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_size = 20, @@ -861,6 +1005,7 @@ struct hash_vectors_st { .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_size = 20, @@ -871,6 +1016,7 @@ struct hash_vectors_st { .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_size = 20, @@ -882,6 +1028,7 @@ struct hash_vectors_st { }, }; +#define HASH_DATA_SIZE 64 /* SHA1 and other hashes */ static int @@ -893,11 +1040,11 @@ test_ncr_hash(int cfd) struct ncr_key_data_st keydata; struct ncr_data_st kdata; ncr_data_t dd, dd2; - uint8_t data[KEY_DATA_SIZE]; + uint8_t data[HASH_DATA_SIZE]; int i, j; struct ncr_session_once_op_st nop; - dinit.max_object_size = KEY_DATA_SIZE; + dinit.max_object_size = HASH_DATA_SIZE; dinit.flags = NCR_DATA_FLAG_EXPORTABLE; dinit.initial_data = NULL; dinit.initial_data_size = 0; @@ -932,9 +1079,10 @@ test_ncr_hash(int cfd) keydata.flags = NCR_KEY_FLAG_EXPORTABLE; - fprintf(stdout, "Tests on AES Encryption\n"); + 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; @@ -1062,6 +1210,9 @@ main() if (test_ncr_wrap_key(fd)) return 1; + if (test_ncr_store_wrap_key(fd)) + return 1; + /* Close the original descriptor */ if (close(fd)) { perror("close(fd)"); diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index 6f0b013..aa46df0 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -35,12 +35,12 @@ typedef uint8_t val64_t[8]; static const val64_t initA = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6"; -static void val64_xor( val64_t * val, uint32_t x) +static void val64_xor( val64_t val, uint32_t x) { - (*val)[7] ^= x & 0xff; - (*val)[6] ^= (x >> 8) & 0xff; - (*val)[5] ^= (x >> 16) & 0xff; - (*val)[4] ^= (x >> 24) & 0xff; + val[7] ^= x & 0xff; + val[6] ^= (x >> 8) & 0xff; + val[5] ^= (x >> 16) & 0xff; + val[4] ^= (x >> 24) & 0xff; } static int rfc3394_wrap(val64_t R[], unsigned int n, struct cipher_data* ctx, @@ -65,7 +65,7 @@ int i,j; aes_block, sizeof(aes_block)); memcpy(A, aes_block, 8); /* A = MSB64(AES(A^{t-1}|R_{1}^{t-1})) */ - val64_xor(&A, i+1); /* A ^= t */ + val64_xor(A, i+1); /* A ^= t */ for (j=0;j<n-1;j++) memcpy(R[j], R[j+1], sizeof(R[j])); @@ -80,25 +80,25 @@ int i,j; 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(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]; - memcpy(*A, wrapped_key, 8); /* A = C[0] */ + memcpy(A, wrapped_key, 8); /* A = C[0] */ for (i=0;i<n;i++) memcpy(R[i], &wrapped_key[(i+1)*8], 8); for (i=(6*n)-1;i>=0;i--) { val64_xor(A, i+1); - memcpy(aes_block, *A, 8); + memcpy(aes_block, A, 8); memcpy(&aes_block[8], R[n-1], 8); _cryptodev_cipher_decrypt(ctx, aes_block, sizeof(aes_block), aes_block, sizeof(aes_block)); - memcpy(*A, aes_block, 8); + memcpy(A, aes_block, 8); for (j=n-1;j>=1;j--) memcpy(R[j], R[j-1], sizeof(R[j])); @@ -114,7 +114,7 @@ static int _wrap_aes_rfc5649(void* kdata, size_t kdata_size, struct key_item_st* struct data_item_st* output, const void* _iv, size_t iv_size) { size_t n; -int i, j, ret; +int i, ret; struct cipher_data ctx; uint8_t iv[8]; @@ -129,17 +129,16 @@ uint8_t iv[8]; iv[6] = (kdata_size >> 8) & 0xff; iv[7] = (kdata_size) & 0xff; - ret = cryptodev_cipher_init(&ctx, "ecb(aes)", kek->key.secret.data, kek->key.secret.size); - if (ret < 0) { + n = (kdata_size+7)/8; + if (n==1) { /* unimplemented */ err(); - return ret; + return -EINVAL; } - n = (kdata_size+7)/8; - if (n==1) { /* unimplemented */ + ret = cryptodev_cipher_init(&ctx, "ecb(aes)", kek->key.secret.data, kek->key.secret.size); + if (ret < 0) { err(); - ret = -EINVAL; - goto cleanup; + return ret; } { @@ -147,14 +146,11 @@ uint8_t iv[8]; /* R = P */ for (i=0;i<kdata_size;i++) { - j=i/8; - R[j][i] = ((uint8_t*)kdata)[i]; + R[i/8][i%8] = ((uint8_t*)kdata)[i]; } for (;i<n*8;i++) { - j=i/8; - R[j][i] = 0; + R[i/8][i%8] = 0; } - ret = rfc3394_wrap( R, n, &ctx, output, iv); if (ret < 0) { err(); @@ -213,7 +209,7 @@ size_t size; { val64_t R[n], A; - ret = rfc3394_unwrap(wrapped_key, R, n, &A, &ctx); + ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); if (ret < 0) { err(); return ret; @@ -387,7 +383,7 @@ struct cipher_data ctx; { val64_t R[n]; - ret = rfc3394_unwrap(wrapped_key, R, n, &A, &ctx); + ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); if (ret < 0) { err(); return ret; @@ -539,6 +535,11 @@ uint8_t * sdata = NULL; size_t sdata_size = 0; int ret; + if (master_key.type != NCR_KEY_TYPE_SECRET) { + err(); + return ENOKEY; + } + copy_from_user( &wrap, arg, sizeof(wrap)); wkey = ncr_key_item_get( key_lst, wrap.keytowrap); @@ -582,13 +583,18 @@ fail: */ int ncr_key_storage_unwrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) { -struct ncr_key_wrap_st wrap; +struct ncr_key_storage_wrap_st wrap; struct key_item_st* wkey = NULL; struct data_item_st * data = NULL; uint8_t * sdata = NULL; size_t sdata_size = 0; int ret; + if (master_key.type != NCR_KEY_TYPE_SECRET) { + err(); + return ENOKEY; + } + copy_from_user( &wrap, arg, sizeof(wrap)); wkey = ncr_key_item_get( key_lst, wrap.keytowrap); @@ -63,7 +63,6 @@ int mx = 1; struct key_item_st* ncr_key_item_get( struct list_sem_st* lst, ncr_key_t desc) { struct key_item_st* item; - down(&lst->sem); list_for_each_entry(item, &lst->list, list) { if (item->desc == desc) { @@ -98,8 +97,6 @@ int ncr_key_init(struct list_sem_st* lst, void __user* arg) return ret; } - copy_from_user( &desc, arg, sizeof(desc)); - key = kmalloc(sizeof(*key), GFP_KERNEL); if (key == NULL) { err(); |