diff options
| -rw-r--r-- | include/ouroboros/crc32.h | 2 | ||||
| -rw-r--r-- | include/ouroboros/hash.h | 17 | ||||
| -rw-r--r-- | include/ouroboros/ipcp.h | 4 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.c | 18 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.h | 7 | ||||
| -rw-r--r-- | src/ipcpd/local/main.c | 4 | ||||
| -rw-r--r-- | src/ipcpd/normal/dir.c | 6 | ||||
| -rw-r--r-- | src/ipcpd/normal/fmgr.c | 6 | ||||
| -rw-r--r-- | src/ipcpd/normal/main.c | 24 | ||||
| -rw-r--r-- | src/ipcpd/shim-data.c | 6 | ||||
| -rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 12 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/main.c | 12 | ||||
| -rw-r--r-- | src/irmd/ipcp.c | 1 | ||||
| -rw-r--r-- | src/irmd/main.c | 43 | ||||
| -rw-r--r-- | src/irmd/registry.c | 4 | ||||
| -rw-r--r-- | src/irmd/registry.h | 2 | ||||
| -rw-r--r-- | src/lib/hash.c | 69 | ||||
| -rw-r--r-- | src/lib/ipcp_config.proto | 2 | ||||
| -rw-r--r-- | src/lib/irm.c | 3 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_bootstrap.c | 113 | 
20 files changed, 231 insertions, 124 deletions
diff --git a/include/ouroboros/crc32.h b/include/ouroboros/crc32.h index dccdf7cb..800d6c4f 100644 --- a/include/ouroboros/crc32.h +++ b/include/ouroboros/crc32.h @@ -27,6 +27,8 @@  #include <stdint.h>  #include <stddef.h> +#define CRC32_HASH_LEN 4 +  void crc32(uint32_t *   crc,             const void * buf,             size_t       len); diff --git a/include/ouroboros/hash.h b/include/ouroboros/hash.h index a94b37ee..60bfbe30 100644 --- a/include/ouroboros/hash.h +++ b/include/ouroboros/hash.h @@ -28,6 +28,15 @@  #include <ouroboros/md5.h>  #include <ouroboros/sha3.h> +enum hash_algo { +        HASH_CRC32 = 0, +        HASH_MD5, +        HASH_SHA3_224, +        HASH_SHA3_256, +        HASH_SHA3_384, +        HASH_SHA3_512 +}; +  #define HASH_FMT "%02x%02x%02x%02x"  #define HASH_VAL(hash)                                 \          ((*(unsigned int *) hash) & 0xFF000000) >> 24, \ @@ -35,8 +44,10 @@          ((*(unsigned int *) hash) & 0x0000FF00) >> 8,  \          ((*(unsigned int *) hash) & 0x000000FF) -/* FIXME: Implement specifying algorithm */ -void get_hash(uint8_t      buf[], -              const char * name); +uint16_t hash_len(enum hash_algo algo); + +void str_hash(enum hash_algo algo, +              void *         buf, +              const char *   str);  #endif /* OUROBOROS_LIB_HASH_H */ diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index f439f29b..4c815b83 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -24,6 +24,8 @@  #ifndef OUROBOROS_IPCP_H  #define OUROBOROS_IPCP_H +#include <ouroboros/hash.h> +  #include <stdint.h>  #include <unistd.h>  #include <stdbool.h> @@ -51,7 +53,7 @@ enum pol_gam {  struct ipcp_config {          char *             dif_name;          enum ipcp_type     type; -        uint16_t           dir_hash_len; +        enum hash_algo     dir_hash_algo;          /* Normal DIF */          uint8_t            addr_size; diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 47c951f1..19607ee1 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -63,23 +63,23 @@ void ipcp_sig_handler(int         sig,  uint8_t * ipcp_hash_dup(const uint8_t * hash)  { -        uint8_t * dup = malloc(ipcpi.dir_hash_len); +        uint8_t * dup = malloc(hash_len(ipcpi.dir_hash_algo));          if (dup == NULL)                  return NULL; -        memcpy(dup, hash, ipcpi.dir_hash_len); +        memcpy(dup, hash, ipcp_dir_hash_len());          return dup;  } -void ipcp_hash_str(char            buf[DIR_HASH_STRLEN + 1], +void ipcp_hash_str(char *          buf,                     const uint8_t * hash)  {          size_t i;          char * HEX = "0123456789abcdef"; -        for (i = 0; i < ipcpi.dir_hash_len; ++i) { +        for (i = 0; i < ipcp_dir_hash_len(); ++i) {                  buf[i * 2]     = HEX[(hash[i] & 0xF0) >> 4];                  buf[i * 2 + 1] = HEX[hash[i] & 0x0F];          } @@ -212,7 +212,7 @@ static void * ipcp_main_loop(void * o)                          conf_msg = msg->conf;                          conf.type = conf_msg->ipcp_type; -                        conf.dir_hash_len = conf_msg->dir_hash_len; +                        conf.dir_hash_algo = conf_msg->dir_hash_algo;                          conf.dif_name = conf_msg->dif_name;                          if (conf.dif_name == NULL) {                                  ret_msg.has_result = true; @@ -270,7 +270,7 @@ static void * ipcp_main_loop(void * o)                                  break;                          } -                        assert(msg->hash.len == ipcpi.dir_hash_len); +                        assert(msg->hash.len == ipcp_dir_hash_len());                          ret_msg.result =                                  ipcpi.ops->ipcp_reg(msg->hash.data); @@ -284,7 +284,7 @@ static void * ipcp_main_loop(void * o)                                  break;                          } -                        assert(msg->hash.len == ipcpi.dir_hash_len); +                        assert(msg->hash.len == ipcp_dir_hash_len());                          ret_msg.result =                                  ipcpi.ops->ipcp_unreg(msg->hash.data); @@ -298,7 +298,7 @@ static void * ipcp_main_loop(void * o)                                  break;                          } -                        assert(msg->hash.len == ipcpi.dir_hash_len); +                        assert(msg->hash.len == ipcp_dir_hash_len());                          if (ipcp_get_state() != IPCP_OPERATIONAL) {                                  log_err("IPCP in wrong state."); @@ -318,7 +318,7 @@ static void * ipcp_main_loop(void * o)                                  break;                          } -                        assert(msg->hash.len == ipcpi.dir_hash_len); +                        assert(msg->hash.len == ipcp_dir_hash_len());                          if (ipcp_get_state() != IPCP_OPERATIONAL) {                                  log_err("IPCP in wrong state."); diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index d6e2aa7c..c78aa5a6 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -24,6 +24,7 @@  #define IPCPD_IPCP_H  #include <ouroboros/config.h> +#include <ouroboros/hash.h>  #include <ouroboros/ipcp.h>  #include "shim-data.h" @@ -60,7 +61,8 @@ struct ipcp_ops {          int   (* ipcp_flow_dealloc)(int fd);  }; -#define DIR_HASH_STRLEN (ipcpi.dir_hash_len * 2) +#define ipcp_dir_hash_strlen() (hash_len(ipcpi.dir_hash_algo) * 2) +#define ipcp_dir_hash_len() (hash_len(ipcpi.dir_hash_algo))  struct ipcp {          int                irmd_api; @@ -70,7 +72,8 @@ struct ipcp {          char *             dif_name;          uint64_t           dt_addr; -        uint16_t           dir_hash_len; + +        enum hash_algo     dir_hash_algo;          struct ipcp_ops *  ops;          int                irmd_fd; diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 21ca7400..162ce4d9 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -119,7 +119,7 @@ static int ipcp_local_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); -        ipcpi.dir_hash_len = conf->dir_hash_len; +        ipcpi.dir_hash_algo = conf->dir_hash_algo;          ipcp_set_state(IPCP_OPERATIONAL); @@ -198,7 +198,7 @@ static int ipcp_local_flow_alloc(int             fd,          assert(ipcpi.alloc_id == -1); -        out_fd = ipcp_flow_req_arr(getpid(), dst, ipcpi.dir_hash_len, cube); +        out_fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);          if (out_fd < 0) {                  pthread_mutex_unlock(&ipcpi.alloc_lock);                  log_dbg("Flow allocation failed: %d", out_fd); diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index 0249ba06..5ea8a300 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -62,7 +62,7 @@ int dir_fini(void)  int dir_reg(const uint8_t * hash)  { -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          int ret;          assert(hash); @@ -91,7 +91,7 @@ int dir_reg(const uint8_t * hash)  int dir_unreg(const uint8_t * hash)  { -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          size_t len;          assert(hash); @@ -121,7 +121,7 @@ int dir_unreg(const uint8_t * hash)  int dir_query(const uint8_t * hash)  { -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          size_t len;          dir_path_reset(); diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index 5166cc5d..ba36812f 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -439,7 +439,7 @@ int fmgr_np1_alloc(int             fd,          ssize_t          ch;          ssize_t          i;          char **          children; -        char             hashstr[DIR_HASH_STRLEN + 1]; +        char             hashstr[ipcp_dir_hash_strlen() + 1];          char *           dst_ipcp = NULL;          ipcp_hash_str(hashstr, dst); @@ -477,7 +477,7 @@ int fmgr_np1_alloc(int             fd,          msg.code        = FLOW_ALLOC_CODE__FLOW_REQ;          msg.has_hash    = true; -        msg.hash.len    = ipcpi.dir_hash_len; +        msg.hash.len    = ipcp_dir_hash_len();          msg.hash.data   = (uint8_t *) dst;          msg.has_qoscube = true;          msg.qoscube     = cube; @@ -663,7 +663,7 @@ int fmgr_np1_post_buf(cep_id_t   cep_id,                  fd = ipcp_flow_req_arr(getpid(),                                         msg->hash.data, -                                       ipcpi.dir_hash_len, +                                       ipcp_dir_hash_len(),                                         msg->qoscube);                  if (fd < 0) {                          pthread_mutex_unlock(&ipcpi.alloc_lock); diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index e37a0fbc..67424914 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -69,16 +69,16 @@ static int boot_components(void)                  return -1;          } -        len = rib_read(BOOT_PATH "/general/dir_hash_len", -                       &ipcpi.dir_hash_len, sizeof(ipcpi.dir_hash_len)); +        len = rib_read(BOOT_PATH "/general/dir_hash_algo", +                       &ipcpi.dir_hash_algo, sizeof(ipcpi.dir_hash_algo));          if (len < 0) {                  log_err("Failed to read hash length: %zd.", len);                  return -1;          } -        ipcpi.dir_hash_len = ntoh16(ipcpi.dir_hash_len); +        ipcpi.dir_hash_algo = ntoh32(ipcpi.dir_hash_algo); -        assert(ipcpi.dir_hash_len != 0); +        assert(ipcp_dir_hash_len() != 0);          if (rib_add(MEMBERS_PATH, ipcpi.name)) {                  log_err("Failed to add name to " MEMBERS_PATH); @@ -229,7 +229,7 @@ static int normal_ipcp_enroll(const char * dst)          log_dbg("Enrolled with " HASH_FMT, HASH_VAL(dst)); -        return 0; +        return ipcpi.dir_hash_algo;  }  const struct ros { @@ -245,7 +245,7 @@ const struct ros {          {BOOT_PATH, "general"},          {BOOT_PATH "/general", "dif_name"}, -        {BOOT_PATH "/general", "dir_hash_len"}, +        {BOOT_PATH "/general", "dir_hash_algo"},          /* DT COMPONENT */          {BOOT_PATH, "dt"}, @@ -293,14 +293,14 @@ int normal_rib_init(void)  static int normal_ipcp_bootstrap(const struct ipcp_config * conf)  { -        uint16_t hash_len; +        uint32_t hash_algo;          assert(conf);          assert(conf->type == THIS_TYPE); -        hash_len = hton16((uint16_t) conf->dir_hash_len); +        hash_algo = hton32((uint32_t) conf->dir_hash_algo); -        assert(ntoh16(hash_len) != 0); +        assert(ntoh32(hash_algo) != 0);          if (normal_rib_init()) {                  log_err("Failed to write initial structure to the RIB."); @@ -310,9 +310,9 @@ static int normal_ipcp_bootstrap(const struct ipcp_config * conf)          if (rib_write(BOOT_PATH "/general/dif_name",                        conf->dif_name,                        strlen(conf->dif_name) + 1) || -            rib_write(BOOT_PATH "/general/dir_hash_len", -                      &hash_len, -                      sizeof(hash_len)) || +            rib_write(BOOT_PATH "/general/dir_hash_algo", +                      &hash_algo, +                      sizeof(hash_algo)) ||              rib_write(BOOT_PATH "/dt/const/addr_size",                        &conf->addr_size,                        sizeof(conf->addr_size)) || diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index 4459837d..2ef48cb0 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -187,7 +187,7 @@ static struct reg_entry * find_reg_entry_by_hash(struct shim_data * data,          list_for_each(h, &data->registry) {                  struct reg_entry * e = list_entry(h, struct reg_entry, list); -                if (!memcmp(e->hash, hash, ipcpi.dir_hash_len)) +                if (!memcmp(e->hash, hash, ipcp_dir_hash_len()))                          return e;          } @@ -202,7 +202,7 @@ static struct dir_entry * find_dir_entry(struct shim_data * data,          list_for_each(h, &data->directory) {                  struct dir_entry * e = list_entry(h, struct dir_entry, list);                  if (e->addr == addr && -                    !memcmp(e->hash, hash, ipcpi.dir_hash_len)) +                    !memcmp(e->hash, hash, ipcp_dir_hash_len()))                          return e;          } @@ -215,7 +215,7 @@ static struct dir_entry * find_dir_entry_any(struct shim_data * data,          struct list_head * h;          list_for_each(h, &data->directory) {                  struct dir_entry * e = list_entry(h, struct dir_entry, list); -                if (!memcmp(e->hash, hash, ipcpi.dir_hash_len)) +                if (!memcmp(e->hash, hash, ipcp_dir_hash_len()))                          return e;          } diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 5ac3bb6f..36cb12c4 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -350,7 +350,7 @@ static int eth_llc_ipcp_sap_alloc(const uint8_t * dst_addr,          msg.has_ssap    = true;          msg.ssap        = ssap;          msg.has_hash    = true; -        msg.hash.len    = ipcpi.dir_hash_len; +        msg.hash.len    = ipcp_dir_hash_len();          msg.hash.data   = (uint8_t *) hash;          msg.has_qoscube = true;          msg.qoscube     = cube; @@ -398,7 +398,7 @@ static int eth_llc_ipcp_sap_req(uint8_t         r_sap,          }          /* reply to IRM, called under lock to prevent race */ -        fd = ipcp_flow_req_arr(getpid(), dst, ipcpi.dir_hash_len, cube); +        fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);          if (fd < 0) {                  pthread_mutex_unlock(&ipcpi.alloc_lock);                  log_err("Could not get new flow from IRMd."); @@ -464,7 +464,7 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * hash,          if (shim_data_reg_has(ipcpi.shim_data, hash)) {                  msg.code      = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REPLY;                  msg.has_hash  = true; -                msg.hash.len  = ipcpi.dir_hash_len; +                msg.hash.len  = ipcp_dir_hash_len();                  msg.hash.data = (uint8_t *) hash;                  eth_llc_ipcp_send_mgmt_frame(&msg, r_addr); @@ -487,7 +487,7 @@ static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,          list_for_each(pos, &ipcpi.shim_data->dir_queries) {                  struct dir_query * e =                          list_entry(pos, struct dir_query, next); -                if (memcmp(e->hash, hash, ipcpi.dir_hash_len) == 0) { +                if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) {                          shim_data_dir_query_respond(e);                  }          } @@ -758,7 +758,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); -        ipcpi.dir_hash_len = conf->dir_hash_len; +        ipcpi.dir_hash_algo = conf->dir_hash_algo;          if (conf->if_name == NULL) {                  log_err("Interface name is NULL."); @@ -942,7 +942,7 @@ static int eth_llc_ipcp_query(const uint8_t * hash)          msg.code      = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REQ;          msg.has_hash  = true; -        msg.hash.len  = ipcpi.dir_hash_len; +        msg.hash.len  = ipcp_dir_hash_len();          msg.hash.data = (uint8_t *) hash;          memset(r_addr, 0xff, MAC_SIZE); diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index e1fe5c7c..20e9b272 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -206,7 +206,7 @@ static int ipcp_udp_port_alloc(uint32_t  dst_ip_addr,          msg.code         = SHIM_UDP_MSG_CODE__FLOW_REQ;          msg.src_udp_port = src_udp_port;          msg.has_hash     = true; -        msg.hash.len     = ipcpi.dir_hash_len; +        msg.hash.len     = ipcp_dir_hash_len();          msg.hash.data    = (uint8_t *) dst;          msg.has_qoscube  = true;          msg.qoscube      = cube; @@ -286,7 +286,7 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,          }          /* reply to IRM */ -        fd = ipcp_flow_req_arr(getpid(), dst, ipcpi.dir_hash_len, cube); +        fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);          if (fd < 0) {                  pthread_mutex_unlock(&ipcpi.alloc_lock);                  log_err("Could not get new flow from IRMd."); @@ -534,7 +534,7 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); -        ipcpi.dir_hash_len = conf->dir_hash_len; +        ipcpi.dir_hash_algo = conf->dir_hash_algo;          if (inet_ntop(AF_INET,                        &conf->ip_addr, @@ -749,7 +749,7 @@ static int ipcp_udp_reg(const uint8_t * hash)          uint32_t dns_addr;          uint32_t ip_addr;  #endif -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          uint8_t * hash_dup;          assert(hash); @@ -809,7 +809,7 @@ static int ipcp_udp_unreg(const uint8_t * hash)          char cmd[100];          uint32_t dns_addr;  #endif -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          assert(hash); @@ -846,7 +846,7 @@ static int ipcp_udp_query(const uint8_t * hash)  #ifdef CONFIG_OUROBOROS_ENABLE_DNS          uint32_t           dns_addr = 0;  #endif -        char hashstr[DIR_HASH_STRLEN + 1]; +        char hashstr[ipcp_dir_hash_strlen() + 1];          assert(hash); diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index f0e57dc8..7a32dd88 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -212,6 +212,7 @@ int ipcp_bootstrap(pid_t              api,          return ret;  } +/* return the hash algorithm */  int ipcp_enroll(pid_t        api,                  const char * dst)  { diff --git a/src/irmd/main.c b/src/irmd/main.c index bdc03ef8..7e118f81 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -37,7 +37,6 @@  #include <ouroboros/qos.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/logs.h> -#include <ouroboros/sha3.h>  #include "utils.h"  #include "registry.h" @@ -57,6 +56,7 @@  #define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */  #define SHM_SAN_HOLDOFF 1000 /* ms */ +#define IPCP_HASH_LEN(e) (hash_len(e->dir_hash_algo))  struct ipcp_entry {          struct list_head next; @@ -64,8 +64,7 @@ struct ipcp_entry {          char *           name;          pid_t            api;          enum ipcp_type   type; -        uint16_t         dir_hash_len; -        /* FIXME: add an enum to specify hash algo */ +        enum hash_algo   dir_hash_algo;          char *           dif_name;          pthread_cond_t   init_cond; @@ -239,13 +238,15 @@ static struct ipcp_entry * get_ipcp_by_dst_name(const char * name)          list_for_each(p, &irmd.ipcps) {                  struct ipcp_entry * e =                          list_entry(p, struct ipcp_entry, next); -                hash = malloc(e->dir_hash_len); +                if (e->dir_hash_algo < 0) +                        continue; +                hash = malloc(IPCP_HASH_LEN(e));                  if  (hash == NULL)                          return NULL; -                get_hash(hash, name); +                str_hash(e->dir_hash_algo, hash, name); -                if (ipcp_query(e->api, hash, e->dir_hash_len) == 0) { +                if (ipcp_query(e->api, hash, hash_len(e->dir_hash_algo)) == 0) {                          free(hash);                          return e;                  } @@ -306,8 +307,7 @@ static pid_t create_ipcp(char *         name,          tmp->dif_name = NULL;          tmp->type = ipcp_type;          tmp->init = false; -        /* FIXME: ipcp dir_hash_len should be configurable */ -        tmp->dir_hash_len = SHA3_256_HASH_LEN; +        tmp->dir_hash_algo = -1;          list_for_each(p, &irmd.ipcps) {                  struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); @@ -434,6 +434,8 @@ static int bootstrap_ipcp(pid_t              api,                  return -ENOMEM;          } +        entry->dir_hash_algo = conf->dir_hash_algo; +          pthread_rwlock_unlock(&irmd.reg_lock);          log_info("Bootstrapped IPCP %d in DIF %s.", @@ -471,7 +473,8 @@ static int enroll_ipcp(pid_t  api,          pthread_rwlock_unlock(&irmd.reg_lock); -        if (ipcp_enroll(api, dif_name)) { +        entry->dir_hash_algo = ipcp_enroll(api, dif_name); +        if (entry->dir_hash_algo < 0) {                  pthread_rwlock_wrlock(&irmd.reg_lock);                  free(entry->dif_name);                  entry->dif_name = NULL; @@ -766,13 +769,13 @@ static int name_reg(const char *  name,                          if (wildcard_match(difs[i], e->dif_name))                                  continue; -                        hash = malloc(e->dir_hash_len); +                        hash = malloc(IPCP_HASH_LEN(e));                          if  (hash == NULL)                                  break; -                        get_hash(hash, name); +                        str_hash(e->dir_hash_algo, hash, name); -                        if (ipcp_reg(e->api, hash, e->dir_hash_len)) { +                        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); @@ -826,13 +829,13 @@ static int name_unreg(const char *  name,                          if (wildcard_match(difs[i], e->dif_name))                                  continue; -                        hash = malloc(e->dir_hash_len); +                        hash = malloc(IPCP_HASH_LEN(e));                          if  (hash == NULL)                                  break; -                        get_hash(hash, name); +                        str_hash(e->dir_hash_algo, hash, name); -                        if (ipcp_unreg(e->api, hash, e->dir_hash_len)) { +                        if (ipcp_unreg(e->api, hash, IPCP_HASH_LEN(e))) {                                  log_err("Could not unregister %s in DIF %s.",                                          name, e->dif_name);                          } else { @@ -1097,16 +1100,16 @@ static int flow_alloc(pid_t              api,          assert(irm_flow_get_state(f) == FLOW_ALLOC_PENDING); -        hash = malloc(ipcp->dir_hash_len); +        hash = malloc(IPCP_HASH_LEN(ipcp));          if  (hash == NULL) {                  /* sanitizer cleans this */                  return -ENOMEM;          } -        get_hash(hash, dst); +        str_hash(ipcp->dir_hash_algo, hash, dst);          if (ipcp_flow_alloc(ipcp->api, port_id, api, hash, -                            ipcp->dir_hash_len, cube)) { +                            IPCP_HASH_LEN(ipcp), cube)) {                  /* sanitizer cleans this */                  log_info("Flow_allocation failed.");                  free(hash); @@ -1248,8 +1251,8 @@ static struct irm_flow * flow_req_arr(pid_t           api,                  return NULL;          } -        re = registry_get_entry_by_hash(&irmd.registry, hash, -                                        ipcp->dir_hash_len); +        re = registry_get_entry_by_hash(&irmd.registry, ipcp->dir_hash_algo, +                                        hash, IPCP_HASH_LEN(ipcp));          if (re == NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock);                  log_err("Unknown hash: " HASH_FMT ".", HASH_VAL(hash)); diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 71e6ea8a..e6571564 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -27,7 +27,6 @@  #include <ouroboros/logs.h>  #include <ouroboros/irm.h>  #include <ouroboros/time_utils.h> -#include <ouroboros/hash.h>  #include "registry.h"  #include "utils.h" @@ -522,6 +521,7 @@ struct reg_entry * registry_get_entry(struct list_head * registry,  }  struct reg_entry * registry_get_entry_by_hash(struct list_head * registry, +                                              enum hash_algo     algo,                                                const uint8_t *    hash,                                                size_t             len)  { @@ -536,7 +536,7 @@ struct reg_entry * registry_get_entry_by_hash(struct list_head * registry,          list_for_each(p, registry) {                  struct reg_entry * e = list_entry(p, struct reg_entry, next); -                get_hash(thash, e->name); +                str_hash(algo, thash, e->name);                  if (memcmp(thash, hash, len) == 0) {                          free(thash);                          return e; diff --git a/src/irmd/registry.h b/src/irmd/registry.h index 771ca83c..29cefc02 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -24,6 +24,7 @@  #define OUROBOROS_IRMD_REGISTRY_H  #include <ouroboros/config.h> +#include <ouroboros/hash.h>  #include <ouroboros/ipcp.h>  #include <ouroboros/list.h>  #include <ouroboros/shared.h> @@ -115,6 +116,7 @@ struct reg_entry *  registry_get_entry(struct list_head * registry,                                         const char *       name);  struct reg_entry *  registry_get_entry_by_hash(struct list_head * registry, +                                               enum hash_algo     algo,                                                 const uint8_t *    hash,                                                 size_t             len); diff --git a/src/lib/hash.c b/src/lib/hash.c index f4fd75ea..e7806d94 100644 --- a/src/lib/hash.c +++ b/src/lib/hash.c @@ -28,16 +28,69 @@  #include <ouroboros/hash.h>  #include <string.h> +#include <assert.h> +#include <stdbool.h> -void get_hash(uint8_t      buf[], -              const char * name) +uint16_t hash_len(enum hash_algo algo)  { -        /* currently we only support 256 bit SHA-3 */ -        struct sha3_ctx ctx; - -        rhash_sha3_256_init(&ctx); +        switch (algo) { +        case HASH_CRC32: +                return CRC32_HASH_LEN; +        case HASH_MD5: +                return MD5_HASH_LEN; +        case HASH_SHA3_224: +                return SHA3_224_HASH_LEN; +        case HASH_SHA3_256: +                return SHA3_256_HASH_LEN; +        case HASH_SHA3_384: +                return SHA3_384_HASH_LEN; +        case HASH_SHA3_512: +                return SHA3_512_HASH_LEN; +        default: +                assert(false); +                break; +        } +} -        rhash_sha3_update(&ctx, name, strlen(name)); +void str_hash(enum hash_algo algo, +              void *         buf, +              const char *   str) +{ +        struct sha3_ctx sha3_ctx; +        struct md5_ctx md5_ctx; -        rhash_sha3_final(&ctx, buf); +        switch (algo) { +        case HASH_CRC32: +                memset(buf, 0, CRC32_HASH_LEN); +                crc32((uint32_t *) buf, str, strlen(str)); +                break; +        case HASH_MD5: +                rhash_md5_init(&md5_ctx); +                rhash_md5_update(&md5_ctx, str, strlen(str)); +                rhash_md5_final(&md5_ctx, (uint8_t *) buf); +                break; +        case HASH_SHA3_224: +                rhash_sha3_224_init(&sha3_ctx); +                rhash_sha3_update(&sha3_ctx, str, strlen(str)); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                break; +        case HASH_SHA3_256: +                rhash_sha3_256_init(&sha3_ctx); +                rhash_sha3_update(&sha3_ctx, str, strlen(str)); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                break; +        case HASH_SHA3_384: +                rhash_sha3_384_init(&sha3_ctx); +                rhash_sha3_update(&sha3_ctx, str, strlen(str)); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                break; +        case HASH_SHA3_512: +                rhash_sha3_512_init(&sha3_ctx); +                rhash_sha3_update(&sha3_ctx, str, strlen(str)); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                break; +        default: +                assert(false); +                break; +        }  } diff --git a/src/lib/ipcp_config.proto b/src/lib/ipcp_config.proto index a0c14c41..d5ff75d6 100644 --- a/src/lib/ipcp_config.proto +++ b/src/lib/ipcp_config.proto @@ -25,7 +25,7 @@ syntax = "proto2";  message ipcp_config_msg {          required string dif_name        =  1; -        required uint32 dir_hash_len    =  2; +        required uint32 dir_hash_algo   =  2;          required int32 ipcp_type        =  3;          // Config for normal IPCP          optional uint32 addr_size       =  4; diff --git a/src/lib/irm.c b/src/lib/irm.c index a2fd5d0b..12d8e8f7 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -23,6 +23,7 @@  #include <ouroboros/config.h>  #include <ouroboros/errno.h> +#include <ouroboros/hash.h>  #include <ouroboros/irm.h>  #include <ouroboros/utils.h>  #include <ouroboros/sockets.h> @@ -105,7 +106,7 @@ int irm_bootstrap_ipcp(pid_t                      api,          msg.conf = &config;          config.dif_name = conf->dif_name;          config.ipcp_type = conf->type; -        config.dir_hash_len = (uint16_t) conf->dir_hash_len; +        config.dir_hash_algo = (enum hash_algo) conf->dir_hash_algo;          switch (conf->type) {          case IPCP_NORMAL: diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 489f98b9..32c09b55 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -34,25 +34,34 @@  #include "irm_ops.h"  #include "irm_utils.h" -#define NORMAL "normal" -#define SHIM_UDP "shim-udp" -#define SHIM_ETH_LLC "shim-eth-llc" -#define LOCAL "local" +#define NORMAL               "normal" +#define SHIM_UDP             "shim-udp" +#define SHIM_ETH_LLC         "shim-eth-llc" +#define LOCAL                "local" -#define DEFAULT_ADDR_SIZE 4 -#define DEFAULT_CEP_ID_SIZE 2 +#define CRC32                "CRC32" +#define MD5                  "MD5" +#define SHA3_224             "SHA3_224" +#define SHA3_256             "SHA3_256" +#define SHA3_384             "SHA3_384" +#define SHA3_512             "SHA3_512" + +#define DEFAULT_HASH_ALGO    HASH_SHA3_256 +#define DEFAULT_HASH_STR     SHA3_256 +#define DEFAULT_ADDR_SIZE    4 +#define DEFAULT_CEP_ID_SIZE  2  #define DEFAULT_PDU_LEN_SIZE 2 -#define DEFAULT_SEQ_NO_SIZE 4 +#define DEFAULT_SEQ_NO_SIZE  4  #define DEFAULT_MIN_PDU_SIZE 0  #define DEFAULT_MAX_PDU_SIZE 9000 -#define DEFAULT_DDNS 0 -#define DEFAULT_ADDR_AUTH FLAT_RANDOM -#define DEFAULT_DT_GAM COMPLETE -#define DEFAULT_RM_GAM COMPLETE +#define DEFAULT_DDNS         0 +#define DEFAULT_ADDR_AUTH    FLAT_RANDOM +#define DEFAULT_DT_GAM       COMPLETE +#define DEFAULT_RM_GAM       COMPLETE +#define ADDR_AUTH_FLAT       "flat" -#define ADDR_AUTH_FLAT  "flat" -#define DT_GAM_COMPLETE "complete" -#define RM_GAM_COMPLETE "complete" +#define DT_GAM_COMPLETE      "complete" +#define RM_GAM_COMPLETE      "complete"  static void usage(void)  { @@ -61,9 +70,11 @@ static void usage(void)                 "                name <ipcp name>\n"                 "                dif <DIF name>\n"                 "                type [TYPE]\n" -/* FIXME: add option to set hash algorithm and length for directory */ +               "                [hash [ALGORITHM] (default: %s)]\n"                 "where TYPE = {" NORMAL " " LOCAL " " -               SHIM_UDP " " SHIM_ETH_LLC"}\n\n" +               SHIM_UDP " " SHIM_ETH_LLC"},\n" +               "      ALGORITHM = { " CRC32 " " MD5 " " +               SHA3_224 " " SHA3_256 " " SHA3_384 " " SHA3_512 "}.\n\n"                 "if TYPE == " NORMAL "\n"                 "                [addr <address size> (default: %d)]\n"                 "                [cep_id <CEP-id size> (default: %d)]\n" @@ -75,16 +86,16 @@ static void usage(void)                 "                [max_pdu <maximum PDU size> (default: %d)]\n"                 "                [addr_auth <address policy> (default: %s)]\n"                 "                [dt_gam <data transfer graph adjacency manager>" -               "(default: %s)]\n" +               " (default: %s)]\n"                 "                [rm_gam <rib manager graph adjacency manager>" -               "(default: %s)]\n" +               " (default: %s)]\n"                 "if TYPE == " SHIM_UDP "\n"                 "                ip <IP address in dotted notation>\n"                 "                [dns <DDNS IP address in dotted notation>"                 " (default = none: %d)]\n"                 "if TYPE == " SHIM_ETH_LLC "\n"                 "                if_name <interface name>\n", -               DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE, +               DEFAULT_HASH_STR, DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE,                 DEFAULT_PDU_LEN_SIZE, DEFAULT_SEQ_NO_SIZE,                 DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE,                 ADDR_AUTH_FLAT, DT_GAM_COMPLETE, RM_GAM_COMPLETE, DEFAULT_DDNS); @@ -92,29 +103,29 @@ static void usage(void)  int do_bootstrap_ipcp(int argc, char ** argv)  { -        char * name = NULL; -        pid_t api; +        char *             name            = NULL; +        char *             hash            = DEFAULT_HASH_STR; +        pid_t              api;          struct ipcp_config conf; -        uint8_t addr_size = DEFAULT_ADDR_SIZE; -        uint8_t cep_id_size = DEFAULT_CEP_ID_SIZE; -        uint8_t pdu_length_size = DEFAULT_PDU_LEN_SIZE; -        uint8_t seqno_size = DEFAULT_SEQ_NO_SIZE; -        bool has_ttl = false; -        bool has_chk = false; -        uint32_t min_pdu_size = DEFAULT_MIN_PDU_SIZE; -        uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE; -        enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH; -        enum pol_gam dt_gam_type = DEFAULT_DT_GAM; -        enum pol_gam rm_gam_type = DEFAULT_RM_GAM; -        uint32_t ip_addr = 0; -        uint32_t dns_addr = DEFAULT_DDNS; -        char * ipcp_type = NULL; -        char * dif_name = NULL; -        char * if_name = NULL; -        pid_t * apis = NULL; -        ssize_t len = 0; -        int i = 0; -        uint16_t dir_hash_len =  SHA3_256_HASH_LEN; +        uint8_t            addr_size       = DEFAULT_ADDR_SIZE; +        uint8_t            cep_id_size     = DEFAULT_CEP_ID_SIZE; +        uint8_t            pdu_length_size = DEFAULT_PDU_LEN_SIZE; +        uint8_t            seqno_size      = DEFAULT_SEQ_NO_SIZE; +        bool               has_ttl         = false; +        bool               has_chk         = false; +        uint32_t           min_pdu_size    = DEFAULT_MIN_PDU_SIZE; +        uint32_t           max_pdu_size    = DEFAULT_MAX_PDU_SIZE; +        enum pol_addr_auth addr_auth_type  = DEFAULT_ADDR_AUTH; +        enum pol_gam       dt_gam_type     = DEFAULT_DT_GAM; +        enum pol_gam       rm_gam_type     = DEFAULT_RM_GAM; +        uint32_t           ip_addr         = 0; +        uint32_t           dns_addr        = DEFAULT_DDNS; +        char *             ipcp_type       = NULL; +        char *             dif_name        = NULL; +        char *             if_name         = NULL; +        pid_t *            apis            = NULL; +        ssize_t            len             = 0; +        int                i               = 0;          while (argc > 0) {                  if (matches(*argv, "type") == 0) { @@ -123,6 +134,8 @@ int do_bootstrap_ipcp(int argc, char ** argv)                          dif_name = *(argv + 1);                  } else if (matches(*argv, "name") == 0) {                          name = *(argv + 1); +                } else if (matches(*argv, "hash") == 0) { +                        hash = *(argv + 1);                  } else if (matches(*argv, "ip") == 0) {                          if (inet_pton (AF_INET, *(argv + 1), &ip_addr) != 1) {                                  usage(); @@ -180,7 +193,23 @@ int do_bootstrap_ipcp(int argc, char ** argv)          }          conf.dif_name = dif_name; -        conf.dir_hash_len = dir_hash_len; + +        if (strcmp(hash, CRC32) == 0) { +                conf.dir_hash_algo = HASH_CRC32; +        } else if (strcmp(hash, MD5) == 0) { +                conf.dir_hash_algo = HASH_MD5; +        } else if (strcmp(hash, SHA3_224) == 0) { +                conf.dir_hash_algo = HASH_SHA3_224; +        } else if (strcmp(hash, SHA3_256) == 0) { +                conf.dir_hash_algo = HASH_SHA3_256; +        } else if (strcmp(hash, SHA3_384) == 0) { +                conf.dir_hash_algo = HASH_SHA3_384; +        } else if (strcmp(hash, SHA3_512) == 0) { +                conf.dir_hash_algo = HASH_SHA3_512; +        } else { +                usage(); +                return -1; +        }          if (strcmp(ipcp_type, NORMAL) == 0) {                  conf.type = IPCP_NORMAL;  | 
