summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--doc/en/weechat_plugin_api.en.adoc48
-rw-r--r--doc/fr/weechat_plugin_api.fr.adoc50
-rw-r--r--doc/it/weechat_plugin_api.it.adoc49
-rw-r--r--doc/ja/weechat_plugin_api.ja.adoc49
-rw-r--r--src/core/wee-crypto.c116
-rw-r--r--src/core/wee-crypto.h4
-rw-r--r--src/plugins/plugin-api.c33
-rw-r--r--src/plugins/plugin-api.h4
-rw-r--r--src/plugins/plugin.c1
-rw-r--r--src/plugins/weechat-plugin.h13
-rw-r--r--tests/unit/core/test-core-crypto.cpp95
12 files changed, 434 insertions, 29 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index aa243544b..831de4d5d 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -26,6 +26,7 @@ New features::
* core: add options to customize commands executed on system signals received (SIGHUP, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2) (issue #1595)
* core: quit WeeChat by default when signal SIGHUP is received in normal run, reload configuration in weechat-headless (issue #1595)
* core: add signals "cursor_start" and "cursor_end"
+ * api: add function crypto_hmac (issue #1628)
* api: add translated string in evaluation of expressions with "translate:xxx"
* api: add evaluation of WeeChat directories with "${weechat_xxx_dir}" in evaluated strings
* api: add optional key "directory" in hashtable options of function/modifier string_eval_path_home
diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc
index 6f1c4de1b..dde1f532c 100644
--- a/doc/en/weechat_plugin_api.en.adoc
+++ b/doc/en/weechat_plugin_api.en.adoc
@@ -3626,6 +3626,54 @@ rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (sa
[NOTE]
This function is not available in scripting API.
+==== crypto_hmac
+
+_WeeChat ≥ 3.2._
+
+Compute keyed-hash message authentication code (HMAC).
+
+Prototype:
+
+[source,C]
+----
+int weechat_crypto_hmac (const void *key, int key_size, const void *message, int message_size,
+ int hash_algo, void *hash, int *hash_size);
+----
+
+Arguments:
+
+* _key_: the key
+* _key_size_: number of bytes in _key_
+* _message_: the message
+* _message_size_: number of bytes in _message_
+* _hash_algo_: the hash algorithm, see table in function
+ <<crypto_hash_algorithms,crypto_hash>>
+* _hash_: pointer to the hash variable, which is used to store the resulting hash
+ (the buffer must be large enough, according to the algorithm, see table
+ in function <<crypto_hash_algorithms,crypto_hash>>)
+* _hash_size_: pointer to a variable used to store the size of the hash computed
+ (in bytes) (can be NULL)
+
+Return value:
+
+* 1 if OK, 0 if error
+
+C example:
+
+[source,C]
+----
+const char *key = "the key";
+const char *message = "the message";
+char hash[256 / 8];
+int rc, hash_size;
+rc = weechat_crypto_hmac (key, strlen (key), message, strlen (message), "sha256", hash, &hash_size);
+/* rc == 1, hash_size == 32 and hash is a buffer with:
+ 47 36 67 02 fc bc b1 97 a4 25 e6 7a b9 52 92 bd 15 9a 66 91 9c fb 94 b0 b4 9a 39 cb c0 24 2d 7b */
+----
+
+[NOTE]
+This function is not available in scripting API.
+
[[directories]]
=== Directories
diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc
index 65cc46414..7d4c0d92d 100644
--- a/doc/fr/weechat_plugin_api.fr.adoc
+++ b/doc/fr/weechat_plugin_api.fr.adoc
@@ -3687,6 +3687,56 @@ rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (sa
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
+==== crypto_hmac
+
+_WeeChat ≥ 3.2._
+
+Calculer le code d'authentification d'une empreinte cryptographique de message
+avec clé (HMAC).
+
+Prototype :
+
+[source,C]
+----
+int weechat_crypto_hmac (const void *key, int key_size, const void *message, int message_size,
+ int hash_algo, void *hash, int *hash_size);
+----
+
+Paramètres :
+
+* _key_ : la clé
+* _key_size_ : nombre d'octets dans _key_
+* _message_ : le message
+* _message_size_ : nombre d'octets dans _message_
+* _hash_algo_ : l'algorithme de hachage, voir le tableau dans la fonction
+ <<crypto_hash_algorithms,crypto_hash>>
+* _hash_ : pointeur vers la variable de hachage, qui est utilisée pour stocker
+ le résultat du hachage (le tampon doit être suffisamment grand, selon
+ l'algorithme, voir le tableau dans la fonction
+ <<crypto_hash_algorithms,crypto_hash>>)
+* _hash_size_ : pointeur vers une variable utiliser pour stocker la longueur
+ du résultat du hachage (en octets) (peut être NULL)
+
+Valeur de retour :
+
+* 1 si OK, 0 si erreur
+
+Exemple en C :
+
+[source,C]
+----
+const char *key = "the key";
+const char *message = "the message";
+char hash[256 / 8];
+int rc, hash_size;
+rc = weechat_crypto_hmac (key, strlen (key), message, strlen (message), "sha256", hash, &hash_size);
+/* rc == 1, hash_size == 32 et hash est un tampon avec :
+ 47 36 67 02 fc bc b1 97 a4 25 e6 7a b9 52 92 bd 15 9a 66 91 9c fb 94 b0 b4 9a 39 cb c0 24 2d 7b */
+----
+
+[NOTE]
+Cette fonction n'est pas disponible dans l'API script.
+
[[directories]]
=== Répertoires
diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc
index 1d266f083..667c09c38 100644
--- a/doc/it/weechat_plugin_api.it.adoc
+++ b/doc/it/weechat_plugin_api.it.adoc
@@ -3764,6 +3764,55 @@ Questa funzione non è disponibile nelle API per lo scripting.
Alcune funzioni legate alle cartelle.
+// TRANSLATION MISSING
+==== crypto_hmac
+
+_WeeChat ≥ 3.2._
+
+Compute keyed-hash message authentication code (HMAC).
+
+Prototipo:
+
+[source,C]
+----
+int weechat_crypto_hmac (const void *key, int key_size, const void *message, int message_size,
+ int hash_algo, void *hash, int *hash_size);
+----
+
+Argomenti:
+
+* _key_: the key
+* _key_size_: number of bytes in _key_
+* _message_: the message
+* _message_size_: number of bytes in _message_
+* _hash_algo_: the hash algorithm, see table in function
+ <<crypto_hash_algorithms,crypto_hash>>
+* _hash_: pointer to the hash variable, which is used to store the resulting hash
+ (the buffer must be large enough, according to the algorithm, see table
+ in function <<crypto_hash_algorithms,crypto_hash>>)
+* _hash_size_: pointer to a variable used to store the size of the hash computed
+ (in bytes) (can be NULL)
+
+Valore restituito:
+
+* 1 if OK, 0 if error
+
+Esempio in C:
+
+[source,C]
+----
+const char *key = "the key";
+const char *message = "the message";
+char hash[256 / 8];
+int rc, hash_size;
+rc = weechat_crypto_hmac (key, strlen (key), message, strlen (message), "sha256", hash, &hash_size);
+/* rc == 1, hash_size == 32 and hash is a buffer with:
+ 47 36 67 02 fc bc b1 97 a4 25 e6 7a b9 52 92 bd 15 9a 66 91 9c fb 94 b0 b4 9a 39 cb c0 24 2d 7b */
+----
+
+[NOTE]
+Questa funzione non è disponibile nelle API per lo scripting.
+
==== mkdir_home
// TRANSLATION MISSING
diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc
index b88949e48..ea645d493 100644
--- a/doc/ja/weechat_plugin_api.ja.adoc
+++ b/doc/ja/weechat_plugin_api.ja.adoc
@@ -3670,6 +3670,55 @@ rc = weechat_crypto_hash_pbkdf2 (data, strlen (data), "sha256", salt, strlen (sa
[NOTE]
スクリプト API ではこの関数を利用できません。
+// TRANSLATION MISSING
+==== crypto_hmac
+
+_WeeChat バージョン 3.2 以上で利用可。_
+
+Compute keyed-hash message authentication code (HMAC).
+
+プロトタイプ:
+
+[source,C]
+----
+int weechat_crypto_hmac (const void *key, int key_size, const void *message, int message_size,
+ int hash_algo, void *hash, int *hash_size);
+----
+
+引数:
+
+* _key_: the key
+* _key_size_: number of bytes in _key_
+* _message_: the message
+* _message_size_: number of bytes in _message_
+* _hash_algo_: the hash algorithm, see table in function
+ <<crypto_hash_algorithms,crypto_hash>>
+* _hash_: pointer to the hash variable, which is used to store the resulting hash
+ (the buffer must be large enough, according to the algorithm, see table
+ in function <<crypto_hash_algorithms,crypto_hash>>)
+* _hash_size_: pointer to a variable used to store the size of the hash computed
+ (in bytes) (can be NULL)
+
+戻り値:
+
+* 成功した場合は 1、失敗した場合は 0
+
+C 言語での使用例:
+
+[source,C]
+----
+const char *key = "the key";
+const char *message = "the message";
+char hash[256 / 8];
+int rc, hash_size;
+rc = weechat_crypto_hmac (key, strlen (key), message, strlen (message), "sha256", hash, &hash_size);
+/* rc == 1, hash_size == 32 and hash is a buffer with:
+ 47 36 67 02 fc bc b1 97 a4 25 e6 7a b9 52 92 bd 15 9a 66 91 9c fb 94 b0 b4 9a 39 cb c0 24 2d 7b */
+----
+
+[NOTE]
+スクリプト API ではこの関数を利用できません。
+
[[directories]]
=== ディレクトリ
diff --git a/src/core/wee-crypto.c b/src/core/wee-crypto.c
index 89a348fab..119230996 100644
--- a/src/core/wee-crypto.c
+++ b/src/core/wee-crypto.c
@@ -80,7 +80,7 @@ weecrypto_get_hash_algo (const char *hash_algo)
}
/*
- * Computes hash of data using the given algorithm.
+ * Computes hash of data using the given hash algorithm.
*
* The hash size depends on the algorithm, common ones are:
*
@@ -137,6 +137,7 @@ weecrypto_hash (const void *data, int data_size, int hash_algo,
hd_md_opened = 1;
gcry_md_write (*hd_md, data, data_size);
+
ptr_hash = gcry_md_read (*hd_md, hash_algo);
if (!ptr_hash)
goto hash_end;
@@ -217,6 +218,91 @@ hash_pbkdf2_end:
}
/*
+ * Computes keyed-hash message authentication code (HMAC).
+ *
+ * The hash size depends on the algorithm, common ones are:
+ *
+ * GCRY_MD_CRC32 32 bits == 4 bytes
+ * GCRY_MD_MD5 128 bits == 16 bytes
+ * GCRY_MD_SHA1 160 bits == 20 bytes
+ * GCRY_MD_SHA224 224 bits == 28 bytes
+ * GCRY_MD_SHA256 256 bits == 32 bytes
+ * GCRY_MD_SHA384 384 bits == 48 bytes
+ * GCRY_MD_SHA512 512 bits == 64 bytes
+ * GCRY_MD_SHA3_224 224 bits == 28 bytes (libgcrypt ≥ 1.7.0)
+ * GCRY_MD_SHA3_256 256 bits == 32 bytes (libgcrypt ≥ 1.7.0)
+ * GCRY_MD_SHA3_384 384 bits == 48 bytes (libgcrypt ≥ 1.7.0)
+ * GCRY_MD_SHA3_512 512 bits == 64 bytes (libgcrypt ≥ 1.7.0)
+ *
+ * The result hash is stored in "hash" (the buffer must be large enough).
+ *
+ * If hash_size is not NULL, the length of hash is stored in *hash_size
+ * (in bytes).
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+weecrypto_hmac (const void *key, int key_size,
+ const void *message, int message_size,
+ int hash_algo,
+ void *hash, int *hash_size)
+{
+ gcry_md_hd_t *hd_md;
+ int rc, hd_md_opened, algo_size;
+ unsigned char *ptr_hash;
+
+ rc = 0;
+ hd_md = NULL;
+ hd_md_opened = 0;
+
+ if (!hash)
+ goto hmac_end;
+
+ if (hash_size)
+ *hash_size = 0;
+
+ if (!key || (key_size < 1) || !message || (message_size < 1))
+ goto hmac_end;
+
+ hd_md = malloc (sizeof (gcry_md_hd_t));
+ if (!hd_md)
+ goto hmac_end;
+
+ if (gcry_md_open (hd_md, hash_algo, GCRY_MD_FLAG_HMAC) != 0)
+ goto hmac_end;
+
+ hd_md_opened = 1;
+
+ if (gcry_md_setkey (*hd_md, key, key_size) != 0)
+ goto hmac_end;
+
+ gcry_md_write (*hd_md, message, message_size);
+
+ ptr_hash = gcry_md_read (*hd_md, hash_algo);
+ if (!ptr_hash)
+ goto hmac_end;
+
+ algo_size = gcry_md_get_algo_dlen (hash_algo);
+ memcpy (hash, ptr_hash, algo_size);
+ if (hash_size)
+ *hash_size = algo_size;
+
+ rc = 1;
+
+hmac_end:
+ if (hd_md)
+ {
+ if (hd_md_opened)
+ gcry_md_close (*hd_md);
+ free (hd_md);
+ }
+ return rc;
+}
+
+/*
* Generates a Time-based One-Time Password (TOTP), as described
* in the RFC 6238.
*
@@ -230,22 +316,11 @@ weecrypto_totp_generate_internal (const char *secret, int length_secret,
uint64_t moving_factor, int digits,
char *result)
{
- gcry_md_hd_t hd_md;
uint64_t moving_factor_swapped;
- unsigned char *ptr_hash;
char hash[20];
int offset, length;
unsigned long bin_code;
- if (gcry_md_open (&hd_md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC) != 0)
- return 0;
-
- if (gcry_md_setkey (hd_md, secret, length_secret) != 0)
- {
- gcry_md_close (hd_md);
- return 0;
- }
-
moving_factor_swapped = (moving_factor >> 56)
| ((moving_factor << 40) & 0x00FF000000000000)
| ((moving_factor << 24) & 0x0000FF0000000000)
@@ -255,19 +330,10 @@ weecrypto_totp_generate_internal (const char *secret, int length_secret,
| ((moving_factor >> 40) & 0x000000000000FF00)
| (moving_factor << 56);
- gcry_md_write (hd_md,
- &moving_factor_swapped, sizeof (moving_factor_swapped));
-
- ptr_hash = gcry_md_read (hd_md, GCRY_MD_SHA1);
- if (!ptr_hash)
- {
- gcry_md_close (hd_md);
- return 0;
- }
-
- memcpy (hash, ptr_hash, sizeof (hash));
-
- gcry_md_close (hd_md);
+ weecrypto_hmac (secret, length_secret,
+ &moving_factor_swapped, sizeof (moving_factor_swapped),
+ GCRY_MD_SHA1,
+ hash, NULL);
offset = hash[19] & 0xf;
bin_code = (hash[offset] & 0x7f) << 24
diff --git a/src/core/wee-crypto.h b/src/core/wee-crypto.h
index efea48b00..897759775 100644
--- a/src/core/wee-crypto.h
+++ b/src/core/wee-crypto.h
@@ -31,6 +31,10 @@ extern int weecrypto_hash_pbkdf2 (const void *data, int data_size,
const void *salt, int salt_size,
int iterations,
void *hash, int *hash_size);
+extern int weecrypto_hmac (const void *key, int key_size,
+ const void *message, int message_size,
+ int hash_algo,
+ void *hash, int *hash_size);
extern char *weecrypto_totp_generate (const char *secret, time_t totp_time,
int digits);
extern int weecrypto_totp_validate (const char *secret, time_t totp_time,
diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c
index 95d46bf4c..2201eb4db 100644
--- a/src/plugins/plugin-api.c
+++ b/src/plugins/plugin-api.c
@@ -163,6 +163,39 @@ plugin_api_crypto_hash_pbkdf2 (const void *data, int data_size,
}
/*
+ * Computes HMAC of key + message using the given algorithm.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+plugin_api_crypto_hmac (const void *key, int key_size,
+ const void *message, int message_size,
+ const char *hash_algo,
+ void *hash, int *hash_size)
+{
+ int algo;
+
+ if (!hash)
+ return 0;
+
+ if (hash_size)
+ *hash_size = 0;
+
+ if (!key || (key_size < 1) || !message || (message_size < 1) || !hash_algo)
+ return 0;
+
+ algo = weecrypto_get_hash_algo (hash_algo);
+ if (algo == GCRY_MD_NONE)
+ return 0;
+
+ return weecrypto_hmac (key, key_size, message, message_size,
+ algo, hash, hash_size);
+}
+
+/*
* Frees an option.
*/
diff --git a/src/plugins/plugin-api.h b/src/plugins/plugin-api.h
index b8d377017..e266b5c69 100644
--- a/src/plugins/plugin-api.h
+++ b/src/plugins/plugin-api.h
@@ -38,6 +38,10 @@ extern int plugin_api_crypto_hash_pbkdf2 (const void *data, int data_size,
const void *salt, int salt_size,
int iterations,
void *hash, int *hash_size);
+extern int plugin_api_crypto_hmac (const void *key, int key_size,
+ const void *message, int message_size,
+ const char *hash_algo,
+ void *hash, int *hash_size);
/* config */
extern void plugin_api_config_file_option_free (struct t_config_option *option);
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 26cbff783..6254b613b 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -665,6 +665,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
new_plugin->crypto_hash = &plugin_api_crypto_hash;
new_plugin->crypto_hash_pbkdf2 = &plugin_api_crypto_hash_pbkdf2;
+ new_plugin->crypto_hmac = &plugin_api_crypto_hmac;
new_plugin->mkdir_home = &dir_mkdir_home;
new_plugin->mkdir = &dir_mkdir;
diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h
index a261d8f44..9eb42f7e9 100644
--- a/src/plugins/weechat-plugin.h
+++ b/src/plugins/weechat-plugin.h
@@ -68,7 +68,7 @@ struct timeval;
* please change the date with current one; for a second change at same
* date, increment the 01, otherwise please keep 01.
*/
-#define WEECHAT_PLUGIN_API_VERSION "20201004-01"
+#define WEECHAT_PLUGIN_API_VERSION "20210601-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@@ -382,6 +382,9 @@ struct t_weechat_plugin
const void *salt, int salt_size,
int iterations,
void *hash, int *hash_size);
+ int (*crypto_hmac) (const void *key, int key_size,
+ const void *message, int message_size,
+ const char *hash_algo, void *hash, int *hash_size);
/* directories/files */
int (*mkdir_home) (const char *directory, int mode);
@@ -1347,6 +1350,14 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
__salt, __salt_size, \
__iterations, \
__hash, __hash_size)
+#define weechat_crypto_hmac(__key, __key_size, \
+ __message, __message_size, \
+ __hash_algo, \
+ __hash, __hash_size) \
+ (weechat_plugin->crypto_hmac)(__key, __key_size, \
+ __message, __message_size, \
+ __hash_algo, \
+ __hash, __hash_size)
/* directories */
#define weechat_mkdir_home(__directory, __mode) \
diff --git a/tests/unit/core/test-core-crypto.cpp b/tests/unit/core/test-core-crypto.cpp
index 625518426..2f360a884 100644
--- a/tests/unit/core/test-core-crypto.cpp
+++ b/tests/unit/core/test-core-crypto.cpp
@@ -29,7 +29,8 @@ extern "C"
#include "src/core/wee-crypto.h"
#include "src/core/wee-string.h"
-#define DATA_HASH "this is a test of hash function"
+/* Hash */
+#define DATA_HASH_MSG "this is a test of hash function"
#define DATA_HASH_CRC32 "ef26fe3e"
#define DATA_HASH_MD5 "1197d121af621ac6a63cb8ef6b5dfa30"
#define DATA_HASH_SHA1 "799d818061175b400dc5aaeb14b8d32cdef32ff0"
@@ -51,6 +52,8 @@ extern "C"
#define DATA_HASH_SHA3_512 "31dfb5fc8f30ac7007acddc4fce562d408706833d0d2af2" \
"e5f61a179099592927ff7d100e278406c7f98d42575001e26e153b135c21f7ef5b00c8" \
"cef93ca048d"
+
+/* Hash PBKDF2 */
#define DATA_HASH_SALT "this is a salt of 32 bytes xxxxx"
#define DATA_HASH_PBKDF2_SHA1_1000 "85ce23c8873830df8f0a96aa82ae7d7635dad12" \
"7"
@@ -60,6 +63,31 @@ extern "C"
"a402af301e1714c25467a32489c773c71eddf5aa39f42823ecc54c9e9b015517b5f3c0" \
"19bae9463a2d8fe527882"
+/* HMAC */
+#define DATA_HMAC_KEY "secret key"
+#define DATA_HMAC_MSG "this is a test of hmac function"
+#define DATA_HMAC_CRC32 "3c189d75"
+#define DATA_HMAC_MD5 "8148a8e01eb0c6ca42880ea58f50d045"
+#define DATA_HMAC_SHA1 "28dea5713c0d48c7638db31050a7ded4308f46fe"
+#define DATA_HMAC_SHA224 "f1cf0ccf287a2e35b98414346931396d47ca929c92c48edcc" \
+ "e8e0b9e"
+#define DATA_HMAC_SHA256 "7be1b4281c0d74d4a3838892b1512efa13a25c7a50d7dce47" \
+ "da070c7e7c65dee"
+#define DATA_HMAC_SHA384 "8cd5f4afc602e11f6b3032fd65e906da810ac51aeb7d30f4b" \
+ "7b495ae3dcc0eede0c5f63d7d2e3688fe658daf4852be67"
+#define DATA_HMAC_SHA512 "940e5c280c08cd858f79a6085b4bdc54710ed339dd1008fa2" \
+ "1643b7bbeea8a5f61c77f395708505461af62776c9cb7be1c263f39055eb8478190cd8" \
+ "0ea5b0850"
+#define DATA_HMAC_SHA3_224 "a08c7f1598ecc7ea54feeb920ef90b3748d59b3203caa74" \
+ "7316eb2d4"
+#define DATA_HMAC_SHA3_256 "21aca280bc1ac1fa261b1169a321eb7a49e38a8ddec66a8" \
+ "fa2ed9c43d7fae4c5"
+#define DATA_HMAC_SHA3_384 "cbf189e8cd31f3c1c5742e2688b13be8e62691952eee374" \
+ "9523b48bd7a7d1cdf38812cf9a3e52dbb1d0e32a11e478ce7"
+#define DATA_HMAC_SHA3_512 "b1eeb16dd18f66cc8886754ac9cf238deea24d9797ceecb" \
+ "9e0582148bfb6b88f7530d594e80a5a5e22e351a079855983da91b0011dff85ea4a895" \
+ "e8fde6fd41a"
+
#define TOTP_SECRET "secretpasswordbase32"
#define WEE_CHECK_HASH(__result_code, __result_hash, \
@@ -109,6 +137,30 @@ extern "C"
} \
LONGS_EQUAL(hash_size_expected, hash_size);
+#define WEE_CHECK_HMAC(__result_code, __result_hash, \
+ __key, __key_size, __message, __message_size, \
+ __hash_algo) \
+ if (__result_hash) \
+ { \
+ hash_size_expected = string_base16_decode (__result_hash, \
+ hash_expected); \
+ } \
+ else \
+ { \
+ hash_size_expected = 0; \
+ } \
+ hash_size = -1; \
+ LONGS_EQUAL(__result_code, \
+ weecrypto_hmac (__key, __key_size, \
+ __message, __message_size, \
+ __hash_algo, \
+ hash, &hash_size)); \
+ if (__result_hash) \
+ { \
+ MEMCMP_EQUAL(hash_expected, hash, hash_size); \
+ } \
+ LONGS_EQUAL(hash_size_expected, hash_size);
+
#define WEE_CHECK_TOTP_GENERATE(__result, __secret, __time, __digits) \
totp = weecrypto_totp_generate (__secret, __time, __digits); \
if (__result == NULL) \
@@ -165,7 +217,7 @@ TEST(CoreCrypto, GetHashAlgo)
TEST(CoreCrypto, Hash)
{
- const char *data = DATA_HASH;
+ const char *data = DATA_HASH_MSG;
char hash_expected[4096], hash[4096];
int data_size, hash_size_expected, hash_size;
@@ -199,7 +251,7 @@ TEST(CoreCrypto, Hash)
TEST(CoreCrypto, HashPbkdf2)
{
- const char *data = DATA_HASH, *salt = DATA_HASH_SALT;
+ const char *data = DATA_HASH_MSG, *salt = DATA_HASH_SALT;
char hash_expected[4096], hash[4096];
int data_size, salt_size, hash_size_expected, hash_size;
@@ -238,6 +290,43 @@ TEST(CoreCrypto, HashPbkdf2)
/*
* Tests functions:
+ * weecrypto_hmac
+ */
+
+TEST(CoreCrypto, Hmac)
+{
+ const char *key = DATA_HMAC_KEY, *msg = DATA_HMAC_MSG;
+ char hash_expected[4096], hash[4096];
+ int key_size, msg_size, hash_size_expected, hash_size;
+
+ key_size = strlen (key);
+ msg_size = strlen (msg);
+
+ WEE_CHECK_HMAC(0, NULL, NULL, 0, NULL, 0, 0);
+ WEE_CHECK_HMAC(0, NULL, "key", 0, NULL, 0, 0);
+ WEE_CHECK_HMAC(0, NULL, NULL, 0, "msg", 0, 0);
+ WEE_CHECK_HMAC(0, NULL, "key", 0, "msg", 0, 0);
+
+ LONGS_EQUAL (0, weecrypto_hmac (key, key_size, msg, msg_size,
+ GCRY_MD_SHA256, NULL, NULL));
+
+ WEE_CHECK_HMAC(1, DATA_HMAC_CRC32, key, key_size, msg, msg_size, GCRY_MD_CRC32);
+ WEE_CHECK_HMAC(1, DATA_HMAC_MD5, key, key_size, msg, msg_size, GCRY_MD_MD5);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA1, key, key_size, msg, msg_size, GCRY_MD_SHA1);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA224, key, key_size, msg, msg_size, GCRY_MD_SHA224);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA256, key, key_size, msg, msg_size, GCRY_MD_SHA256);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA384, key, key_size, msg, msg_size, GCRY_MD_SHA384);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA512, key, key_size, msg, msg_size, GCRY_MD_SHA512);
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA3_224, key, key_size, msg, msg_size, GCRY_MD_SHA3_224);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA3_256, key, key_size, msg, msg_size, GCRY_MD_SHA3_256);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA3_384, key, key_size, msg, msg_size, GCRY_MD_SHA3_384);
+ WEE_CHECK_HMAC(1, DATA_HMAC_SHA3_512, key, key_size, msg, msg_size, GCRY_MD_SHA3_512);
+#endif
+}
+
+/*
+ * Tests functions:
* weecrypto_totp_generate
*/