diff options
Diffstat (limited to 'src/wsgcrypt.cpp')
| -rw-r--r-- | src/wsgcrypt.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/wsgcrypt.cpp b/src/wsgcrypt.cpp new file mode 100644 index 0000000..c6b89a5 --- /dev/null +++ b/src/wsgcrypt.cpp @@ -0,0 +1,69 @@ +/** + * wsgcrypt.c + * + * Created on 2020-11-26 + * @author: qyc + * + * @explain: + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "wsgcrypt.h" + +gcry_error_t ws_hmac_buffer(int algo, void *digest, const void *buffer, size_t length, const void *key, size_t keylen) +{ + gcry_md_hd_t hmac_handle; + gcry_error_t result = gcry_md_open(&hmac_handle, algo, GCRY_MD_FLAG_HMAC); + if (result) { + return result; + } + result = gcry_md_setkey(hmac_handle, key, keylen); + if (result) { + gcry_md_close(hmac_handle); + return result; + } + gcry_md_write(hmac_handle, buffer, length); + memcpy(digest, gcry_md_read(hmac_handle, 0), gcry_md_get_algo_dlen(algo)); + gcry_md_close(hmac_handle); + return GPG_ERR_NO_ERROR; +} + +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; + + guint offset; + for (offset = 0; offset < out_len; offset += hash_len) { + gcry_md_reset(h); + // Set PRK + gcry_md_setkey(h, prk, prk_len); + if (offset > 0) + // T(1..N) + gcry_md_write(h, lastoutput, hash_len); + // info + gcry_md_write(h, info, info_len); + // constant 0x01..N + gcry_md_putc(h, (guint8)(offset / hash_len + 1)); + + 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; +} |
