From 589f7d1e4f3aaca3fec6c38474bb962a9c578ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 15 Apr 2021 04:38:49 +0200 Subject: [PATCH] Nest: Allow MAC algorithms to specify min/max key length Add min/max key length fields to the MAC algorithm description and validate configured keys before they are used. --- lib/mac.c | 2 +- lib/mac.h | 2 ++ nest/config.Y | 9 +++++++-- nest/password.c | 26 ++++++++++++++++++++++++++ nest/password.h | 1 + 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/mac.c b/lib/mac.c index f07d38df..6c9cc743 100644 --- a/lib/mac.c +++ b/lib/mac.c @@ -173,7 +173,7 @@ hmac_final(struct mac_context *ctx) { \ name, size/8, sizeof(struct vx##_context), \ vx##_mac_init, vx##_mac_update, vx##_mac_final, \ - size/8, VX##_BLOCK_SIZE, NULL, NULL, NULL \ + size/8, VX##_BLOCK_SIZE, NULL, NULL, NULL, 0, VX##_SIZE \ } const struct mac_desc mac_table[ALG_MAX] = { diff --git a/lib/mac.h b/lib/mac.h index a03e0546..99a56eed 100644 --- a/lib/mac.h +++ b/lib/mac.h @@ -94,6 +94,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_length; /* Minimum allowed key length */ + uint max_key_length; /* Maximum allowed key length */ }; extern const struct mac_desc mac_table[ALG_MAX]; diff --git a/nest/config.Y b/nest/config.Y index 8bd89de0..45d18679 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -504,8 +504,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: @@ -542,6 +542,11 @@ password_algorithm: | BLAKE2B512 { $$ = ALG_BLAKE2B_512; } ; +password_item_end: +{ + password_validate_length(this_p_item); +}; + /* BFD options */ diff --git a/nest/password.c b/nest/password.c index 6f87af21..34e2a61e 100644 --- a/nest/password.c +++ b/nest/password.c @@ -9,6 +9,7 @@ #include "nest/bird.h" #include "nest/password.h" +#include "conf/conf.h" #include "lib/string.h" #include "lib/timer.h" #include "lib/mac.h" @@ -85,3 +86,28 @@ max_mac_length(list *l) return val; } + +/** + * password_validate_length - enforce key length restrictions + * @pi: Password item + * + * This is a common MAC algorithm validation function that will enforce that the + * key length constrains specified in the MAC type table. + */ + +void +password_validate_length(const struct password_item *pi) +{ + if (!pi->alg) + return; + + const struct mac_desc *alg = &mac_table[pi->alg]; + + if (alg->min_key_length && (pi->length < alg->min_key_length)) + cf_error("Key length (%u B) below minimum length of %u B for %s", + pi->length, alg->min_key_length, alg->name); + + if (alg->max_key_length && (pi->length > alg->max_key_length)) + cf_error("Key length (%u B) exceeds maximum length of %u B for %s", + pi->length, alg->max_key_length, alg->name); +} diff --git a/nest/password.h b/nest/password.h index 8a0da223..53168bb7 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_length(const struct password_item *p); static inline int password_verify(struct password_item *p1, char *p2, uint size) {