summaryrefslogtreecommitdiffstats
path: root/userspace/ncrypto_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'userspace/ncrypto_key.c')
-rw-r--r--userspace/ncrypto_key.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/userspace/ncrypto_key.c b/userspace/ncrypto_key.c
new file mode 100644
index 0000000..66bbc96
--- /dev/null
+++ b/userspace/ncrypto_key.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT, INC. AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL RED HAT, INC. OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Red Hat author: Jan Chadima <jchadima@redhat.com>
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <errno.h>
+#include <linux/ncr.h>
+#include "ncrypto.h"
+#include "ncrypto_internal.h"
+
+int
+ncr_key_init(ncr_key_t *key)
+{
+ if ((__ncr_file_descriptor < 0) && (__ncr_global_init() < 0))
+ return -1;
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_INIT, key) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_generate(ncr_key_t key, ncr_key_generate_params_t params)
+{
+ struct ncr_key_generate_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key == NCR_KEY_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.desc = key;
+ if (params)
+ memmove(&io.params, params, sizeof(io.params));
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_GENERATE, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_generate_pair(ncr_key_t key1, ncr_key_t key2, ncr_key_generate_params_t params)
+{
+ struct ncr_key_generate_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key1 == NCR_KEY_INVALID|| key2 == NCR_KEY_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.desc = key1;
+ io.desc2 = key2;
+ if (params)
+ memmove(&io.params, params, sizeof(io.params));
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_GENERATE_PAIR, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_derive(ncr_key_t newkey, unsigned int keyflags, ncr_key_t key, ncr_derive_t derive, ncr_key_params_t params)
+{
+ struct ncr_key_derivation_params_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (newkey == NCR_KEY_INVALID || key == NCR_KEY_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.derive = derive;
+ io.newkey = newkey;
+ io.key = key;
+ io.keyflags = keyflags;
+ if (params)
+ memmove(&io.params, params, sizeof(io.params));
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_DERIVE, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+ncr_key_get_info(struct ncr_key_info_st *dest, ncr_key_t key)
+{
+ if (key == NCR_KEY_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memset(dest, 0, sizeof(*dest));
+ dest->key = key;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_GET_INFO, dest) < 0)
+ return -1;
+
+ return 0;
+}
+
+ncr_algorithm_t
+ncr_key_get_algorithm(ncr_key_t key)
+{
+ struct ncr_key_info_st io;
+
+ if (ncr_key_get_info(&io, key) < 0)
+ return -1;
+ return io.algorithm;
+}
+
+int
+ncr_key_get_flags(ncr_key_t key)
+{
+ struct ncr_key_info_st io;
+
+ if (ncr_key_get_info(&io, key) < 0)
+ return -1;
+ return io.flags;
+}
+
+ncr_key_type_t
+ncr_key_get_type(ncr_key_t key)
+{
+ struct ncr_key_info_st io;
+
+ if (ncr_key_get_info(&io, key) < 0)
+ return -1;
+ return io.type;
+}
+
+int
+ncr_key_get_id(ncr_key_t key, void *id, size_t *id_size)
+{
+ struct ncr_key_info_st io;
+
+ if (ncr_key_get_info(&io, key) < 0)
+ return -1;
+
+ if (io.key_id_size < *id_size)
+ *id_size = io.key_id_size;
+
+ memmove(id, &io.key_id, *id_size);
+
+ return 0;
+}
+
+int
+ncr_key_export(ncr_key_t key, void *idata, size_t idata_size)
+{
+ struct ncr_key_data_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key == NCR_KEY_INVALID || !idata || !idata_size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.key = key;
+ io.idata = idata;
+ io.idata_size = idata_size;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_EXPORT, &io) < 0)
+ return -1;
+
+ return io.idata_size;
+}
+
+int
+ncr_key_import(ncr_key_t key, void *idata, size_t idata_size, void *id, size_t id_size, ncr_algorithm_t algorithm, unsigned int type, unsigned int flags)
+{
+ struct ncr_key_data_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key == NCR_KEY_INVALID || !idata || !idata_size || (!id && id_size != 0) || algorithm == NCR_ALG_NONE) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.key = key;
+ io.idata = idata;
+ io.idata_size = idata_size;
+ if (id_size > MAX_KEY_ID_SIZE) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ memmove(&io.key_id, id, id_size);
+ io.key_id_size = id_size;
+ io.algorithm = algorithm;
+ io.type = type;
+ io.flags = flags;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_IMPORT, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_wrap(ncr_key_t key, ncr_wrap_algorithm_t algorithm, ncr_key_params_t params, ncr_key_t keytowrap, void *idata, size_t idata_size)
+{
+ struct ncr_key_wrap_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key == NCR_KEY_INVALID || keytowrap == NCR_KEY_INVALID || !idata || !idata_size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.key = key;
+ io.algorithm = algorithm;
+ if (params)
+ memmove(&io.params, params, sizeof(io.params));
+ io.keytowrap = keytowrap;
+ io.io = idata;
+ io.io_size = idata_size;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_WRAP, &io) < 0)
+ return -1;
+
+ return io.io_size;
+}
+
+int
+ncr_key_unwrap(ncr_key_t key, ncr_wrap_algorithm_t algorithm, ncr_key_params_t params, ncr_key_t keytowrap, void *idata, size_t idata_size)
+{
+ struct ncr_key_wrap_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (key == NCR_KEY_INVALID || keytowrap == NCR_KEY_INVALID || !idata || !idata_size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.key = key;
+ io.algorithm = algorithm;
+ if (params)
+ memmove(&io.params, params, sizeof(io.params));
+ io.keytowrap = keytowrap;
+ io.io = idata;
+ io.io_size = idata_size;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_UNWRAP, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_storage_wrap(ncr_key_t keytowrap, void *idata, size_t idata_size)
+{
+ struct ncr_key_storage_wrap_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (keytowrap == NCR_KEY_INVALID || !idata || !idata_size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.keytowrap = keytowrap;
+ io.io = idata;
+ io.io_size = idata_size;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_STORAGE_WRAP, &io) < 0)
+ return -1;
+
+ return io.io_size;
+}
+
+int
+ncr_key_storage_unwrap(ncr_key_t keytowrap, void *idata, size_t idata_size)
+{
+ struct ncr_key_storage_wrap_st io;
+ memset(&io, 0, sizeof(io));
+
+ if (keytowrap == NCR_KEY_INVALID|| !idata || !idata_size) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ io.keytowrap = keytowrap;
+ io.io = idata;
+ io.io_size = idata_size;
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_STORAGE_UNWRAP, &io) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ncr_key_deinit(ncr_key_t key)
+{
+ if (key == NCR_KEY_INVALID) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (__ncr_file_descriptor < 0) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (ioctl(__ncr_file_descriptor, NCRIO_KEY_DEINIT, &key) < 0)
+ return -1;
+
+ return 0;
+}
+