Applied. On Fri, 2019-08-30 at 12:15 -0700, Brian Gix wrote: > One time test at startup to ensure either kernel version v4.9 or later, > *or* that required AES-CCM support has been back-ported. If support not > there, daemon will run without providing D-Bus service or attaching to > controllers (prevents systemd thrashing). > --- > mesh/crypto.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ > mesh/crypto.h | 1 + > mesh/main.c | 7 +++++++ > 3 files changed, 62 insertions(+) > > diff --git a/mesh/crypto.c b/mesh/crypto.c > index a6dc7ffe2..cebdffe45 100644 > --- a/mesh/crypto.c > +++ b/mesh/crypto.c > @@ -1130,3 +1130,57 @@ bool mesh_crypto_check_fcs(const uint8_t *packet, uint8_t packet_len, > > return fcs == 0xcf; > } > + > +/* This function performs a quick-check of ELL and Kernel AEAD encryption. > + * Some kernel versions before v4.9 have a known AEAD bug. If the system > + * running this test is using a v4.8 or earlier kernel, a failure here is > + * likely unless AEAD encryption has been backported. > + */ > +static const uint8_t crypto_test_result[] = { > + 0x75, 0x03, 0x7e, 0xe2, 0x89, 0x81, 0xbe, 0x59, > + 0xbc, 0xe6, 0xdd, 0x23, 0x63, 0x5b, 0x16, 0x61, > + 0xb7, 0x23, 0x92, 0xd4, 0x86, 0xee, 0x84, 0x29, > + 0x9a, 0x2a, 0xbf, 0x96 > +}; > + > +bool mesh_crypto_check_avail() > +{ > + void *cipher; > + bool result; > + uint8_t i; > + union { > + struct { > + uint8_t key[16]; > + uint8_t aad[16]; > + uint8_t nonce[13]; > + uint8_t data[20]; > + uint8_t mic[8]; > + } crypto; > + uint8_t bytes[0]; > + } u; > + uint8_t out_msg[sizeof(u.crypto.data) + sizeof(u.crypto.mic)]; > + > + l_debug("Testing Crypto"); > + for (i = 0; i < sizeof(u); i++) { > + u.bytes[i] = 0x60 + i; > + } > + > + cipher = l_aead_cipher_new(L_AEAD_CIPHER_AES_CCM, u.crypto.key, > + sizeof(u.crypto.key), sizeof(u.crypto.mic)); > + > + if (!cipher) > + return false; > + > + result = l_aead_cipher_encrypt(cipher, > + u.crypto.data, sizeof(u.crypto.data), > + u.crypto.aad, sizeof(u.crypto.aad), > + u.crypto.nonce, sizeof(u.crypto.nonce), > + out_msg, sizeof(out_msg)); > + > + if (result) > + result = !memcmp(out_msg, crypto_test_result, sizeof(out_msg)); > + > + l_aead_cipher_free(cipher); > + > + return result; > +} > diff --git a/mesh/crypto.h b/mesh/crypto.h > index 1a73bcaa3..e5ce840b4 100644 > --- a/mesh/crypto.h > +++ b/mesh/crypto.h > @@ -161,3 +161,4 @@ bool mesh_crypto_check_fcs(const uint8_t *packet, uint8_t packet_len, > uint8_t received_fcs); > bool mesh_crypto_aes_cmac(const uint8_t key[16], const uint8_t *msg, > size_t msg_len, uint8_t res[16]); > +bool mesh_crypto_check_avail(void); > diff --git a/mesh/main.c b/mesh/main.c > index 262e3da48..273651f97 100644 > --- a/mesh/main.c > +++ b/mesh/main.c > @@ -34,6 +34,7 @@ > #include "lib/mgmt.h" > > #include "mesh/mesh.h" > +#include "mesh/crypto.h" > #include "mesh/dbus.h" > #include "mesh/mesh-io.h" > > @@ -121,6 +122,12 @@ int main(int argc, char *argv[]) > > l_log_set_stderr(); > > + if (!mesh_crypto_check_avail()) { > + l_error("Mesh Crypto functions unavailable"); > + status = l_main_run_with_signal(signal_handler, NULL); > + goto done; > + } > + > for (;;) { > int opt; > const char *str;