diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-07-30 23:21:02 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-07-30 23:21:02 +0200 |
commit | 67d0481e51b198cbad2b1d33389fd80e7a87dd46 (patch) | |
tree | 91695a45a1f6ffb9e4ab53d6d6b1c34eb3dc25f2 | |
parent | 517e0cc6199dcca54f8d20ebb90e304d4cc93c43 (diff) | |
parent | af51c84e19753ec0c9de368816a30bcc4fb90c24 (diff) | |
download | cryptodev-linux-67d0481e51b198cbad2b1d33389fd80e7a87dd46.tar.gz cryptodev-linux-67d0481e51b198cbad2b1d33389fd80e7a87dd46.tar.xz cryptodev-linux-67d0481e51b198cbad2b1d33389fd80e7a87dd46.zip |
Merge branch 'master' into replace-lists
Conflicts:
ncr-int.h
ncr-key.c
ncr.c
-rw-r--r-- | AUTHORS | 6 | ||||
-rw-r--r-- | README | 27 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c | 24 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c | 24 | ||||
-rw-r--r-- | ncr-int.h | 2 | ||||
-rw-r--r-- | ncr-key-wrap.c | 180 | ||||
-rw-r--r-- | ncr-key.c | 2 | ||||
-rw-r--r-- | ncr-limits.c | 2 | ||||
-rw-r--r-- | ncr-sessions.c | 11 | ||||
-rw-r--r-- | ncr.c | 7 | ||||
-rw-r--r-- | ncr.h | 3 | ||||
-rw-r--r-- | userspace/setkey.c | 4 |
13 files changed, 172 insertions, 123 deletions
@@ -1,9 +1,10 @@ Michal Ludvig: - Initial implementation for linux 2.6.8 + Initial implementation of OpenBSD's /dev/crypto API for linux 2.6.8 Nikos Mavrogiannopoulos: Port to 2.6.27 and later, better compatibility with OpenBSD (and FreeBSD) cryptodev and maintanance. + Design and implementation of NCR (NewCrypto) API. Michael Weiser: Porting to blkcipher async API. Several hardware drivers @@ -12,5 +13,8 @@ Michael Weiser: Phil Sutter: Implemented a zero copy version of the internal engine. +Miloslav Trmač: + Several optimizations and bugfixes in the NCR API. + Maintained by Nikos Mavrogiannopoulos (nmav [at] gnutls [dot] org) @@ -1,25 +1,30 @@ -This is the linux-cryptodev [newapi] branch. Here a new API is being -designed. The ioctl() API is in ncr.h and the userspace in ncrypto.h. +=== NCR API === + +This is the linux-cryptodev NCR branch. The ioctl() API is in ncr.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 +per system) using the ncr-setkey program. After this stage the new API should 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 -as encryption/decryption/signing/verifying), but raw access to the -keys will not be possible. +access to cryptographic keys. Operations are possible (such as +encryption/decryption/signing/verifying), but raw access to the +keys is not be possible. + + +=== OpenBSD crypto compatibility === + +A compatibility API using OpenBSD's interface via /dev/crypto device driver +is supported. This enables access to kernel space cipher implementations +and hardware accelerators. -The old OpenBSD API via /dev/crypto device driver is still supported. +For questions and suggestions please use the mailing lists at: +http://home.gna.org/cryptodev-linux/lists.html -It was initially written for linux 2.6.8 by Michal Ludvig. Compatibility -fixes for *BSD cryptodev as well as porting to 2.6.27 blkcipher API -by Nikos Mavrogiannopoulos. Initial blkcipher async API porting by -Michael Weiser. Maintained by Nikos Mavrogiannopoulos (nmav [at] gnutls [dot] org) @@ -1,3 +1,6 @@ * ioctl_compat() mode for ncr.h API as it is in cryptodev.h * Put limits to sessions * Export private keys to PKCS #8 format (can it be implemented?) +* Documentation for functions +* Is a writev() like interface needed? +* Implement the NIST DSA generation algorithm. diff --git a/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c index 6c97e96..c0a2e22 100644 --- a/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c +++ b/libtomcrypt/pk/asn1/der/x509/der_decode_subject_public_key_info.c @@ -1,11 +1,25 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis +/* + * New driver for /dev/crypto device (aka CryptoDev) + + * Copyright (c) 2010 Katholieke Universiteit Leuven * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. + * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org> * - * The library is free for all purposes without any express - * guarantee it works. + * This file is part of linux cryptodev. * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tomcrypt.h" /** diff --git a/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c index e37c4b4..4c7e966 100644 --- a/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c +++ b/libtomcrypt/pk/asn1/der/x509/der_encode_subject_public_key_info.c @@ -1,11 +1,25 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis +/* + * New driver for /dev/crypto device (aka CryptoDev) + + * Copyright (c) 2010 Katholieke Universiteit Leuven * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. + * Author: Nikos Mavrogiannopoulos <nmav@gnutls.org> * - * The library is free for all purposes without any express - * guarantee it works. + * This file is part of linux cryptodev. * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tomcrypt.h" @@ -10,6 +10,7 @@ #include <ncr-dh.h> #define KEY_DATA_MAX_SIZE 3*1024 +#define NCR_CIPHER_MAX_KEY_LEN 1024 #define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__) @@ -119,7 +120,6 @@ int ncr_key_generate(struct ncr_lists *lst, void __user* arg); int ncr_key_info(struct ncr_lists *lst, void __user* arg); int ncr_key_generate_pair(struct ncr_lists *lst, void __user* arg); -int ncr_key_derive(struct ncr_lists *lst, void __user* arg); int ncr_key_get_public(struct ncr_lists *lst, void __user* arg); int ncr_key_item_get_read(struct key_item_st**st, struct ncr_lists *lst, diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index b66b731..1a32c5c 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -46,7 +46,7 @@ static void val64_xor( val64_t val, uint32_t x) val[4] ^= (x >> 24) & 0xff; } -static int rfc3394_wrap(val64_t R[], unsigned int n, struct cipher_data* ctx, +static int rfc3394_wrap(val64_t *R, unsigned int n, struct cipher_data* ctx, uint8_t* output, size_t *output_size, const uint8_t iv[8]) { val64_t A; @@ -120,6 +120,7 @@ size_t n; int i, ret; struct cipher_data ctx; uint8_t iv[8]; +val64_t *R = NULL; if (iv_size != 4) { memcpy(iv, RFC5649_IV, 4); @@ -144,33 +145,32 @@ uint8_t iv[8]; return ret; } - { - val64_t *R; + R = kmalloc(n * sizeof (*R), GFP_KERNEL); + if (R == NULL) { + err(); + ret = -ENOMEM; + goto cleanup; + } - R = kmalloc(n * sizeof (*R), GFP_KERNEL); - if (R == NULL) { - err(); - ret = -ENOMEM; - goto cleanup; - } - /* R = P */ - for (i=0;i<kdata_size;i++) { - R[i/8][i%8] = ((uint8_t*)kdata)[i]; - } - for (;i<n*8;i++) { - R[i/8][i%8] = 0; - } - ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); - kfree(R); - if (ret < 0) { - err(); - goto cleanup; - } + /* R = P */ + for (i=0;i<kdata_size;i++) { + R[i/8][i%8] = ((uint8_t*)kdata)[i]; + } + + for (;i<n*8;i++) { + R[i/8][i%8] = 0; + } + + ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); + if (ret < 0) { + err(); + goto cleanup; } ret = 0; cleanup: + kfree(R); cryptodev_cipher_deinit(&ctx); return ret; @@ -184,6 +184,7 @@ int i, ret; struct cipher_data ctx; uint8_t iv[4]; size_t size; +val64_t *R = NULL, A; if (iv_size != 4) { memcpy(iv, RFC5649_IV, 4); @@ -212,49 +213,42 @@ size_t size; goto cleanup; } - { - val64_t *R, A; - - R = kmalloc(n * sizeof (*R), GFP_KERNEL); - if (R == NULL) { - err(); - ret = -ENOMEM; - goto cleanup; - } - ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); - if (ret < 0) { - err(); - kfree(R); - goto cleanup; - } + R = kmalloc(n * sizeof (*R), GFP_KERNEL); + if (R == NULL) { + err(); + ret = -ENOMEM; + goto cleanup; + } - if (memcmp(A, iv, 4)!= 0) { - err(); - kfree(R); - ret = -EINVAL; - goto cleanup; - } + ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); + if (ret < 0) { + err(); + goto cleanup; + } - size = (A[4] << 24) | (A[5] << 16) | (A[6] << 8) | A[7]; - if (size > n*8 || size < (n-1)*8 || *kdata_size < size) { - err(); - kfree(R); - ret = -EINVAL; - goto cleanup; - } + if (memcmp(A, iv, 4)!= 0) { + err(); + ret = -EINVAL; + goto cleanup; + } - memset(kdata, 0, size); - *kdata_size = size; - for (i=0;i<size;i++) { - ((uint8_t*)kdata)[i] = R[i/8][i%8]; - } - kfree(R); + size = (A[4] << 24) | (A[5] << 16) | (A[6] << 8) | A[7]; + if (size > n*8 || size < (n-1)*8 || *kdata_size < size) { + err(); + ret = -EINVAL; + goto cleanup; } + memset(kdata, 0, size); + *kdata_size = size; + for (i=0;i<size;i++) { + ((uint8_t*)kdata)[i] = R[i/8][i%8]; + } ret = 0; cleanup: + kfree(R); cryptodev_cipher_deinit(&ctx); return ret; @@ -293,6 +287,7 @@ size_t key_size, n; uint8_t *raw_key; int i, ret; struct cipher_data ctx; +val64_t *R = NULL; if (tobewrapped->type != NCR_KEY_TYPE_SECRET) { err(); @@ -322,24 +317,28 @@ struct cipher_data ctx; n = key_size/8; - { - val64_t R[(NCR_CIPHER_MAX_KEY_LEN + 7) / 8]; + R = kmalloc(sizeof(*R)*n, GFP_KERNEL); + if (R == NULL) { + err(); + ret = -ENOMEM; + goto cleanup; + } - /* R = P */ - for (i=0;i<n;i++) { - memcpy(R[i], &raw_key[i*8], 8); - } + /* R = P */ + for (i=0;i<n;i++) { + memcpy(R[i], &raw_key[i*8], 8); + } - ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); - if (ret < 0) { - err(); - goto cleanup; - } + ret = rfc3394_wrap( R, n, &ctx, output, output_size, iv); + if (ret < 0) { + err(); + goto cleanup; } ret = 0; cleanup: + kfree(R); cryptodev_cipher_deinit(&ctx); return ret; @@ -365,6 +364,7 @@ size_t n; val64_t A; int i, ret; struct cipher_data ctx; +val64_t * R = NULL; if (iv_size < sizeof(initA)) { iv_size = sizeof(initA); @@ -387,41 +387,43 @@ struct cipher_data ctx; n = wrapped_key_size/8 - 1; - if (sizeof(output->key.secret.data) < (n-1)*8) { + if (NCR_CIPHER_MAX_KEY_LEN < (n-1)*8) { err(); ret = -EINVAL; goto cleanup; } - { - val64_t R[sizeof(output->key.secret.data)/8 + 1]; - - ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); - if (ret < 0) { - err(); - return ret; - } - - if (memcmp(A, iv, 8)!= 0) { - err(); - ret = -EINVAL; - goto cleanup; - } + R = kmalloc(sizeof(*R)*n, GFP_KERNEL); + if (R == NULL) { + err(); + ret = -ENOMEM; + 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; + ret = rfc3394_unwrap(wrapped_key, R, n, A, &ctx); + if (ret < 0) { + err(); + return ret; + } + 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; ret = 0; cleanup: + kfree(R); cryptodev_cipher_deinit(&ctx); return ret; @@ -186,9 +186,9 @@ int ncr_key_init(struct ncr_lists *lst, void __user* arg) _ncr_key_item_put(key); return -ENOMEM; } + desc = key->desc; mutex_unlock(&lst->key_idr_mutex); - desc = key->desc; ret = copy_to_user(arg, &desc, sizeof(desc)); if (unlikely(ret)) { _ncr_key_remove(lst, desc); diff --git a/ncr-limits.c b/ncr-limits.c index 4d36c4f..ff8ff59 100644 --- a/ncr-limits.c +++ b/ncr-limits.c @@ -185,7 +185,7 @@ int ret; size_t i; pitem = kmalloc(sizeof(*pitem), GFP_KERNEL); - if (uitem == NULL) { + if (pitem == NULL) { err(); mutex_unlock(&process_limit_mutex); ret = -ENOMEM; diff --git a/ncr-sessions.c b/ncr-sessions.c index 1f2c251..3109292 100644 --- a/ncr-sessions.c +++ b/ncr-sessions.c @@ -104,7 +104,7 @@ struct session_item_st* ncr_session_new(struct ncr_lists *lst) } init_MUTEX(&sess->mem_mutex); - atomic_set(&sess->refcnt, 1); + atomic_set(&sess->refcnt, 2); /* One for lst->list, one for "sess" */ mutex_lock(&lst->session_idr_mutex); /* idr_pre_get() should preallocate enough, and, due to @@ -223,7 +223,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses ns = ncr_session_new(lists); if (ns == NULL) { err(); - return -EINVAL; + return -ENOMEM; } ns->op = session->op; @@ -257,7 +257,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses if (ns->algorithm->kstr == NULL) { err(); - return -EINVAL; + ret = -EINVAL; + goto fail; } ret = cryptodev_cipher_init(&ns->cipher, ns->algorithm->kstr, @@ -336,7 +337,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params); if (IS_ERR(sign_hash)) { err(); - return PTR_ERR(sign_hash); + ret = PTR_ERR(sign_hash); + goto fail; } if (!sign_hash->can_digest) { @@ -384,6 +386,7 @@ fail: if (ret < 0) { _ncr_session_remove(lists, ns->desc); } + _ncr_sessions_item_put(ns); return ret; } @@ -103,11 +103,14 @@ struct ncr_master_key_st st; dprintk(0, KERN_DEBUG, "Master key was previously initialized.\n"); } + if (unlikely(copy_from_user(master_key.key.secret.data, st.key, st.key_size))) { + err(); + return -EFAULT; + } + dprintk(0, KERN_INFO, "Initializing master key.\n"); master_key.type = NCR_KEY_TYPE_SECRET; - - memcpy(master_key.key.secret.data, st.key, st.key_size); master_key.key.secret.size = st.key_size; return 0; @@ -7,7 +7,6 @@ #endif #define NCR_CIPHER_MAX_BLOCK_LEN 32 -#define NCR_CIPHER_MAX_KEY_LEN 512 #define NCR_HASH_MAX_OUTPUT_SIZE 64 typedef enum { @@ -221,7 +220,7 @@ struct ncr_key_wrap_st { /* Internal ops */ struct ncr_master_key_st { - uint8_t key[NCR_CIPHER_MAX_KEY_LEN]; + uint8_t __user * key; uint16_t key_size; }; diff --git a/userspace/setkey.c b/userspace/setkey.c index d0a2b62..ea9d30e 100644 --- a/userspace/setkey.c +++ b/userspace/setkey.c @@ -25,6 +25,7 @@ int main(int argc, char** argv) struct ncr_master_key_st key; int size, ret; struct stat st; + uint8_t rawkey[32]; if (argc != 2) { fprintf(stderr, "Usage: setkey [filename]\n"); @@ -52,12 +53,13 @@ int main(int argc, char** argv) exit(1); } - size = fread(key.key, 1, sizeof(key.key), fp); + size = fread(rawkey, 1, sizeof(rawkey), fp); if (size < 16) { fprintf(stderr, "Illegal key!\n"); exit(1); } fclose(fp); + key.key = rawkey; key.key_size = size; /* Open the crypto device */ |