diff options
author | Peter Wu <peter@lekensteyn.nl> | 2018-02-10 14:06:17 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-02-12 08:37:48 +0000 |
commit | ae91f43155662d857b6e4e07a67c244f921e0a8b (patch) | |
tree | 69bcbcce3ecea03ed6040c419b051c96b06702f6 /wsutil/wsgcrypt.c | |
parent | d2016c6a1bb9a1688da684825cbda889d95238a6 (diff) |
Extract HKDF-Expand from TLS 1.3 dissector
HKDF (RFC 5869) is a standard construct used in TLS 1.3, QUIC and
OSCORE, generalize it for use outside the TLS dissector.
Since none of the users need the "context" (formerly "hash_value")
field, remove the parameter.
Change-Id: Id952de8cb3000f6f6eda844d17c78bbd3906a84d
Reviewed-on: https://code.wireshark.org/review/25723
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'wsutil/wsgcrypt.c')
-rw-r--r-- | wsutil/wsgcrypt.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/wsutil/wsgcrypt.c b/wsutil/wsgcrypt.c index 9e3a86055c..eef943c272 100644 --- a/wsutil/wsgcrypt.c +++ b/wsutil/wsgcrypt.c @@ -144,6 +144,44 @@ out: return decr_len; } +gcry_error_t +hkdf_expand(int hashalgo, const guint8 *prk, guint prk_len, const guint8 *info, guint info_len, + guint8 *out, guint out_len) +{ + // Current maximum hash output size: 48 bytes for SHA-384. + guchar lastoutput[48]; + gcry_md_hd_t h; + gcry_error_t err; + const guint hash_len = gcry_md_get_algo_dlen(hashalgo); + + /* Some sanity checks */ + if (!(out_len > 0 && out_len <= 255 * hash_len) || + !(hash_len > 0 && hash_len <= sizeof(lastoutput))) { + return GPG_ERR_INV_ARG; + } + + err = gcry_md_open(&h, hashalgo, GCRY_MD_FLAG_HMAC); + if (err) { + return err; + } + + for (guint offset = 0; offset < out_len; offset += hash_len) { + gcry_md_reset(h); + gcry_md_setkey(h, prk, prk_len); /* Set PRK */ + if (offset > 0) { + gcry_md_write(h, lastoutput, hash_len); /* T(1..N) */ + } + gcry_md_write(h, info, info_len); /* info */ + gcry_md_putc(h, (guint8) (offset / hash_len + 1)); /* constant 0x01..N */ + + memcpy(lastoutput, gcry_md_read(h, hashalgo), hash_len); + memcpy(out + offset, lastoutput, MIN(hash_len, out_len - offset)); + } + + gcry_md_close(h); + return 0; +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * |