* [RFC 0/2] Cipher infrastructure
@ 2015-01-30 10:57 Tomasz Bursztyka
2015-01-30 10:57 ` [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-01-30 10:57 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 1345 bytes --]
Hi,
Went quickly through the cipher proposal, to get a somehow working implementation.
Seems to work with aes, but not with arc4.
And now I wonder if we should not provide an initialization vector for some ciphers? (like arc4).
I thought I could set one IV per socket once, but it does not seems so. (thus there is
nothing related to IV in this RFC).
So, should I set iv elements in struct l_cipher, so I could set one one encrypting/decrypting?
It's just a bit annoying with cmsg handling, but I got nice example with libkapi (though this
one mandate the user to provide the iv. I tought we could handle randomly generated ones?)
libkapi is kind of nice as it uses vmsplice and so on. It's just a lot of code, I don't
think we want something that complex.
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 | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++
ell/cipher.h | 51 +++++++++++++
ell/ell.h | 1 +
unit/test-cipher.c | 109 +++++++++++++++++++++++++++
5 files changed, 384 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-01-30 10:57 [RFC 0/2] Cipher infrastructure Tomasz Bursztyka
@ 2015-01-30 10:57 ` Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
2015-02-02 18:44 ` [RFC 0/2] Cipher infrastructure Denis Kenzior
2 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-01-30 10:57 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 8101 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 | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ell/cipher.h | 51 ++++++++++++++
ell/ell.h | 1 +
4 files changed, 271 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..230d1af
--- /dev/null
+++ b/ell/cipher.c
@@ -0,0 +1,215 @@
+/*
+ *
+ * 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)
+
+static struct {
+ int sk;
+ unsigned int count;
+} alg_list[L_CIPHER_ARC4 + 1];
+
+struct l_cipher {
+ enum l_cipher_type type;
+ int sk;
+};
+
+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;
+ int sk;
+
+ if (!is_valid_type(type))
+ return NULL;
+
+ cipher = l_new(struct l_cipher, 1);
+
+ cipher->type = type;
+
+ if (alg_list[type].sk > 0) {
+ sk = alg_list[type].sk;
+ goto accept;
+ }
+
+ sk = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
+ if (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(sk, (struct sockaddr *) &salg, sizeof(salg)) < 0)
+ goto error;
+accept:
+ if (setsockopt(sk, SOL_ALG, ALG_SET_KEY, key, key_length) < 0)
+ goto error;
+
+ cipher->sk = accept4(sk, NULL, 0, SOCK_CLOEXEC);
+ if (cipher->sk < 0)
+ goto error;
+
+ if (alg_list[type].sk == 0) {
+ alg_list[type].sk = sk;
+ alg_list[type].count = 1;
+ } else
+ alg_list[type].count++;
+
+ return cipher;
+error:
+ if (sk > 0 && alg_list[type].sk == 0)
+ close(sk);
+
+ l_free(cipher);
+
+ return NULL;
+}
+
+LIB_EXPORT void l_cipher_free(struct l_cipher *cipher)
+{
+ if (unlikely(!cipher))
+ return;
+
+ alg_list[cipher->type].count--;
+
+ close(cipher->sk);
+
+ if (alg_list[cipher->type].count == 0) {
+ close(alg_list[cipher->type].sk);
+ alg_list[cipher->type].sk = 0;
+ }
+
+ l_free(cipher);
+}
+
+static void operate_cipher(int sk, __u32 operation,
+ const void *in, void *out, size_t len)
+{
+ char c_msg_buf[CMSG_SPACE(sizeof(operation))] = {};
+ struct msghdr msg = {};
+ struct cmsghdr *c_msg;
+ struct iovec iov;
+
+ 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(sk, &msg, 0) < 0)
+ return;
+
+ if (read(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->sk, 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->sk, ALG_OP_DECRYPT, in, out, len);
+}
diff --git a/ell/cipher.h b/ell/cipher.h
new file mode 100644
index 0000000..644d350
--- /dev/null
+++ b/ell/cipher.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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-01-30 10:57 [RFC 0/2] Cipher infrastructure Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
@ 2015-01-30 10:57 ` Tomasz Bursztyka
2015-02-02 18:44 ` [RFC 0/2] Cipher infrastructure Denis Kenzior
2 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-01-30 10:57 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 3926 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 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 113 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..f52cac5
--- /dev/null
+++ b/unit/test-cipher.c
@@ -0,0 +1,109 @@
+/*
+ *
+ * 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 in[256] = {};
+ char out[256] = {};
+ int r;
+
+ cipher = l_cipher_new(L_CIPHER_AES, KEY_STR, KEY_LEN);
+ assert(cipher);
+
+ memcpy(in, FIXED_STR, FIXED_LEN);
+
+ l_cipher_encrypt(cipher, in, out, 256);
+
+ r = memcmp(out, FIXED_STR, FIXED_LEN);
+ assert(r);
+
+ l_cipher_decrypt(cipher, out, in, 256);
+
+ r = memcmp(in, FIXED_STR, FIXED_LEN);
+ assert(!r);
+
+ l_cipher_free(cipher);
+}
+
+static void test_arc4(const void *data)
+{
+ struct l_cipher *cipher;
+ char in[256] = {};
+ char out[256] = {};
+ int r;
+
+ cipher = l_cipher_new(L_CIPHER_ARC4, KEY_STR, KEY_LEN);
+ assert(cipher);
+
+ memcpy(in, FIXED_STR, FIXED_LEN);
+
+ l_cipher_encrypt(cipher, in, out, 256);
+
+ r = memcmp(out, FIXED_STR, FIXED_LEN);
+ assert(r);
+
+ l_cipher_decrypt(cipher, out, in, 256);
+
+ r = memcmp(in, 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: [RFC 0/2] Cipher infrastructure
2015-01-30 10:57 [RFC 0/2] Cipher infrastructure Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
@ 2015-02-02 18:44 ` Denis Kenzior
2015-02-03 8:07 ` Tomasz Bursztyka
2 siblings, 1 reply; 5+ messages in thread
From: Denis Kenzior @ 2015-02-02 18:44 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 689 bytes --]
Hi Tomasz,
On 01/30/2015 04:57 AM, Tomasz Bursztyka wrote:
> Hi,
>
> Went quickly through the cipher proposal, to get a somehow working implementation.
> Seems to work with aes, but not with arc4.
>
ARC4 is a bit weird. The same function is used for encryption and
decryption, so the stream is not reset. You will likely need to set the
key prior to each encrypt/decrypt operation.
> And now I wonder if we should not provide an initialization vector for some ciphers? (like arc4).
>
I'm still not fully sure we need the IV. EAPoL Key-IV is only used in
certain situations. Lets try to find an AP / trace that actually sets
the IV field.
Regards,
-Denis
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC 0/2] Cipher infrastructure
2015-02-02 18:44 ` [RFC 0/2] Cipher infrastructure Denis Kenzior
@ 2015-02-03 8:07 ` Tomasz Bursztyka
0 siblings, 0 replies; 5+ messages in thread
From: Tomasz Bursztyka @ 2015-02-03 8:07 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 920 bytes --]
Hi Denis,
> Hi Tomasz,
>
> On 01/30/2015 04:57 AM, Tomasz Bursztyka wrote:
>> Hi,
>>
>> Went quickly through the cipher proposal, to get a somehow working
>> implementation.
>> Seems to work with aes, but not with arc4.
>>
>
> ARC4 is a bit weird. The same function is used for encryption and
> decryption, so the stream is not reset. You will likely need to set
> the key prior to each encrypt/decrypt operation.
OK.
>
>> And now I wonder if we should not provide an initialization vector
>> for some ciphers? (like arc4).
>>
>
> I'm still not fully sure we need the IV. EAPoL Key-IV is only used in
> certain situations. Lets try to find an AP / trace that actually sets
> the IV field.
>
Ok, then I think it's worth putting an iv/iv-len params to the
l_cipher_new(). I might implement its support later though, let's see
(but at least the API would be fixed).
Tomasz
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-02-03 8:07 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-30 10:57 [RFC 0/2] Cipher infrastructure Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 1/2] cipher: Add a basic infrastructure for kernel based cipher operations Tomasz Bursztyka
2015-01-30 10:57 ` [PATCH 2/2] unit: Add unit test for the cipher infrastructure Tomasz Bursztyka
2015-02-02 18:44 ` [RFC 0/2] Cipher infrastructure Denis Kenzior
2015-02-03 8:07 ` 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.