[PATCH] dbus: added l_dbus_message_iter_get_fixed_array
by James Prestwood
Returns pointer and length of dbus array in place so no copying
is needed.
---
ell/dbus-message.c | 14 ++++++++++++++
ell/dbus.h | 3 ++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/ell/dbus-message.c b/ell/dbus-message.c
index f4f6b42..7a24f5b 100644
--- a/ell/dbus-message.c
+++ b/ell/dbus-message.c
@@ -1414,6 +1414,20 @@ LIB_EXPORT bool l_dbus_message_iter_get_variant(
return result;
}
+LIB_EXPORT bool l_dbus_message_iter_get_fixed_array(
+ struct l_dbus_message_iter *iter,
+ const void **a, uint32_t *len)
+{
+ if (iter->container_type != 'a')
+ return false;
+
+ *a = iter->data + iter->pos;
+ *len = iter->len - 4;
+
+ return true;
+}
+
+
void _dbus_message_set_sender(struct l_dbus_message *message,
const char *sender)
{
diff --git a/ell/dbus.h b/ell/dbus.h
index 1b1ec2b..4eb579c 100644
--- a/ell/dbus.h
+++ b/ell/dbus.h
@@ -170,7 +170,8 @@ bool l_dbus_message_get_arguments_valist(struct l_dbus_message *message,
bool l_dbus_message_iter_next_entry(struct l_dbus_message_iter *iter, ...);
bool l_dbus_message_iter_get_variant(struct l_dbus_message_iter *iter,
const char *signature, ...);
-
+bool l_dbus_message_iter_get_fixed_array(struct l_dbus_message_iter *iter,
+ const void **a, uint32_t *len);
bool l_dbus_message_set_arguments(struct l_dbus_message *message,
const char *signature, ...);
bool l_dbus_message_set_arguments_valist(struct l_dbus_message *message,
--
2.7.4
2 years, 11 months
[PATCH 1/3] tls: introduce more_tofollow flag into l_tls_write_cb_t
by Tim Kourt
TLS is a stream-oriented protocol and assumes processing of
a TLS record as soon as it becomes available. Certain
applications of TLS such as: TTLS, PEAP, etc. require to deal
with the packets that span multiple TLS records and must be
handled as a single block of data. This change introduces
'more_tofollow' flag into l_tls_write_cb_t that indicates
whether we have processed all of the data submitted into
l_tls_write or l_tls_handle_rx functions.
---
ell/tls-private.h | 3 ++-
ell/tls-record.c | 28 +++++++++++++++++-----------
ell/tls.c | 5 +++--
ell/tls.h | 2 +-
4 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/ell/tls-private.h b/ell/tls-private.h
index d501651..ace1293 100644
--- a/ell/tls-private.h
+++ b/ell/tls-private.h
@@ -218,7 +218,8 @@ void tls_disconnect(struct l_tls *tls, enum l_tls_alert_desc desc,
void tls_tx_record(struct l_tls *tls, enum tls_content_type type,
const uint8_t *data, size_t len);
bool tls_handle_message(struct l_tls *tls, const uint8_t *message,
- int len, enum tls_content_type type, uint16_t version);
+ int len, enum tls_content_type type, uint16_t version,
+ bool more_tofollow);
/* X509 Certificates and Certificate Chains */
diff --git a/ell/tls-record.c b/ell/tls-record.c
index c0e5834..9a05450 100644
--- a/ell/tls-record.c
+++ b/ell/tls-record.c
@@ -63,7 +63,8 @@ static void tls_write_mac(struct l_tls *tls, uint8_t *compressed,
static void tls_tx_record_plaintext(struct l_tls *tls,
uint8_t *plaintext,
- uint16_t plaintext_len)
+ uint16_t plaintext_len,
+ bool more_tofollow)
{
uint8_t *compressed;
uint16_t compressed_len;
@@ -169,9 +170,9 @@ static void tls_tx_record_plaintext(struct l_tls *tls,
ciphertext[3] = ciphertext_len >> 8;
ciphertext[4] = ciphertext_len >> 0;
- tls->tx(ciphertext, ciphertext_len + 5, tls->user_data);
+ tls->tx(ciphertext, ciphertext_len + 5, more_tofollow, tls->user_data);
}
-
+#include <stdio.h>
void tls_tx_record(struct l_tls *tls, enum tls_content_type type,
const uint8_t *data, size_t len)
{
@@ -195,15 +196,17 @@ void tls_tx_record(struct l_tls *tls, enum tls_content_type type,
plaintext[4] = fragment_len >> 0;
memcpy(plaintext + 5, data, fragment_len);
- tls_tx_record_plaintext(tls, plaintext, fragment_len + 5);
-
data += fragment_len;
len -= fragment_len;
+
+ tls_tx_record_plaintext(tls, plaintext, fragment_len + 5,
+ len ? true : false);
}
}
static bool tls_handle_plaintext(struct l_tls *tls, const uint8_t *plaintext,
- int len, uint8_t type, uint16_t version)
+ int len, uint8_t type, uint16_t version,
+ bool more_tofollow)
{
int header_len, need_len;
int chunk_len;
@@ -218,7 +221,8 @@ static bool tls_handle_plaintext(struct l_tls *tls, const uint8_t *plaintext,
switch (type) {
case TLS_CT_CHANGE_CIPHER_SPEC:
case TLS_CT_APPLICATION_DATA:
- return tls_handle_message(tls, plaintext, len, type, version);
+ return tls_handle_message(tls, plaintext, len, type, version,
+ more_tofollow);
/*
* We need to perform input reassembly twice at different levels:
@@ -277,7 +281,8 @@ static bool tls_handle_plaintext(struct l_tls *tls, const uint8_t *plaintext,
if (tls->message_buf_len == need_len) {
if (!tls_handle_message(tls, tls->message_buf,
need_len, type,
- version))
+ version,
+ len ? true : false))
return false;
tls->message_buf_len = 0;
@@ -314,7 +319,7 @@ static bool tls_handle_plaintext(struct l_tls *tls, const uint8_t *plaintext,
return true;
}
-static bool tls_handle_ciphertext(struct l_tls *tls)
+static bool tls_handle_ciphertext(struct l_tls *tls, bool more_tofollow)
{
uint8_t type;
uint16_t version;
@@ -483,7 +488,7 @@ static bool tls_handle_ciphertext(struct l_tls *tls)
/* DEFLATE not supported so just pass on compressed / compressed_len */
return tls_handle_plaintext(tls, compressed, compressed_len,
- type, version);
+ type, version, more_tofollow);
}
LIB_EXPORT void l_tls_handle_rx(struct l_tls *tls, const uint8_t *data,
@@ -501,7 +506,8 @@ LIB_EXPORT void l_tls_handle_rx(struct l_tls *tls, const uint8_t *data,
/* Do we have a full structure? */
if (tls->record_buf_len == need_len) {
- if (!tls_handle_ciphertext(tls))
+ if (!tls_handle_ciphertext(tls, len ?
+ true : false))
return;
tls->record_buf_len = 0;
diff --git a/ell/tls.c b/ell/tls.c
index d3b4809..8e5b927 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -2065,7 +2065,8 @@ LIB_EXPORT void l_tls_write(struct l_tls *tls, const uint8_t *data, size_t len)
}
bool tls_handle_message(struct l_tls *tls, const uint8_t *message,
- int len, enum tls_content_type type, uint16_t version)
+ int len, enum tls_content_type type, uint16_t version,
+ bool more_tofollow)
{
enum handshake_hash_type hash;
@@ -2178,7 +2179,7 @@ bool tls_handle_message(struct l_tls *tls, const uint8_t *message,
if (!len)
return true;
- tls->rx(message, len, tls->user_data);
+ tls->rx(message, len, more_tofollow, tls->user_data);
return true;
}
diff --git a/ell/tls.h b/ell/tls.h
index 0a7c920..865792e 100644
--- a/ell/tls.h
+++ b/ell/tls.h
@@ -56,7 +56,7 @@ enum l_tls_alert_desc {
};
typedef void (*l_tls_write_cb_t)(const uint8_t *data, size_t len,
- void *user_data);
+ bool more_tofollow, void *user_data);
typedef void (*l_tls_ready_cb_t)(const char *peer_identity, void *user_data);
typedef void (*l_tls_disconnect_cb_t)(enum l_tls_alert_desc reason,
bool remote, void *user_data);
--
2.9.4
2 years, 12 months
[PATCH 1/4] cipher: Correctly propagate AEAD failures
by Mat Martineau
Some pre-4.9 kernels have an AEAD bug that makes recvmsg() return an
incorrect value that does not include the AAD length. This could cause
an erroneous successful return from l_aead_cipher_{en,de}crypt() if
ad_len was longer than the expected output. operate_cipher() now returns
the number of bytes copied to the 'out' buffer, and the AEAD functions
only succeed if the expected number of bytes were copied.
---
ell/cipher.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/ell/cipher.c b/ell/cipher.c
index bbf0a48..bfbe5d4 100644
--- a/ell/cipher.c
+++ b/ell/cipher.c
@@ -378,8 +378,10 @@ static ssize_t operate_cipher(int sk, __u32 operation,
result = recvmsg(sk, &msg, 0);
- if (result > (ssize_t) ad_len)
+ if (result >= (ssize_t) ad_len)
result -= ad_len;
+ else if (result > 0)
+ result = 0;
l_free(iov[0].iov_base);
} else {
@@ -546,7 +548,8 @@ LIB_EXPORT bool l_aead_cipher_encrypt(struct l_aead_cipher *cipher,
return operate_cipher(cipher->encrypt_sk, ALG_OP_ENCRYPT, in, in_len,
ad, ad_len, nonce, nonce_len, out, out_len,
- l_aead_cipher_get_ivlen(cipher)) >= 0;
+ l_aead_cipher_get_ivlen(cipher)) ==
+ (ssize_t)out_len;
}
LIB_EXPORT bool l_aead_cipher_decrypt(struct l_aead_cipher *cipher,
@@ -563,7 +566,8 @@ LIB_EXPORT bool l_aead_cipher_decrypt(struct l_aead_cipher *cipher,
return operate_cipher(cipher->decrypt_sk, ALG_OP_DECRYPT, in, in_len,
ad, ad_len, nonce, nonce_len, out, out_len,
- l_aead_cipher_get_ivlen(cipher)) >= 0;
+ l_aead_cipher_get_ivlen(cipher)) ==
+ (ssize_t)out_len;
}
static void init_supported()
--
2.16.1
3 years
[PATCH 1/4] key: Add private API for key feature detection
by Mat Martineau
The Diffie-Hellman, keyring restrictions, and key crypto parts of the
l_key API depend on kernel features that were added relatively
recently. While the affected l_key calls fail gracefully when the kernel
doesn't implement the required feature, they do not fail in a way that
allows unit tests to differentiate between library bugs and kernel
support. l_key_is_supported() is a private API to check for kernel
support.
---
ell/key-private.h | 27 +++++++++++++++++++++++++++
ell/key.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
create mode 100644 ell/key-private.h
diff --git a/ell/key-private.h b/ell/key-private.h
new file mode 100644
index 0000000..ea0012f
--- /dev/null
+++ b/ell/key-private.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Embedded Linux library
+ *
+ * Copyright (C) 2018 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
+ *
+ */
+
+#define L_KEY_FEATURE_DH (1 << 0)
+#define L_KEY_FEATURE_RESTRICT (1 << 1)
+#define L_KEY_FEATURE_CRYPTO (1 << 2)
+
+bool l_key_is_supported(uint32_t features);
diff --git a/ell/key.c b/ell/key.c
index 5a73bbd..4093143 100644
--- a/ell/key.c
+++ b/ell/key.c
@@ -36,6 +36,7 @@
#include "key.h"
#include "string.h"
#include "random.h"
+#include "key-private.h"
#ifndef KEYCTL_DH_COMPUTE
#define KEYCTL_DH_COMPUTE 23
@@ -772,3 +773,33 @@ bool l_keyring_unlink(struct l_keyring *keyring, const struct l_key *key)
return error == 0;
}
+
+bool l_key_is_supported(uint32_t features)
+{
+ long result;
+
+ if (features & L_KEY_FEATURE_DH) {
+ result = syscall(__NR_keyctl, KEYCTL_DH_COMPUTE, NULL, "x", 1,
+ NULL);
+
+ if (result == -1 && errno == EOPNOTSUPP)
+ return false;
+ }
+
+ if (features & L_KEY_FEATURE_RESTRICT) {
+ result = syscall(__NR_keyctl, KEYCTL_RESTRICT_KEYRING, 0,
+ "asymmetric", "");
+
+ if (result == -1 && errno == EOPNOTSUPP)
+ return false;
+ }
+
+ if (features & L_KEY_FEATURE_CRYPTO) {
+ result = syscall(__NR_keyctl, KEYCTL_PKEY_QUERY, 0, 0, "", 0);
+
+ if (result == -1 && errno == EOPNOTSUPP)
+ return false;
+ }
+
+ return true;
+}
--
2.16.1
3 years
[PATCH] unit: Skip key crypto test if the kernel doesn't support it
by Mat Martineau
---
This is one approach to testing for key crypto functionality - I thought
I'd float it as a proposal for handling missing kernel features.
The l_key API fails cleanly when key crypto is not supported by the
kernel, but the unit test needs to differentiate between ELL bugs and
lack of kernel support.
If regular ELL programs need to query for kernel feature support, I
could add l_key_crypto_is_supported() instead.
Depending on how far back in kernel history we want to go, checks for DH
(kernel v4.7+) and keyring restriction (v4.12+) keyctls would be very
similar to this crypto check.
Mat
unit/test-key.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/unit/test-key.c b/unit/test-key.c
index f2526f5..81c9ee6 100644
--- a/unit/test-key.c
+++ b/unit/test-key.c
@@ -24,7 +24,11 @@
#include <config.h>
#endif
+#define _GNU_SOURCE
#include <assert.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
#include <ell/ell.h>
@@ -497,6 +501,19 @@ static void test_trust_chain(const void *data)
l_free(cert);
}
+#ifndef KEYCTL_PKEY_QUERY
+#define KEYCTL_PKEY_QUERY 24
+#endif
+
+static bool kernel_has_key_crypto(void)
+{
+ long result = syscall(__NR_keyctl, KEYCTL_PKEY_QUERY, 0, 0, "", 0);
+
+ assert(result == -1);
+
+ return (errno != EOPNOTSUPP);
+}
+
static void test_key_crypto(const void *data)
{
uint8_t *cert;
@@ -626,7 +643,8 @@ int main(int argc, char *argv[])
l_test_add("trusted keyring", test_trusted_keyring, NULL);
l_test_add("trust chain", test_trust_chain, NULL);
- l_test_add("key crypto", test_key_crypto, NULL);
+ if (kernel_has_key_crypto())
+ l_test_add("key crypto", test_key_crypto, NULL);
return l_test_run();
}
--
2.16.0
3 years