]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: Changes to support hash algo in keychain.
authorAbhinay Ramesh <rabhinay@vmware.com>
Tue, 11 May 2021 10:00:38 +0000 (10:00 +0000)
committerAbhinay Ramesh <rabhinay@vmware.com>
Wed, 9 Feb 2022 01:49:14 +0000 (01:49 +0000)
Problem Statement:
==================
Currently there is no support for configuring hash algorithm in
keychain. 
 
RCA:
====
Not implemented yet.
 
Fix:
====
Changes are done to configure hash algorithm as part of keychain.
which will easy the configuration from modules using keychain.
 
Risk:
=====
Low risk
 
Tests Executed:
===============
Have tested the configuration and unconfiguration flow for newly
implemented CLI.

!
key chain abcd
 key 100
  key-string password
  cryptographic-algorithm sha1
 exit
 key 200
  key-string password
  cryptographic-algorithm sha256
 exit
!

Signed-off-by: Abhinay Ramesh <rabhinay@vmware.com>
lib/keychain.c
lib/keychain.h

index 1d678b949e8d11ebb521245b9b686b9c8e6e9a4c..6b03fbd56053dafbcc39d335cd6619d129d54c2b 100644 (file)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include <zebra.h>
 
 #include "command.h"
@@ -207,6 +208,7 @@ static struct key *key_get(const struct keychain *keychain, uint32_t index)
 
        key = key_new();
        key->index = index;
+       key->hash_algo = KEYCHAIN_ALGO_NULL;
        listnode_add_sort(keychain->key, key);
 
        return key;
@@ -336,6 +338,133 @@ DEFUN (no_key_string,
        return CMD_SUCCESS;
 }
 
+const struct keychain_algo_info algo_info[] = {
+       {KEYCHAIN_ALGO_NULL, "null", 0, 0, "NULL"},
+       {KEYCHAIN_ALGO_MD5, "md5", KEYCHAIN_MD5_HASH_SIZE,
+        KEYCHAIN_ALGO_MD5_INTERNAL_BLK_SIZE, "MD5"},
+       {KEYCHAIN_ALGO_HMAC_SHA1, "hmac-sha-1", KEYCHAIN_HMAC_SHA1_HASH_SIZE,
+        KEYCHAIN_ALGO_SHA1_INTERNAL_BLK_SIZE, "HMAC-SHA-1"},
+       {KEYCHAIN_ALGO_HMAC_SHA256, "hmac-sha-256",
+        KEYCHAIN_HMAC_SHA256_HASH_SIZE, KEYCHAIN_ALGO_SHA256_INTERNAL_BLK_SIZE,
+        "HMAC-SHA-256"},
+       {KEYCHAIN_ALGO_HMAC_SHA384, "hmac-sha-384",
+        KEYCHAIN_HMAC_SHA384_HASH_SIZE, KEYCHAIN_ALGO_SHA384_INTERNAL_BLK_SIZE,
+        "HMAC-SHA-384"},
+       {KEYCHAIN_ALGO_HMAC_SHA512, "hmac-sha-512",
+        KEYCHAIN_HMAC_SHA512_HASH_SIZE, KEYCHAIN_ALGO_SHA512_INTERNAL_BLK_SIZE,
+        "HMAC-SHA-512"},
+       {KEYCHAIN_ALGO_MAX, "max", KEYCHAIN_MAX_HASH_SIZE,
+        KEYCHAIN_ALGO_MAX_INTERNAL_BLK_SIZE, "Not defined"}
+};
+
+uint32_t keychain_get_block_size(enum keychain_hash_algo key)
+{
+       return algo_info[key].block;
+}
+
+uint32_t keychain_get_hash_len(enum keychain_hash_algo key)
+{
+       return algo_info[key].length;
+}
+
+const char *keychain_get_description(enum keychain_hash_algo key)
+{
+       return algo_info[key].desc;
+}
+
+struct keychain_algo_info
+keychain_get_hash_algo_info(enum keychain_hash_algo key)
+{
+       return algo_info[key];
+}
+
+enum keychain_hash_algo keychain_get_algo_id_by_name(const char *name)
+{
+#ifdef CRYPTO_INTERNAL
+       if (!strncmp(name, "hmac-sha-2", 10))
+               return KEYCHAIN_ALGO_HMAC_SHA256;
+       else if (!strncmp(name, "m", 1))
+               return KEYCHAIN_ALGO_MD5;
+       else
+               return KEYCHAIN_ALGO_NULL;
+#else
+       if (!strncmp(name, "m", 1))
+               return KEYCHAIN_ALGO_MD5;
+       else if (!strncmp(name, "hmac-sha-1", 10))
+               return KEYCHAIN_ALGO_HMAC_SHA1;
+       else if (!strncmp(name, "hmac-sha-2", 10))
+               return KEYCHAIN_ALGO_HMAC_SHA256;
+       else if (!strncmp(name, "hmac-sha-3", 10))
+               return KEYCHAIN_ALGO_HMAC_SHA384;
+       else if (!strncmp(name, "hmac-sha-5", 10))
+               return KEYCHAIN_ALGO_HMAC_SHA512;
+       else
+               return KEYCHAIN_ALGO_NULL;
+#endif
+}
+
+const char *keychain_get_algo_name_by_id(enum keychain_hash_algo key)
+{
+       return algo_info[key].name;
+}
+
+DEFUN(cryptographic_algorithm, cryptographic_algorithm_cmd,
+      "cryptographic-algorithm "
+      "<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512>",
+      "Cryptographic-algorithm\n"
+      "Use MD5 algorithm\n"
+      "Use HMAC-SHA-1 algorithm\n"
+      "Use HMAC-SHA-256 algorithm\n"
+      "Use HMAC-SHA-384 algorithm\n"
+      "Use HMAC-SHA-512 algorithm\n")
+{
+       int algo_idx = 1;
+       uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
+
+       VTY_DECLVAR_CONTEXT_SUB(key, key);
+       hash_algo = keychain_get_algo_id_by_name(argv[algo_idx]->arg);
+#ifndef CRYPTO_OPENSSL
+       if (hash_algo == KEYCHAIN_ALGO_NULL) {
+               vty_out(vty,
+                       "Hash algorithm not supported, compile with --with-crypto=openssl\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+#endif /* CRYPTO_OPENSSL */
+       key->hash_algo = hash_algo;
+       return CMD_SUCCESS;
+}
+
+DEFUN(no_cryptographic_algorithm, no_cryptographic_algorithm_cmd,
+      "no cryptographic-algorithm "
+      "[<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512>]",
+      NO_STR
+      "Cryptographic-algorithm\n"
+      "Use MD5 algorithm\n"
+      "Use HMAC-SHA-1 algorithm\n"
+      "Use HMAC-SHA-256 algorithm\n"
+      "Use HMAC-SHA-384 algorithm\n"
+      "Use HMAC-SHA-512 algorithm\n")
+{
+       int algo_idx = 2;
+       uint8_t hash_algo = KEYCHAIN_ALGO_NULL;
+
+       VTY_DECLVAR_CONTEXT_SUB(key, key);
+       if (argc > algo_idx) {
+               hash_algo = keychain_get_algo_id_by_name(argv[algo_idx]->arg);
+               if (hash_algo == KEYCHAIN_ALGO_NULL) {
+                       vty_out(vty,
+                               "Hash algorithm not supported, try compiling with --with-crypto=openssl\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       if ((hash_algo != KEYCHAIN_ALGO_NULL) && (hash_algo != key->hash_algo))
+               return CMD_SUCCESS;
+
+       key->hash_algo = KEYCHAIN_ALGO_NULL;
+       return CMD_SUCCESS;
+}
+
 /* Convert HH:MM:SS MON DAY YEAR to time_t value.  -1 is returned when
    given string is malformed. */
 static time_t key_str2time(const char *time_str, const char *day_str,
@@ -1004,6 +1133,11 @@ static int keychain_config_write(struct vty *vty)
                        if (key->string)
                                vty_out(vty, "  key-string %s\n", key->string);
 
+                       if (key->hash_algo != KEYCHAIN_ALGO_NULL)
+                               vty_out(vty, "  cryptographic-algorithm %s\n",
+                                       keychain_get_algo_name_by_id(
+                                               key->hash_algo));
+
                        if (key->accept.start) {
                                keychain_strftime(buf, BUFSIZ,
                                                  &key->accept.start);
@@ -1051,6 +1185,7 @@ static int keychain_config_write(struct vty *vty)
        return 0;
 }
 
+
 static void keychain_active_config(vector comps, struct cmd_token *token)
 {
        struct keychain *keychain;
@@ -1131,4 +1266,6 @@ void keychain_init(void)
        install_element(KEYCHAIN_KEY_NODE,
                        &send_lifetime_duration_month_day_cmd);
        install_element(KEYCHAIN_KEY_NODE, &no_send_lifetime_cmd);
+       install_element(KEYCHAIN_KEY_NODE, &cryptographic_algorithm_cmd);
+       install_element(KEYCHAIN_KEY_NODE, &no_cryptographic_algorithm_cmd);
 }
index eb6d2f175edd7c9670aa79d451b235705a56916d..c47bb7a7921a74c44de98cba32372477124f2028 100644 (file)
 extern "C" {
 #endif
 
+enum keychain_hash_algo {
+       KEYCHAIN_ALGO_NULL,
+       KEYCHAIN_ALGO_MD5,
+       KEYCHAIN_ALGO_HMAC_SHA1,
+       KEYCHAIN_ALGO_HMAC_SHA256,
+       KEYCHAIN_ALGO_HMAC_SHA384,
+       KEYCHAIN_ALGO_HMAC_SHA512,
+       KEYCHAIN_ALGO_MAX
+};
+
+#define KEYCHAIN_MD5_HASH_SIZE 16
+#define KEYCHAIN_HMAC_SHA1_HASH_SIZE 20
+#define KEYCHAIN_HMAC_SHA256_HASH_SIZE 32
+#define KEYCHAIN_HMAC_SHA384_HASH_SIZE 48
+#define KEYCHAIN_HMAC_SHA512_HASH_SIZE 64
+#define KEYCHAIN_MAX_HASH_SIZE 64
+
+#define KEYCHAIN_ALGO_MD5_INTERNAL_BLK_SIZE 16
+#define KEYCHAIN_ALGO_SHA1_INTERNAL_BLK_SIZE 64
+#define KEYCHAIN_ALGO_SHA256_INTERNAL_BLK_SIZE 64
+#define KEYCHAIN_ALGO_SHA384_INTERNAL_BLK_SIZE 128
+#define KEYCHAIN_ALGO_SHA512_INTERNAL_BLK_SIZE 128
+#define KEYCHAIN_ALGO_MAX_INTERNAL_BLK_SIZE 128
+
+struct keychain_algo_info {
+       enum keychain_hash_algo key;
+       const char *name;
+       uint32_t length;
+       uint32_t block;
+       const char *desc;
+};
+
+extern const struct keychain_algo_info algo_info[];
+uint32_t keychain_get_block_size(enum keychain_hash_algo key);
+uint32_t keychain_get_hash_len(enum keychain_hash_algo key);
+const char *keychain_get_description(enum keychain_hash_algo key);
+struct keychain_algo_info
+keychain_get_hash_algo_info(enum keychain_hash_algo key);
+enum keychain_hash_algo keychain_get_algo_id_by_name(const char *name);
+const char *keychain_get_algo_name_by_id(enum keychain_hash_algo key);
+
 struct keychain {
        char *name;
 
@@ -47,7 +88,7 @@ struct key {
        uint32_t index;
 
        char *string;
-
+       enum keychain_hash_algo hash_algo;
        struct key_range send;
        struct key_range accept;
 
@@ -60,7 +101,7 @@ extern struct keychain *keychain_lookup(const char *);
 extern struct key *key_lookup_for_accept(const struct keychain *, uint32_t);
 extern struct key *key_match_for_accept(const struct keychain *, const char *);
 extern struct key *key_lookup_for_send(const struct keychain *);
-
+const char *keychain_algo_str(enum keychain_hash_algo hash_algo);
 #ifdef __cplusplus
 }
 #endif