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 block sizes.
Signed-off-by: Toke Høiland-Jørgensen <[email protected]> --- lib/blake2.c | 16 ++++++++++++++++ lib/blake2.h | 2 ++ lib/mac.c | 6 ++++-- lib/mac.h | 7 +++++++ nest/config.Y | 9 +++++++-- nest/password.c | 6 ++++++ nest/password.h | 1 + 7 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/blake2.c b/lib/blake2.c index ac4b7d663..a3e5bdba4 100644 --- a/lib/blake2.c +++ b/lib/blake2.c @@ -7,6 +7,8 @@ */ +#include "nest/bird.h" +#include "conf/conf.h" #include "blake2-ref.h" void blake2s_bird_init(struct mac_context *mac, const byte *key, uint keylen) @@ -28,6 +30,13 @@ byte *blake2s_bird_final(struct mac_context *mac) return ctx->buf; } +void blake2s_bird_validate_key(const byte *key UNUSED, uint keylen) +{ + if (keylen != BLAKE2S_SIZE) + cf_error("Key size %d does not match required size of %d bytes for Blake2s", + keylen, BLAKE2S_SIZE); +} + void blake2b_bird_init(struct mac_context *mac, const byte *key, uint keylen) { struct blake2b_context *ctx = (void *) mac; @@ -44,3 +53,10 @@ byte *blake2b_bird_final(struct mac_context *mac) blake2b_final(&ctx->state, ctx->buf, BLAKE2B_SIZE); return ctx->buf; } + +void blake2b_bird_validate_key(const byte *key UNUSED, uint keylen) +{ + if (keylen != BLAKE2B_SIZE) + cf_error("Key size %d does not match required size of %d bytes for Blake2b", + keylen, BLAKE2B_SIZE); +} diff --git a/lib/blake2.h b/lib/blake2.h index 1ef51b482..c53015d66 100644 --- a/lib/blake2.h +++ b/lib/blake2.h @@ -58,10 +58,12 @@ struct blake2b_context { void blake2s_bird_init(struct mac_context *ctx, const byte *key, uint keylen); void blake2s_bird_update(struct mac_context *ctx, const byte *buf, uint len); byte *blake2s_bird_final(struct mac_context *ctx); +void blake2s_bird_validate_key(const byte *key, uint keylen); void blake2b_bird_init(struct mac_context *ctx, const byte *key, uint keylen); void blake2b_bird_update(struct mac_context *ctx, const byte *buf, uint len); byte *blake2b_bird_final(struct mac_context *ctx); +void blake2b_bird_validate_key(const byte *key, uint keylen); #endif /* _BIRD_BLAKE2_H_ */ diff --git a/lib/mac.c b/lib/mac.c index ca02beff4..e42b64fe8 100644 --- a/lib/mac.c +++ b/lib/mac.c @@ -172,10 +172,12 @@ const struct mac_desc mac_table[ALG_MAX] = { [ALG_SHA512] = HASH_DESC("Keyed SHA-512", sha512, SHA512), [ALG_BLAKE2S] = {"Blake2s", BLAKE2S_SIZE, sizeof(struct blake2s_context), blake2s_bird_init, blake2s_bird_update, - blake2s_bird_final, BLAKE2S_SIZE, BLAKE2S_BLOCK_SIZE}, + blake2s_bird_final, BLAKE2S_SIZE, BLAKE2S_BLOCK_SIZE, + NULL, NULL, NULL, blake2s_bird_validate_key}, [ALG_BLAKE2B] = {"Blake2b", BLAKE2B_SIZE, sizeof(struct blake2b_context), blake2b_bird_init, blake2b_bird_update, - blake2b_bird_final, BLAKE2B_SIZE, BLAKE2B_BLOCK_SIZE}, + blake2b_bird_final, BLAKE2B_SIZE, BLAKE2B_BLOCK_SIZE, + NULL, NULL, NULL, blake2b_bird_validate_key}, [ALG_HMAC_MD5] = HMAC_DESC("HMAC-MD5", md5, MD5), [ALG_HMAC_SHA1] = HMAC_DESC("HMAC-SHA-1", sha1, SHA1), [ALG_HMAC_SHA224] = HMAC_DESC("HMAC-SHA-224", sha224, SHA224), diff --git a/lib/mac.h b/lib/mac.h index add6d794f..7b8bd6d2a 100644 --- a/lib/mac.h +++ b/lib/mac.h @@ -89,6 +89,7 @@ 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); + void (*validate_key)(const byte *key, uint keylen); }; extern const struct mac_desc mac_table[ALG_MAX]; @@ -99,6 +100,12 @@ static inline const char *mac_type_name(uint id) static inline uint mac_type_length(uint id) { return mac_table[id].mac_length; } +static inline void mac_validate_key(uint id, const byte *key, uint keylen) +{ + if (mac_table[id].validate_key) + mac_table[id].validate_key(key, 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 8a99f8c9c..ebcfb66be 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -467,8 +467,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: @@ -503,6 +503,11 @@ password_algorithm: | BLAKE2B { $$ = ALG_BLAKE2B; } ; +password_item_end: +{ + password_validate_config(this_p_item); +}; + /* Core commands */ CF_CLI_HELP(SHOW, ..., [[Show status information]]) diff --git a/nest/password.c b/nest/password.c index 6f87af218..3fb342e96 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_validate_key(p->alg, p->password, p->length); +} diff --git a/nest/password.h b/nest/password.h index 8a0da2237..818bdf2b9 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) {
