All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Cipher infrastructure
@ 2015-02-06 12:39 Tomasz Bursztyka
  2015-02-06 12:39 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-02-06 12:39 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 823 bytes --]

Hi,

Looks like we need to re-inject the keys to the master socket (the one which
is binded so the selected crypto) once before an operation type, so first encrypt
and/or first decrypt.
Now it seems to work. Should it handle an initialization vector?

Tomasz Bursztyka (2):
  cipher: Add a basic infrastructure for kernel based cipher operations
  unit: Add unit test for the cipher infrastructure

 Makefile.am        |  11 ++-
 ell/cipher.c       | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ell/cipher.h       |  52 +++++++++++++
 ell/ell.h          |   1 +
 unit/test-cipher.c | 107 ++++++++++++++++++++++++++
 5 files changed, 389 insertions(+), 3 deletions(-)
 create mode 100644 ell/cipher.c
 create mode 100644 ell/cipher.h
 create mode 100644 unit/test-cipher.c

-- 
2.0.5


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations
  2015-02-06 12:39 [PATCH v2 0/2] Cipher infrastructure Tomasz Bursztyka
@ 2015-02-06 12:39 ` Tomasz Bursztyka
  2015-02-06 12:39 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
  2015-02-09 15:40 ` [PATCH v2 0/2] Cipher infrastructure Denis Kenzior
  2 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-02-06 12:39 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 8314 bytes --]

This will let the possibility to use the crypto API provided by the
kernel in a simple manner. However, it's worth noticing such API might
not be relevant if a lot of big frames need to processed, where it will
be better to get non blocking sockets as well as lowering the memory
copies via vmsplice/splice.
---
 Makefile.am  |   6 +-
 ell/cipher.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ell/cipher.h |  52 ++++++++++++++
 ell/ell.h    |   1 +
 4 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 ell/cipher.c
 create mode 100644 ell/cipher.h

diff --git a/Makefile.am b/Makefile.am
index 50f81eb..910d5e0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,7 +33,8 @@ pkginclude_HEADERS = ell/ell.h \
 			ell/genl.h \
 			ell/dbus.h \
 			ell/dbus-service.h \
-			ell/hwdb.h
+			ell/hwdb.h \
+			ell/cipher.h
 
 lib_LTLIBRARIES = ell/libell.la
 
@@ -67,7 +68,8 @@ ell_libell_la_SOURCES = $(linux_headers) \
 			ell/gvariant-util.c \
 			ell/siphash-private.h \
 			ell/siphash.c \
-			ell/hwdb.c
+			ell/hwdb.c \
+			ell/cipher.c
 
 ell_libell_la_LDFLAGS = -no-undefined \
 			-version-info $(ELL_CURRENT):$(ELL_REVISION):$(ELL_AGE)
diff --git a/ell/cipher.c b/ell/cipher.c
new file mode 100644
index 0000000..3d4070d
--- /dev/null
+++ b/ell/cipher.c
@@ -0,0 +1,221 @@
+/*
+ *
+ *  Embedded Linux library
+ *
+ *  Copyright (C) 2015  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include "util.h"
+#include "cipher.h"
+#include "private.h"
+
+#ifndef SOL_ALG
+#define SOL_ALG 279
+#endif
+
+#ifndef AF_ALG
+#define AF_ALG	38
+#define PF_ALG	AF_ALG
+
+#include <linux/types.h>
+
+struct sockaddr_alg {
+	__u16	salg_family;
+	__u8	salg_type[14];
+	__u32	salg_feat;
+	__u32	salg_mask;
+	__u8	salg_name[64];
+};
+
+struct af_alg_iv {
+	__u32   ivlen;
+	__u8    iv[0];
+};
+
+/* Socket options */
+#define ALG_SET_KEY	1
+#define ALG_SET_IV	2
+#define ALG_SET_OP	3
+
+/* Operations */
+#define ALG_OP_DECRYPT	0
+#define ALG_OP_ENCRYPT	1
+
+#else
+#include <linux/if_alg.h>
+#endif
+
+#define is_valid_type(type)  ((type) <= L_CIPHER_ARC4)
+
+struct l_cipher {
+	enum l_cipher_type type;
+	int b_sk;
+	int sk;
+	void *key;
+	size_t key_length;
+	bool enc;
+	bool dec;
+};
+
+LIB_EXPORT struct l_cipher *l_cipher_new(enum l_cipher_type type,
+						const void *key,
+						size_t key_length)
+{
+	struct sockaddr_alg salg;
+	struct l_cipher *cipher;
+
+	if (unlikely(!key))
+		return NULL;
+
+	if (!is_valid_type(type))
+		return NULL;
+
+	cipher = l_new(struct l_cipher, 1);
+
+	cipher->type = type;
+
+	cipher->b_sk = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
+	if (cipher->b_sk < 0)
+		goto error;
+
+	memset(&salg, 0, sizeof(salg));
+	salg.salg_family = AF_ALG;
+	strcpy((char *) salg.salg_type, "skcipher");
+
+	switch (type) {
+	case L_CIPHER_AES:
+		strcpy((char *) salg.salg_name, "ecb(aes)");
+		break;
+	case L_CIPHER_ARC4:
+		strcpy((char *) salg.salg_name, "ecb(arc4)");
+		break;
+	}
+
+	if (bind(cipher->b_sk, (struct sockaddr *) &salg, sizeof(salg)) < 0)
+		goto error;
+
+	cipher->key = l_memdup(key, key_length);
+	cipher->key_length = key_length;
+
+	cipher->sk = accept4(cipher->b_sk, NULL, 0, SOCK_CLOEXEC);
+	if (cipher->sk < 0)
+		goto error;
+
+	return cipher;
+error:
+	if (cipher->b_sk > 0)
+		close(cipher->b_sk);
+
+	if (cipher->key)
+		l_free(cipher->key);
+
+	l_free(cipher);
+
+	return NULL;
+}
+
+LIB_EXPORT void l_cipher_free(struct l_cipher *cipher)
+{
+	if (unlikely(!cipher))
+		return;
+
+	close(cipher->sk);
+	close(cipher->b_sk);
+
+	if (cipher->key)
+		l_free(cipher->key);
+
+	l_free(cipher);
+}
+
+static void operate_cipher(struct l_cipher *cipher, __u32 operation,
+				const void *in, void *out, size_t len)
+{
+	char c_msg_buf[CMSG_SPACE(sizeof(operation))] = {};
+	struct msghdr msg = {};
+	bool setkey = false;
+	struct cmsghdr *c_msg;
+	struct iovec iov;
+
+	if (operation == ALG_OP_ENCRYPT && !cipher->enc) {
+		setkey = cipher->enc = true;
+		cipher->dec = false;
+	} else if (operation == ALG_OP_DECRYPT && !cipher->dec) {
+		setkey = cipher->dec = true;
+		cipher->enc = false;
+	}
+
+	if (setkey) {
+		if (setsockopt(cipher->b_sk, SOL_ALG, ALG_SET_KEY,
+					cipher->key, cipher->key_length) < 0)
+			return;
+	}
+
+	msg.msg_control = c_msg_buf;
+	msg.msg_controllen = sizeof(c_msg_buf);
+
+	c_msg = CMSG_FIRSTHDR(&msg);
+	c_msg->cmsg_level = SOL_ALG;
+	c_msg->cmsg_type = ALG_SET_OP;
+	c_msg->cmsg_len = CMSG_LEN(sizeof(operation));
+	memcpy(CMSG_DATA(c_msg), &operation, sizeof(operation));
+
+	iov.iov_base = (void *) in;
+	iov.iov_len = len;
+
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	if (sendmsg(cipher->sk, &msg, 0) < 0)
+		return;
+
+	if (read(cipher->sk, out, len) < 0)
+		return;
+}
+
+LIB_EXPORT void l_cipher_encrypt(struct l_cipher *cipher,
+					const void *in, void *out, size_t len)
+{
+	if (unlikely(!cipher))
+		return;
+
+	if (unlikely(!in) || unlikely(!out))
+		return;
+
+	operate_cipher(cipher, ALG_OP_ENCRYPT, in, out, len);
+}
+
+LIB_EXPORT void l_cipher_decrypt(struct l_cipher *cipher,
+					const void *in, void *out, size_t len)
+{
+	if (unlikely(!cipher))
+		return;
+
+	if (unlikely(!in) || unlikely(!out))
+		return;
+
+	operate_cipher(cipher, ALG_OP_DECRYPT, in, out, len);
+}
diff --git a/ell/cipher.h b/ell/cipher.h
new file mode 100644
index 0000000..b273102
--- /dev/null
+++ b/ell/cipher.h
@@ -0,0 +1,52 @@
+/*
+ *
+ *  Embedded Linux library
+ *
+ *  Copyright (C) 2015  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __ELL_CIPHER_H
+#define __ELL_CIPHER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct l_cipher;
+
+enum l_cipher_type {
+	L_CIPHER_AES,
+	L_CIPHER_ARC4,
+};
+
+struct l_cipher *l_cipher_new(enum l_cipher_type type,
+				const void *key, size_t key_length);
+
+void l_cipher_free(struct l_cipher *cipher);
+
+void l_cipher_encrypt(struct l_cipher *cipher,
+			const void *in, void *out, size_t len);
+
+void l_cipher_decrypt(struct l_cipher *cipher,
+			const void *in, void *out, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ELL_CIPHER_H */
diff --git a/ell/ell.h b/ell/ell.h
index c4dc1f2..4d9afa3 100644
--- a/ell/ell.h
+++ b/ell/ell.h
@@ -35,6 +35,7 @@
 #include <ell/checksum.h>
 #include <ell/settings.h>
 #include <ell/hwdb.h>
+#include <ell/cipher.h>
 
 #include <ell/netlink.h>
 #include <ell/genl.h>
-- 
2.0.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] unit: Add unit test for the cipher infrastructure
  2015-02-06 12:39 [PATCH v2 0/2] Cipher infrastructure Tomasz Bursztyka
  2015-02-06 12:39 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
@ 2015-02-06 12:39 ` Tomasz Bursztyka
  2015-02-09 15:40 ` [PATCH v2 0/2] Cipher infrastructure Denis Kenzior
  2 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-02-06 12:39 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 3888 bytes --]

It quickly encrypt, verify that the buffer has different content, and
again decrypt and verify now it has the same content.
---
 Makefile.am        |   5 ++-
 unit/test-cipher.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 unit/test-cipher.c

diff --git a/Makefile.am b/Makefile.am
index 910d5e0..e32054f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -107,7 +107,8 @@ unit_tests = unit/test-unit \
 			unit/test-gvariant-util \
 			unit/test-gvariant-message \
 			unit/test-siphash \
-			unit/test-hwdb
+			unit/test-hwdb \
+			unit/test-cipher
 
 if MAINTAINER_MODE
 noinst_PROGRAMS += $(unit_tests)
@@ -157,6 +158,8 @@ unit_test_siphash_LDADD = ell/libell-private.la
 
 unit_test_hwdb_LDADD = ell/libell-private.la
 
+unit_test_cipher_LDADD = ell/libell-private.la
+
 if MAINTAINER_MODE
 noinst_LTLIBRARIES += unit/example-plugin.la
 endif
diff --git a/unit/test-cipher.c b/unit/test-cipher.c
new file mode 100644
index 0000000..41a4447
--- /dev/null
+++ b/unit/test-cipher.c
@@ -0,0 +1,107 @@
+/*
+ *
+ *  Embedded Linux library
+ *
+ *  Copyright (C) 2015  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+
+#include <ell/ell.h>
+
+#define FIXED_STR  "The quick brown fox jumps over the lazy dog. " \
+		   "Jackdaws love my big sphinx of quartz. "       \
+		   "Pack my box with five dozen liquor jugs. "     \
+		   "How razorback-jumping frogs can level six piqued gymnasts!"
+#define FIXED_LEN  (strlen(FIXED_STR))
+
+#define KEY_STR "This key has exactly _32_ bytes!"
+#define KEY_LEN (strlen(KEY_STR))
+
+static void test_unsupported(const void *data)
+{
+	struct l_cipher *cipher;
+
+	cipher = l_cipher_new(42, KEY_STR, KEY_LEN);
+	assert(!cipher);
+}
+
+static void test_aes(const void *data)
+{
+	struct l_cipher *cipher;
+	char buf[256] = {};
+	int r;
+
+	cipher = l_cipher_new(L_CIPHER_AES, KEY_STR, KEY_LEN);
+	assert(cipher);
+
+	memcpy(buf, FIXED_STR, FIXED_LEN);
+
+	l_cipher_encrypt(cipher, buf, buf, 256);
+
+	r = memcmp(buf, FIXED_STR, FIXED_LEN);
+	assert(r);
+
+	l_cipher_decrypt(cipher, buf, buf, 256);
+
+	r = memcmp(buf, FIXED_STR, FIXED_LEN);
+	assert(!r);
+
+	l_cipher_free(cipher);
+}
+
+static void test_arc4(const void *data)
+{
+	struct l_cipher *cipher;
+	char buf[256] = {};
+	int r;
+
+	cipher = l_cipher_new(L_CIPHER_ARC4, KEY_STR, KEY_LEN);
+	assert(cipher);
+
+	memcpy(buf, FIXED_STR, FIXED_LEN);
+
+	l_cipher_encrypt(cipher, buf, buf, 256);
+
+	r = memcmp(buf, FIXED_STR, FIXED_LEN);
+	assert(r);
+
+	l_cipher_decrypt(cipher, buf, buf, 256);
+
+	r = memcmp(buf, FIXED_STR, FIXED_LEN);
+	assert(!r);
+
+	l_cipher_free(cipher);
+}
+
+int main(int argc, char *argv[])
+{
+	l_test_init(&argc, &argv);
+
+	l_test_add("unsupported", test_unsupported, NULL);
+
+	l_test_add("aes", test_aes, NULL);
+
+	l_test_add("arc4", test_arc4, NULL);
+
+	return l_test_run();
+}
-- 
2.0.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/2] Cipher infrastructure
  2015-02-06 12:39 [PATCH v2 0/2] Cipher infrastructure Tomasz Bursztyka
  2015-02-06 12:39 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
  2015-02-06 12:39 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
@ 2015-02-09 15:40 ` Denis Kenzior
  2015-02-10  7:19   ` Tomasz Bursztyka
  2 siblings, 1 reply; 5+ messages in thread
From: Denis Kenzior @ 2015-02-09 15:40 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 1119 bytes --]

Hi Tomasz,

On 02/06/2015 06:39 AM, Tomasz Bursztyka wrote:
> Hi,
>
> Looks like we need to re-inject the keys to the master socket (the one which
> is binded so the selected crypto) once before an operation type, so first encrypt
> and/or first decrypt.
> Now it seems to work. Should it handle an initialization vector?
>
> Tomasz Bursztyka (2):
>    cipher: Add a basic infrastructure for kernel based cipher operations
>    unit: Add unit test for the cipher infrastructure
>
>   Makefile.am        |  11 ++-
>   ell/cipher.c       | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>   ell/cipher.h       |  52 +++++++++++++
>   ell/ell.h          |   1 +
>   unit/test-cipher.c | 107 ++++++++++++++++++++++++++
>   5 files changed, 389 insertions(+), 3 deletions(-)
>   create mode 100644 ell/cipher.c
>   create mode 100644 ell/cipher.h
>   create mode 100644 unit/test-cipher.c
>

I went ahead and applied both patches, but I reworked the implementation 
afterward.  I tried to explain the reasoning in the commit message, let 
me know if I succeeded :)

Regards,
-Denis

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/2] Cipher infrastructure
  2015-02-09 15:40 ` [PATCH v2 0/2] Cipher infrastructure Denis Kenzior
@ 2015-02-10  7:19   ` Tomasz Bursztyka
  0 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-02-10  7:19 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 267 bytes --]

Hi Denis,

>
> I went ahead and applied both patches, but I reworked the 
> implementation afterward.  I tried to explain the reasoning in the 
> commit message, let me know if I succeeded :) 

I would have preferred to get comments on the patches.

Tomasz

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-02-10  7:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-06 12:39 [PATCH v2 0/2] Cipher infrastructure Tomasz Bursztyka
2015-02-06 12:39 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
2015-02-06 12:39 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
2015-02-09 15:40 ` [PATCH v2 0/2] Cipher infrastructure Denis Kenzior
2015-02-10  7:19   ` Tomasz Bursztyka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.