70 lines
1.7 KiB
C++
70 lines
1.7 KiB
C++
|
|
/**
|
||
|
|
* 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;
|
||
|
|
}
|