From fbf2c100fd28ebbe3d49c4b5c99ae279d4a23171 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 17 Jun 2010 10:59:16 +0200 Subject: Fixed key storage wrapping. --- examples/new.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- ncr-key-wrap.c | 58 +++++++++++---------- 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> 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=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;isem); 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(); -- cgit