diff options
| author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-15 18:56:23 +0200 |
|---|---|---|
| committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-17 20:49:04 +0200 |
| commit | 775307081d84e0ad390943aa64705280035ac17e (patch) | |
| tree | 851a4225098a90cde3f3f55e657673e4a0e87de6 | |
| parent | 50ca531fd57d964d9eb3005e59273c6d26c4f277 (diff) | |
| download | cryptodev-linux-775307081d84e0ad390943aa64705280035ac17e.tar.gz cryptodev-linux-775307081d84e0ad390943aa64705280035ac17e.tar.xz cryptodev-linux-775307081d84e0ad390943aa64705280035ac17e.zip | |
Wrapping/Unwrapping works and tested.
| -rw-r--r-- | examples/new.c | 94 | ||||
| -rw-r--r-- | ncr-key-wrap.c | 66 |
2 files changed, 137 insertions, 23 deletions
diff --git a/examples/new.c b/examples/new.c index 65592c4..6709bb1 100644 --- a/examples/new.c +++ b/examples/new.c @@ -532,6 +532,11 @@ test_ncr_wrap_key(int cfd) } /* now export the unwrapped */ +#if 0 + /* 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 = kdata.desc; @@ -556,7 +561,7 @@ test_ncr_wrap_key(int cfd) fprintf(stderr, "\n"); return 1; } - +#endif @@ -642,10 +647,8 @@ test_ncr_aes(int cfd) keydata.algorithm = NCR_ALG_AES_CBC; keydata.flags = NCR_KEY_FLAG_EXPORTABLE; - keydata.key = key; - keydata.data = dd; - fprintf(stdout, "Tests on AES\n"); + fprintf(stdout, "Tests on AES Encryption\n"); for (i=0;i<sizeof(aes_vectors)/sizeof(aes_vectors[0]);i++) { /* import key */ @@ -660,6 +663,8 @@ test_ncr_aes(int cfd) 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)"); @@ -720,6 +725,84 @@ test_ncr_aes(int cfd) } } + fprintf(stdout, "Tests on AES Decryption\n"); + for (i=0;i<sizeof(aes_vectors)/sizeof(aes_vectors[0]);i++) { + + /* import key */ + kdata.data = (void*)aes_vectors[i].key; + kdata.data_size = 16; + kdata.desc = dd; + 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; + } + + 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; + } + + /* import ciphertext */ + + kdata.data = (void*)aes_vectors[i].ciphertext; + 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; + } + + /* decrypt */ + memset(&nop, 0, sizeof(nop)); + nop.init.algorithm = NCR_ALG_AES_ECB; + nop.init.params.key = key; + nop.init.op = NCR_OP_DECRYPT; + nop.op.data.cipher.ciphertext = dd; + nop.op.data.cipher.plaintext = dd2; + + if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_SESSION_ONCE)"); + return 1; + } + + /* verify */ + kdata.desc = dd2; + kdata.data = data; + kdata.data_size = sizeof(data); + kdata.append_flag = 0; + + 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) { + 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, "%.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"); @@ -738,7 +821,6 @@ main() perror("open(/dev/crypto)"); return 1; } -#if 0 /* Run the test itself */ if (test_ncr_data(fd)) @@ -763,7 +845,7 @@ main() if (test_ncr_aes(fd)) return 1; -#endif + if (test_ncr_wrap_key(fd)) return 1; diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index 74e1f64..b6987af 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -50,7 +50,7 @@ void val64_xor( val64_t * val, uint32_t x) /* Wraps using the RFC3394 way. */ static int wrap_aes(struct key_item_st* tobewrapped, struct key_item_st *kek, - struct data_item_st* output) + struct data_item_st* output, const void* iv, size_t iv_size) { size_t key_size, n; uint8_t *raw_key; @@ -63,6 +63,11 @@ struct cipher_data ctx; err(); return -EINVAL; } + + if (iv_size < sizeof(initA)) { + iv_size = sizeof(initA); + iv = initA; + } ret = cryptodev_cipher_init(&ctx, "ecb(aes)", kek->key.secret.data, kek->key.secret.size); if (ret < 0) { @@ -96,7 +101,7 @@ struct cipher_data ctx; memcpy(R[i], &raw_key[i*8], 8); } - memcpy(A, initA, sizeof(initA)); + memcpy(A, iv, 8); for (i=0;i<6*n;i++) { memcpy(aes_block, A, 8); @@ -128,16 +133,34 @@ cleanup: return ret; } +#if 0 +/* for debugging */ +void print_val64(char* str, val64_t val) +{ + int i; + printk("%s: ",str); + for (i=0;i<8;i++) + printk("%.2x", val[i]); + printk("\n"); + +} +#endif + static int unwrap_aes(struct key_item_st* output, struct key_item_st *kek, - struct data_item_st* wrapped) + struct data_item_st* wrapped, const void* iv, size_t iv_size) { -size_t key_size, n; -uint8_t *raw_key; +size_t wrapped_key_size, n; +uint8_t *wrapped_key; val64_t A; int i, j, ret; uint8_t aes_block[16]; struct cipher_data ctx; + if (iv_size < sizeof(initA)) { + iv_size = sizeof(initA); + iv = initA; + } + ret = cryptodev_cipher_init(&ctx, "ecb(aes)", kek->key.secret.data, kek->key.secret.size); if (ret < 0) { err(); @@ -146,16 +169,16 @@ struct cipher_data ctx; output->type = NCR_KEY_TYPE_SECRET; - raw_key = wrapped->data; - key_size = wrapped->data_size; + wrapped_key = wrapped->data; + wrapped_key_size = wrapped->data_size; - if (key_size % 8 != 0) { + if (wrapped_key_size % 8 != 0) { err(); ret = -EINVAL; goto cleanup; } - n = key_size/8 - 1; + n = wrapped_key_size/8 - 1; if (sizeof(output->key.secret.data) < (n-1)*8) { err(); @@ -166,10 +189,10 @@ struct cipher_data ctx; { val64_t R[n]; - memcpy(A, raw_key, 8); /* A = C[0] */ + memcpy(A, wrapped_key, 8); /* A = C[0] */ for (i=0;i<n;i++) - memcpy(R[i], &raw_key[(i+1)*8], 8); - + memcpy(R[i], &wrapped_key[(i+1)*8], 8); + for (i=(6*n)-1;i>=0;i--) { val64_xor(&A, i+1); @@ -180,22 +203,27 @@ struct cipher_data ctx; aes_block, sizeof(aes_block)); memcpy(A, aes_block, 8); - memcpy(R[0], &aes_block[8], 8); - for (j=1;j<n;j++) + for (j=n-1;j>=1;j--) memcpy(R[j], R[j-1], sizeof(R[j])); + + memcpy(R[0], &aes_block[8], 8); } - if (memcmp(A, initA, sizeof(initA))!= 0) { + + if (memcmp(A, iv, 8)!= 0) { err(); ret = -EINVAL; goto cleanup; } + memset(&output->key, 0, sizeof(output->key)); for (i=0;i<n;i++) { memcpy(&output->key.secret.data[i*8], R[i], sizeof(R[i])); } output->key.secret.size = n*8; + output->flags = NCR_KEY_FLAG_WRAPPABLE; + output->type = NCR_KEY_TYPE_SECRET; } @@ -229,6 +257,7 @@ int ret; return -EPERM; } + /* FIXME: allow alternative IV */ key = ncr_key_item_get( key_lst, wrap.key.key); if (key == NULL) { err(); @@ -247,7 +276,7 @@ int ret; switch(wrap.algorithm) { case NCR_WALG_AES_RFC3394: - ret = wrap_aes(wkey, key, data); + ret = wrap_aes(wkey, key, data, wrap.key.params.cipher.iv, wrap.key.params.cipher.iv_size); break; default: err(); @@ -262,6 +291,9 @@ fail: return ret; } +/* Unwraps keys. All keys unwrapped are not accessible by + * userspace. + */ int ncr_key_unwrap(struct list_sem_st* key_lst, struct list_sem_st* data_lst, void __user* arg) { struct ncr_key_wrap_st wrap; @@ -296,7 +328,7 @@ int ret; switch(wrap.algorithm) { case NCR_WALG_AES_RFC3394: - ret = unwrap_aes(wkey, key, data); + ret = unwrap_aes(wkey, key, data, wrap.key.params.cipher.iv, wrap.key.params.cipher.iv_size); break; default: err(); |
