diff options
author | dimitri staessens <dimitri.staessens@ugent.be> | 2017-08-09 18:55:37 +0200 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@ugent.be> | 2017-08-09 20:48:27 +0200 |
commit | 24aa46946349529bf36d3569796a28917d3e756f (patch) | |
tree | 58ef8a40142323771eecbd8ce6c2eaea409bc138 /src | |
parent | c1d7ff1e1bd44e1a38af8a1b498c68f3378fa342 (diff) | |
download | ouroboros-24aa46946349529bf36d3569796a28917d3e756f.tar.gz ouroboros-24aa46946349529bf36d3569796a28917d3e756f.zip |
build, lib, ipcpd, irmd: Add support for libgcrypt
This adds support for libgcrypt. If at least version 1.7.0 of
libgcrypt is present, it may be used for secure random number
generation and is used for hashing in the irmd/ipcp.
The hash definitions are moved to the internal hash.h header, and
defined independently of the hashes that are defined as part of the
directory policy for the normal IPCP. The translation is moved from
the IRMd to ipcpd/ipcp.h. The bootstrap call from the IRMd expects the
IPCP to return the correct hash algorithm with a dif_info struct,
which is in line with the behavior of the enroll call.
This also improves how some platform checks in the build system are
handled.
Diffstat (limited to 'src')
-rw-r--r-- | src/ipcpd/ipcp.c | 53 | ||||
-rw-r--r-- | src/ipcpd/normal/dt_pci.c | 1 | ||||
-rw-r--r-- | src/ipcpd/shim-eth-llc/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/irmd/ipcp.c | 20 | ||||
-rw-r--r-- | src/irmd/ipcp.h | 3 | ||||
-rw-r--r-- | src/irmd/main.c | 29 | ||||
-rw-r--r-- | src/lib/CMakeLists.txt | 67 | ||||
-rw-r--r-- | src/lib/hash.c | 15 | ||||
-rw-r--r-- | src/lib/random.c | 11 | ||||
-rw-r--r-- | src/tools/irm/irm_ipcp_bootstrap.c | 13 |
10 files changed, 142 insertions, 76 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 48ff046c..b2afdf99 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -23,6 +23,7 @@ #define OUROBOROS_PREFIX "ipcpd/ipcp" #include <ouroboros/config.h> +#include <ouroboros/hash.h> #include <ouroboros/logs.h> #include <ouroboros/time_utils.h> #include <ouroboros/utils.h> @@ -174,7 +175,7 @@ static void * mainloop(void * o) strcpy(conf.dif_info.dif_name, conf_msg->dif_info->dif_name); if (conf.dif_info.dif_name == NULL) { - ret_msg.has_result = true; + log_err("No DIF name provided."); ret_msg.result = -1; break; } @@ -186,21 +187,55 @@ static void * mainloop(void * o) conf.dt_gam_type = conf_msg->dt_gam_type; conf.rm_gam_type = conf_msg->rm_gam_type; conf.routing_type = conf_msg->routing_type; - conf.dif_info.dir_hash_algo = - conf_msg->dif_info->dir_hash_algo; + + switch(conf_msg->dif_info->dir_hash_algo) { + case DIR_HASH_SHA3_224: + conf.dif_info.dir_hash_algo + = HASH_SHA3_224; + break; + case DIR_HASH_SHA3_256: + conf.dif_info.dir_hash_algo + = HASH_SHA3_256; + break; + case DIR_HASH_SHA3_384: + conf.dif_info.dir_hash_algo + = HASH_SHA3_384; + break; + case DIR_HASH_SHA3_512: + conf.dif_info.dir_hash_algo + = HASH_SHA3_512; + break; + default: + assert(false); + } + + dif_info.dir_hash_algo = + conf.dif_info.dir_hash_algo; } if (conf_msg->ipcp_type == IPCP_SHIM_UDP) { - conf.ip_addr = conf_msg->ip_addr; - conf.dns_addr = conf_msg->dns_addr; + conf.ip_addr = conf_msg->ip_addr; + conf.dns_addr = conf_msg->dns_addr; + dif_info.dir_hash_algo = HASH_MD5; + ipcpi.dir_hash_algo = HASH_MD5; } - if (conf_msg->ipcp_type == IPCP_SHIM_ETH_LLC) - conf.if_name = conf_msg->if_name; + if (conf_msg->ipcp_type == IPCP_SHIM_ETH_LLC) { + conf.if_name = conf_msg->if_name; + dif_info.dir_hash_algo = HASH_SHA3_256; + ipcpi.dir_hash_algo = HASH_SHA3_256; + } - ipcpi.dir_hash_algo = conf_msg->dif_info->dir_hash_algo; + if (conf_msg->ipcp_type == IPCP_LOCAL) { + dif_info.dir_hash_algo = HASH_SHA3_256; + ipcpi.dir_hash_algo = HASH_SHA3_256; + } ret_msg.result = ipcpi.ops->ipcp_bootstrap(&conf); + if (ret_msg.result == 0) { + ret_msg.dif_info = &dif_info; + dif_info.dif_name = conf.dif_info.dif_name; + } break; case IPCP_MSG_CODE__IPCP_ENROLL: ret_msg.has_result = true; @@ -220,7 +255,7 @@ static void * mainloop(void * o) ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name, &info); if (ret_msg.result == 0) { - ret_msg.dif_info = &dif_info; + ret_msg.dif_info = &dif_info; dif_info.dir_hash_algo = info.dir_hash_algo; dif_info.dif_name = info.dif_name; } diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c index a4f99142..2a252545 100644 --- a/src/ipcpd/normal/dt_pci.c +++ b/src/ipcpd/normal/dt_pci.c @@ -22,7 +22,6 @@ #include <ouroboros/config.h> #include <ouroboros/errno.h> -#include <ouroboros/crc32.h> #include <ouroboros/rib.h> #include "dt_pci.h" diff --git a/src/ipcpd/shim-eth-llc/CMakeLists.txt b/src/ipcpd/shim-eth-llc/CMakeLists.txt index 08f50c04..12bfb42e 100644 --- a/src/ipcpd/shim-eth-llc/CMakeLists.txt +++ b/src/ipcpd/shim-eth-llc/CMakeLists.txt @@ -32,12 +32,10 @@ add_executable(ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES} target_link_libraries(ipcpd-shim-eth-llc LINK_PUBLIC ouroboros ${PROTOBUF_C_LIBRARY}) -if (${NETMAP_C_INCLUDE_DIR} STREQUAL "NETMAP_C_INCLUDE_DIR-NOTFOUND") - message(STATUS "Could not find netmap. Install for better performance.") -else () +if (NOT ${NETMAP_C_INCLUDE_DIR} STREQUAL "NETMAP_C_INCLUDE_DIR-NOTFOUND") message(STATUS "Found netmap headers in ${NETMAP_C_INCLUDE_DIR}") include_directories(${NETMAP_C_INCLUDE_DIR}) - add_compile_flags(ipcpd-shim-eth-llc -DHAVE_NETMAP) + set(HAVE_NETMAP "1" CACHE STRING "Have netmap") test_and_set_c_compiler_flag_global(-std=c99) endif () diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index bf71bc3d..528e90a2 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -206,8 +206,9 @@ int ipcp_destroy(pid_t api) return 0; } -int ipcp_bootstrap(pid_t api, - ipcp_config_msg_t * conf) +int ipcp_bootstrap(pid_t api, + ipcp_config_msg_t * conf, + struct dif_info * info) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; @@ -229,6 +230,20 @@ int ipcp_bootstrap(pid_t api, } ret = recv_msg->result; + if (ret != 0) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return ret; + } + + if (recv_msg->dif_info == NULL) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return -EIPCP; + } + + info->dir_hash_algo = recv_msg->dif_info->dir_hash_algo; + strcpy(info->dif_name, recv_msg->dif_info->dif_name); + + ret = recv_msg->result; ipcp_msg__free_unpacked(recv_msg, NULL); return ret; @@ -269,7 +284,6 @@ int ipcp_enroll(pid_t api, } info->dir_hash_algo = recv_msg->dif_info->dir_hash_algo; - strcpy(info->dif_name, recv_msg->dif_info->dif_name); ipcp_msg__free_unpacked(recv_msg, NULL); diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index fde0428c..15ebb0ae 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -39,7 +39,8 @@ int ipcp_enroll(pid_t api, struct dif_info * info); int ipcp_bootstrap(pid_t api, - ipcp_config_msg_t * conf); + ipcp_config_msg_t * conf, + struct dif_info * info); int ipcp_reg(pid_t api, const uint8_t * hash, diff --git a/src/irmd/main.c b/src/irmd/main.c index 3f83ab2c..de4a07ab 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -59,10 +59,6 @@ #define SHM_SAN_HOLDOFF 1000 /* ms */ #define IPCP_HASH_LEN(e) hash_len(e->dir_hash_algo) -#define SHIM_ETH_LLC_HASH_ALGO HASH_SHA3_256 -#define SHIM_UDP_HASH_ALGO HASH_MD5 -#define LOCAL_HASH_ALGO HASH_SHA3_256 - struct ipcp_entry { struct list_head next; @@ -410,6 +406,7 @@ static int bootstrap_ipcp(pid_t api, ipcp_config_msg_t * conf) { struct ipcp_entry * entry = NULL; + struct dif_info info; pthread_rwlock_wrlock(&irmd.reg_lock); @@ -426,31 +423,21 @@ static int bootstrap_ipcp(pid_t api, return -1; } - if (entry->type == IPCP_LOCAL) - entry->dir_hash_algo = conf->dif_info->dir_hash_algo - = LOCAL_HASH_ALGO; - else if (entry->type == IPCP_SHIM_ETH_LLC) - entry->dir_hash_algo = conf->dif_info->dir_hash_algo - = SHIM_ETH_LLC_HASH_ALGO; - else if (entry->type == IPCP_SHIM_UDP) - entry->dir_hash_algo = conf->dif_info->dir_hash_algo - = SHIM_UDP_HASH_ALGO; - else - entry->dir_hash_algo = conf->dif_info->dir_hash_algo; - - if (ipcp_bootstrap(entry->api, conf)) { + if (ipcp_bootstrap(entry->api, conf, &info)) { pthread_rwlock_unlock(&irmd.reg_lock); log_err("Could not bootstrap IPCP."); return -1; } - entry->dif_name = strdup(conf->dif_info->dif_name); + entry->dif_name = strdup(info.dif_name); if (entry->dif_name == NULL) { pthread_rwlock_unlock(&irmd.reg_lock); log_warn("Failed to set name of DIF."); return -ENOMEM; } + entry->dir_hash_algo = info.dir_hash_algo; + pthread_rwlock_unlock(&irmd.reg_lock); log_info("Bootstrapped IPCP %d in DIF %s.", @@ -463,7 +450,7 @@ static int enroll_ipcp(pid_t api, char * dst_name) { struct ipcp_entry * entry = NULL; - struct dif_info info; + struct dif_info info; pthread_rwlock_wrlock(&irmd.reg_lock); @@ -813,8 +800,8 @@ static int name_reg(const char * name, if (ipcp_reg(e->api, hash, IPCP_HASH_LEN(e))) { log_err("Could not register " HASH_FMT - " in DIF %s.", - HASH_VAL(hash), e->dif_name); + " in DIF %s (IPCP %d).", + HASH_VAL(hash), e->dif_name, e->api); } else { if (registry_add_name_to_dif(&irmd.registry, name, diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index fe4dd88c..34bf5b1f 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -26,10 +26,48 @@ if (NOT LIBPTHREAD_LIBRARIES) message(FATAL_ERROR "Could not find libpthread.") endif () -find_path(LINUX_RND_HDR - sys/random.h - HINTS /usr/include /usr/local/include - ) +include(CheckSymbolExists) +list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200809L) +list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__XSI_VISIBLE=500) +list(APPEND CMAKE_REQUIRED_LIBRARIES pthread) +check_symbol_exists(pthread_mutexattr_setrobust pthread.h HAVE_ROBUST_MUTEX) +set(HAVE_ROBUST_MUTEX CACHE STRING "Have robust mutexes") + +find_library(LIBGCRYPT_LIBRARIES gcrypt) +if (LIBGCRYPT_LIBRARIES) + find_path(GCRYPT_INCLUDE_DIR gcrypt.h HINTS /usr/include /usr/local/include) + if (NOT ${GCRYPT_INCLUDE_DIR} STREQUAL "GRYPT_INCLUDE_DIR-NOTFOUND") + file(STRINGS ${GCRYPT_INCLUDE_DIR}/gcrypt.h GCSTR + REGEX "^#define GCRYPT_VERSION ") + string(REGEX REPLACE "^#define GCRYPT_VERSION \"(.*)\".*$" "\\1" + GCVER "${GCSTR}") + message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES} (found version \"${GCVER}\")") + if (NOT GCVER VERSION_LESS "1.7.0") + include_directories(${GCRYPT_INCLUDE_DIR}) + set(HAVE_LIBGCRYPT "1" CACHE STRING "Have libgcrypt") + endif() + endif () +endif () + +find_package(OpenSSL) +if (OPENSSL_FOUND) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(HAVE_OPENSSL "1" CACHE STRING "Have OpenSSL") +endif () + +find_path(LINUX_RND_HDR sys/random.h HINTS /usr/include/ /usr/local/include/) +if (NOT ${LINUX_RND_HDR} STREQUAL "LINUX_RND_HDR-NOTFOUND") + message(STATUS "Found sys/random.h in ${LINUX_RND_HDR}") + include_directories(${LINUX_RND_HDR}) + set(HAVE_SYS_RANDOM "1" CACHE STRING "Have Random Header") +endif () + +if (NOT ((CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") OR + HAVE_SYS_RANDOM OR HAVE_OPENSSL OR HAVE_LIBGCRYPT)) + message(FATAL_ERROR "No secure random generator found, " + "please install libgcrypt (> 1.7.0) or OpenSSL" + ) +endif () set(SOURCE_FILES # Add source files here @@ -71,26 +109,9 @@ if (CMAKE_BUILD_TYPE MATCHES Debug) add_compile_flags(ouroboros -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) -if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - message(STATUS "Found FreeBSD, using arc4random.") -else() - if (${LINUX_RND_HDR} STREQUAL "LINUX_RND_HDR-NOTFOUND") - find_package(OpenSSL) - if (NOT OPENSSL_FOUND) - message(FATAL_ERROR "No secure random generation, please install libssl.") - else() - include_directories($OPENSSL_INCLUDE_DIR}) - add_compile_flags(ouroboros -DHAVE_OPENSSL) - endif() - else () - message(STATUS "Found linux random header in ${LINUX_RND_HDR}.") - include_directories(${LINUX_RND_HDR}) - add_compile_flags(ouroboros -DHAVE_SYS_RANDOM) - endif () -endif() - target_link_libraries(ouroboros ${LIBRT_LIBRARIES} - ${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY} ${OPENSSL_LIBRARIES}) + ${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY} ${OPENSSL_LIBRARIES} + ${LIBGCRYPT_LIBRARIES}) install(TARGETS ouroboros LIBRARY DESTINATION usr/lib) diff --git a/src/lib/hash.c b/src/lib/hash.c index 9db3a276..088d43cd 100644 --- a/src/lib/hash.c +++ b/src/lib/hash.c @@ -27,12 +27,22 @@ #include <ouroboros/config.h> #include <ouroboros/hash.h> +#ifndef HAVE_LIBGCRYPT +#include <ouroboros/crc32.h> +#include <ouroboros/md5.h> +#include <ouroboros/sha3.h> +#else +#include <gcrypt.h> +#endif #include <string.h> #include <assert.h> #include <stdbool.h> uint16_t hash_len(enum hash_algo algo) { +#ifdef HAVE_LIBGCRYPT + return (uint16_t) gcry_md_get_algo_dlen(algo); +#else switch (algo) { case HASH_CRC32: return CRC32_HASH_LEN; @@ -52,12 +62,16 @@ uint16_t hash_len(enum hash_algo algo) } return 0; +#endif } void str_hash(enum hash_algo algo, void * buf, const char * str) { +#ifdef HAVE_LIBGCRYPT + gcry_md_hash_buffer(algo, buf, str, strlen(str)); +#else struct sha3_ctx sha3_ctx; struct md5_ctx md5_ctx; @@ -95,4 +109,5 @@ void str_hash(enum hash_algo algo, assert(false); break; } +#endif } diff --git a/src/lib/random.c b/src/lib/random.c index d6bde0f8..17973695 100644 --- a/src/lib/random.c +++ b/src/lib/random.c @@ -21,10 +21,13 @@ * 02110-1301 USA */ +#include <ouroboros/config.h> #include <ouroboros/random.h> #if defined(HAVE_SYS_RANDOM) #include <sys/random.h> +#elif defined(HAVE_LIBGCRYPT) +#include <grypt.h> #elif defined(__FreeBSD__) #include <stdlib.h> #elif defined(HAVE_OPENSSL) @@ -36,16 +39,14 @@ int random_buffer(void * buf, size_t len) { #if defined(HAVE_SYS_RANDOM) - return getrandom(buf, len, GRND_NONBLOCK); /* also in glibc 2.25 */ + return getrandom(buf, len, GRND_NONBLOCK); /* glibc 2.25 */ +#elif defined(HAVE_LIBGCRYPT) + return gcry_randomize(buf, len, GCRY_STRONG_RANDOM); #elif defined(__FreeBSD__) return arc4random_buf(buf, len); #elif defined(HAVE_OPENSSL) if (len > 0 && len < INT_MAX) return RAND_bytes((unsigned char *) buf, (int) len); return -1; -#else - (void) buf; - (void) len; - return -1; #endif } diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 6277dee4..571bff8b 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -39,7 +39,6 @@ #define SHIM_ETH_LLC "shim-eth-llc" #define LOCAL "local" -#define CRC32 "CRC32" #define MD5 "MD5" #define SHA3_224 "SHA3_224" #define SHA3_256 "SHA3_256" @@ -79,8 +78,8 @@ static void usage(void) " (default: %s)]\n" " [routing <routing policy> (default: %s)]\n" " [hash [ALGORITHM] (default: %s)]\n" - "where ALGORITHM = {" CRC32 " " MD5 " " - SHA3_224 " " SHA3_256 " " SHA3_384 " " SHA3_512 "}\n" + "where ALGORITHM = {" SHA3_224 " " SHA3_256 " " + SHA3_384 " " SHA3_512 "}\n" "if TYPE == " SHIM_UDP "\n" " ip <IP address in dotted notation>\n" " [dns <DDNS IP address in dotted notation>" @@ -104,7 +103,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) enum pol_gam dt_gam_type = DEFAULT_DT_GAM; enum pol_gam rm_gam_type = DEFAULT_RM_GAM; enum pol_routing routing_type = DEFAULT_ROUTING; - enum hash_algo hash_algo = DEFAULT_HASH_ALGO; + enum pol_dir_hash hash_algo = DEFAULT_HASH_ALGO; uint32_t ip_addr = 0; uint32_t dns_addr = DEFAULT_DDNS; char * ipcp_type = NULL; @@ -122,11 +121,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) } else if (matches(*argv, "name") == 0) { name = *(argv + 1); } else if (matches(*argv, "hash") == 0) { - if (strcmp(*(argv + 1), CRC32) == 0) - hash_algo = HASH_CRC32; - else if (strcmp(*(argv + 1), MD5) == 0) - hash_algo = HASH_MD5; - else if (strcmp(*(argv + 1), SHA3_224) == 0) + if (strcmp(*(argv + 1), SHA3_224) == 0) hash_algo = HASH_SHA3_224; else if (strcmp(*(argv + 1), SHA3_256) == 0) hash_algo = HASH_SHA3_256; |