From: Toke Høiland-Jørgensen <[email protected]> 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 <[email protected]> --- 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) {
