diff --git a/src/main.c b/src/main.c index 63a5d1fd..ed35e05b 100644 --- a/src/main.c +++ b/src/main.c @@ -26,8 +26,10 @@ #include #include +#include #include #include +#include "ell/key-private.h" #include "linux/nl80211.h" @@ -168,6 +170,134 @@ static void nl80211_vanished(void *user_data) wiphy_exit(); } +static void print_koption(const void *key, void *value, void *user_data) +{ + l_info("\t%s", (const char *) key); +} + +static int check_crypto() +{ + int r = 0; + struct l_hashmap *options = l_hashmap_string_new(); + struct l_hashmap *optional = l_hashmap_string_new(); + + if (!l_checksum_is_supported(L_CHECKSUM_SHA1, true)) { + r = -ENOTSUP; + l_error("No HMAC(SHA1) support found"); + l_hashmap_insert(options, "CONFIG_CRYPTO_USER_API_HASH", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_SHA1", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_HMAC", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_SHA1_SSSE3", &r); + } + + if (!l_checksum_is_supported(L_CHECKSUM_MD5, true)) { + r = -ENOTSUP; + l_error("No HMAC(MD5) support found"); + l_hashmap_insert(options, "CONFIG_CRYPTO_USER_API_HASH", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_MD5", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_HMAC", &r); + } + + if (!l_checksum_cmac_aes_supported()) { + r = -ENOTSUP; + l_error("No CMAC(AES) support found"); + l_hashmap_insert(options, "CONFIG_CRYPTO_USER_API_HASH", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_AES", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_CMAC", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_AES_X86_64", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_AES_NI_INTEL", &r); + } + + if (!l_checksum_is_supported(L_CHECKSUM_SHA256, true)) { + r = -ENOTSUP; + l_error("No HMAC(SHA256) support not found"); + l_hashmap_insert(options, "CONFIG_CRYPTO_USER_API_HASH", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_HMAC", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_SHA256", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_SHA256_SSSE3", &r); + } + + if (!l_checksum_is_supported(L_CHECKSUM_SHA512, true)) { + l_warn("No HMAC(SHA512) support found, " + "certain TLS connections might fail"); + l_hashmap_insert(options, "CONFIG_CRYPTO_SHA512", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_SHA512_SSSE3", &r); + } + + if (!l_cipher_is_supported(L_CIPHER_ARC4)) { + r = -ENOTSUP; + l_error("RC4 support not found"); + l_hashmap_insert(options, + "CONFIG_CRYPTO_USER_API_SKCIPHER", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_ARC4", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_ECB", &r); + } + + if (!l_cipher_is_supported(L_CIPHER_DES) || + !l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC)) { + r = -ENOTSUP; + l_error("DES support not found"); + l_hashmap_insert(options, + "CONFIG_CRYPTO_USER_API_SKCIPHER", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_DES", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_ECB", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_DES3_EDE_X86_64", &r); + } + + if (!l_cipher_is_supported(L_CIPHER_AES)) { + r = -ENOTSUP; + l_error("AES support not found"); + l_hashmap_insert(options, + "CONFIG_CRYPTO_USER_API_SKCIPHER", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_AES", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_ECB", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_AES_X86_64", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_AES_NI_INTEL", &r); + } + + if (!l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC)) { + l_warn("No CBC(DES3_EDE) support found, " + "certain TLS connections might fail"); + l_hashmap_insert(options, "CONFIG_CRYPTO_DES", &r); + l_hashmap_insert(options, "CONFIG_CRYPTO_CBC", &r); + l_hashmap_insert(optional, "CONFIG_CRYPTO_DES3_EDE_X86_64", &r); + } + + if (!l_cipher_is_supported(L_CIPHER_AES_CBC)) { + l_warn("No CBC(AES) support found, " + "WPS will not be available"); + l_hashmap_insert(options, "CONFIG_CRYPTO_CBC", &r); + } + + if (!l_key_is_supported(L_KEY_FEATURE_DH)) { + l_warn("No Diffie-Hellman support found, " + "WPS will not be available"); + l_hashmap_insert(options, "CONFIG_KEY_DH_OPERATIONS", &r); + } + + if (l_hashmap_isempty(options)) + goto done; + + l_info("The following options are missing in the kernel:"); + + if (l_hashmap_remove(options, "CONFIG_CRYPTO_USER_API_HASH")) + l_info("\tCONFIG_CRYPTO_USER_API_HASH"); + + if (l_hashmap_remove(options, "CONFIG_CRYPTO_USER_API_SKCIPHER")) + l_info("\tCONFIG_CRYPTO_USER_API_SKCIPHER"); + + l_hashmap_foreach(options, print_koption, NULL); + + l_info("The following optimized implementations might be available:"); + l_hashmap_foreach(optional, print_koption, NULL); + +done: + l_hashmap_destroy(options, NULL); + l_hashmap_destroy(optional, NULL); + + return r; +} + int main(int argc, char *argv[]) { bool enable_dbus_debug = false; @@ -228,6 +358,11 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } + l_log_set_stderr(); + + if (check_crypto() < 0) + return EXIT_FAILURE; + if (!l_main_init()) return EXIT_FAILURE; @@ -237,7 +372,6 @@ int main(int argc, char *argv[]) signal = l_signal_create(&mask, signal_handler, NULL, NULL); - l_log_set_stderr(); l_debug_enable("*"); #ifdef __GLIBC__