summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2016-11-30 01:32:30 +0300
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-06-24 03:08:23 +0300
commit92daa9548dfd53490e6e463e4ce5185cdd766be0 (patch)
tree14f3e6caac7ce8a9fe4279c1b476050ceec7732e
parent7d8fd3aee4d71e1cd79ab5c980d137b363283a33 (diff)
downloadgnutls-92daa9548dfd53490e6e463e4ce5185cdd766be0.tar.gz
Add MAC api to support copying of instances
GOST ciphersuites requires continuously computing MAC of all the previously sent or received data. The easies way to support that is to add support for copy function, that creates MAC instance with the same internal state. Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r--lib/crypto-backend.h1
-rw-r--r--lib/hash_int.c16
-rw-r--r--lib/hash_int.h4
-rw-r--r--lib/includes/gnutls/crypto.h1
4 files changed, 22 insertions, 0 deletions
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index f2fbba947d..f91a5387d1 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -55,6 +55,7 @@ typedef struct {
gnutls_mac_output_func output;
gnutls_mac_deinit_func deinit;
gnutls_mac_fast_func fast;
+ gnutls_mac_copy_func copy;
/* Not needed for registered on run-time. Only included
* should define it. */
diff --git a/lib/hash_int.c b/lib/hash_int.c
index fbc56b4333..61e24d5375 100644
--- a/lib/hash_int.c
+++ b/lib/hash_int.c
@@ -225,6 +225,7 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e,
mac->setnonce = cc->setnonce;
mac->output = cc->output;
mac->deinit = cc->deinit;
+ mac->copy = cc->copy;
return 0;
}
@@ -239,6 +240,7 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e,
mac->setnonce = _gnutls_mac_ops.setnonce;
mac->output = _gnutls_mac_ops.output;
mac->deinit = _gnutls_mac_ops.deinit;
+ mac->copy = _gnutls_mac_ops.copy;
if (_gnutls_mac_ops.setkey(mac->handle, key, keylen) < 0) {
gnutls_assert();
@@ -249,6 +251,20 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e,
return 0;
}
+int _gnutls_mac_copy(const mac_hd_st * handle, mac_hd_st * dst)
+{
+ if (handle->copy == NULL)
+ return gnutls_assert_val(GNUTLS_E_HASH_FAILED);
+
+ *dst = *handle; /* copy data */
+ dst->handle = handle->copy(handle->handle);
+
+ if (dst->handle == NULL)
+ return GNUTLS_E_HASH_FAILED;
+
+ return 0;
+}
+
void _gnutls_mac_deinit(mac_hd_st * handle, void *digest)
{
if (handle->handle == NULL) {
diff --git a/lib/hash_int.h b/lib/hash_int.h
index 52fb2b01f0..8e3154daa6 100644
--- a/lib/hash_int.h
+++ b/lib/hash_int.h
@@ -41,6 +41,7 @@ typedef int (*nonce_func) (void *handle, const void *text, size_t size);
typedef int (*output_func) (void *src_ctx, void *digest,
size_t digestsize);
typedef void (*hash_deinit_func) (void *handle);
+typedef void *(*copy_func) (const void *handle);
typedef struct {
const mac_entry_st *e;
@@ -62,6 +63,7 @@ typedef struct {
nonce_func setnonce;
output_func output;
hash_deinit_func deinit;
+ copy_func copy;
void *handle;
} mac_hd_st;
@@ -73,6 +75,8 @@ int _gnutls_mac_exists(gnutls_mac_algorithm_t algorithm);
int _gnutls_mac_init(mac_hd_st *, const mac_entry_st * e,
const void *key, int keylen);
+int _gnutls_mac_copy(const mac_hd_st * handle, mac_hd_st * dst);
+
int _gnutls_mac_fast(gnutls_mac_algorithm_t algorithm, const void *key,
int keylen, const void *text, size_t textlen,
void *digest);
diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h
index 93a157857c..640924bed5 100644
--- a/lib/includes/gnutls/crypto.h
+++ b/lib/includes/gnutls/crypto.h
@@ -208,6 +208,7 @@ typedef void (*gnutls_mac_deinit_func) (void *ctx);
typedef int (*gnutls_mac_fast_func) (gnutls_mac_algorithm_t, const void *nonce,
size_t nonce_size, const void *key, size_t keysize,
const void *text, size_t textsize, void *digest);
+typedef void *(*gnutls_mac_copy_func) (const void *ctx);
int
gnutls_crypto_register_mac(gnutls_mac_algorithm_t mac,