aboutsummaryrefslogtreecommitdiffstats
path: root/wsutil/wsgcrypt.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-02-10 14:06:17 +0100
committerAnders Broman <a.broman58@gmail.com>2018-02-12 08:37:48 +0000
commitae91f43155662d857b6e4e07a67c244f921e0a8b (patch)
tree69bcbcce3ecea03ed6040c419b051c96b06702f6 /wsutil/wsgcrypt.c
parentd2016c6a1bb9a1688da684825cbda889d95238a6 (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.c38
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
*