[PATCH v4 5/8] config: Allow MAC algorithms to specify a function to validate their keys

Toke Høiland-Jørgensen toke at toke.dk
Fri Jan 15 16:52:54 CET 2021


From: Toke Høiland-Jørgensen <toke at toke.dk>

This adds a new field to the MAC algorithm description which is a pointer
that will allow an algorithm to validate a key before it is used. Add this
validate to the Blake algorithms, validating that the key length is exactly
equal to their respective output sizes.

Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
---
 lib/mac.c       |   31 ++++++++++++++++++++++++++-----
 lib/mac.h       |    4 ++++
 nest/config.Y   |    8 ++++++--
 nest/password.c |    6 ++++++
 nest/password.h |    1 +
 5 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/lib/mac.c b/lib/mac.c
index f780b54c918b..b6d1f97a71fe 100644
--- a/lib/mac.c
+++ b/lib/mac.c
@@ -151,6 +151,27 @@ hmac_final(struct mac_context *ctx)
 }
 
 
+/**
+ * mac_type_validate_key - enforce key length validation
+ * @id: MAC algorithm ID,
+ * @key: key to verify
+ * @keylen: length of key
+ *
+ * This is a common MAC algorithm validation function that will enforce that the
+ * key length constrains specified in the MAC type table.
+ */
+void
+mac_type_validate_key(uint id, const byte *key UNUSED, uint keylen)
+{
+  if (mac_table[id].min_key_size && keylen < mac_table[id].min_key_size)
+    cf_error("Key size %d smaller than minimum size of %d bytes for %s",
+             keylen, mac_table[id].min_key_size, mac_type_name(id));
+
+  if (mac_table[id].max_key_size && keylen > mac_table[id].max_key_size)
+    cf_error("Key size %d larger than maximum size of %d bytes for %s",
+             keylen, mac_table[id].max_key_size, mac_type_name(id));
+}
+
 /*
  *	Common code
  */
@@ -163,11 +184,11 @@ hmac_final(struct mac_context *ctx)
   { name, PX##_SIZE, sizeof(struct hmac_context), hmac_init, hmac_update, hmac_final, \
     PX##_SIZE, PX##_BLOCK_SIZE, px##_init, px##_update, px##_final }
 
-#define BLAKE_DESC(name, vx, VX, size)                                         \
-  {                                                                            \
-    name, size/8, sizeof(struct vx##_context), vx##_bird_init,     \
-        vx##_bird_update, vx##_bird_final, size/8,                \
-        VX##_BLOCK_SIZE, NULL, NULL, NULL \
+#define BLAKE_DESC(name, vx, VX, size)                                  \
+  {                                                                     \
+    name, size/8, sizeof(struct vx##_context), vx##_bird_init,          \
+      vx##_bird_update, vx##_bird_final, size/8,                        \
+      VX##_BLOCK_SIZE, NULL, NULL, NULL, VX##_SIZE, VX##_SIZE           \
   }
 
 const struct mac_desc mac_table[ALG_MAX] = {
diff --git a/lib/mac.h b/lib/mac.h
index e3847239e10c..56653f8ac38a 100644
--- a/lib/mac.h
+++ b/lib/mac.h
@@ -91,6 +91,8 @@ struct mac_desc {
   void (*hash_init)(struct hash_context *ctx);
   void (*hash_update)(struct hash_context *ctx, const byte *data, uint datalen);
   byte *(*hash_final)(struct hash_context *ctx);
+  uint min_key_size;			/* Minimum allowed key size */
+  uint max_key_size;			/* Maximum allowed key size */
 };
 
 extern const struct mac_desc mac_table[ALG_MAX];
@@ -101,6 +103,8 @@ static inline const char *mac_type_name(uint id)
 static inline uint mac_type_length(uint id)
 { return mac_table[id].mac_length; }
 
+void mac_type_validate_key(uint id, const byte *key, uint keylen);
+
 static inline const char *mac_get_name(struct mac_context *ctx)
 { return ctx->type->name; }
 
diff --git a/nest/config.Y b/nest/config.Y
index 992075e754cd..7cbfbd5d8d1b 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -499,8 +499,8 @@ password_items:
 ;
 
 password_item:
-    password_item_begin '{' password_item_params '}'
-  | password_item_begin
+    password_item_begin '{' password_item_params '}' password_item_end
+  | password_item_begin password_item_end
 ;
 
 password_item_begin:
@@ -537,6 +537,10 @@ password_algorithm:
  | BLAKE2B512	{ $$ = ALG_BLAKE2B_512; }
  ;
 
+password_item_end:
+{
+  password_validate_config(this_p_item);
+};
 
 /* BFD options */
 
diff --git a/nest/password.c b/nest/password.c
index 6f87af218d6b..b7ef30591449 100644
--- a/nest/password.c
+++ b/nest/password.c
@@ -85,3 +85,9 @@ max_mac_length(list *l)
 
   return val;
 }
+
+void
+password_validate_config(struct password_item *p)
+{
+  mac_type_validate_key(p->alg, p->password, p->length);
+}
diff --git a/nest/password.h b/nest/password.h
index 8a0da22375fc..818bdf2b94f3 100644
--- a/nest/password.h
+++ b/nest/password.h
@@ -24,6 +24,7 @@ extern struct password_item *last_password_item;
 struct password_item *password_find(list *l, int first_fit);
 struct password_item *password_find_by_id(list *l, uint id);
 struct password_item *password_find_by_value(list *l, char *pass, uint size);
+void password_validate_config(struct password_item *p);
 
 static inline int password_verify(struct password_item *p1, char *p2, uint size)
 {



More information about the Bird-users mailing list