summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2016-12-14 03:15:49 +0300
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2016-12-14 17:20:01 +0300
commitab4f250945f056efef028a9dbb6d435d1c0c1d1b (patch)
tree53d65ebbbb3ee0ce970eaa0ba1a9537c65cf7c40
parent0991158e093c9e81dfd141fb95db3f4ff161e8d0 (diff)
downloadgnutls-ab4f250945f056efef028a9dbb6d435d1c0c1d1b.tar.gz
Add special MD5+SHA1 digest to simplify TLS signature code
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r--lib/algorithms/mac.c1
-rw-r--r--lib/includes/gnutls/gnutls.h.in6
-rw-r--r--lib/nettle/mac.c35
3 files changed, 41 insertions, 1 deletions
diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c
index 0198e4a205..c04dadf0db 100644
--- a/lib/algorithms/mac.c
+++ b/lib/algorithms/mac.c
@@ -34,6 +34,7 @@
static const mac_entry_st hash_algorithms[] = {
{"SHA1", HASH_OID_SHA1, MAC_OID_SHA1, GNUTLS_MAC_SHA1, 20, 20, 0, 0, 1, 64},
{"MD5", HASH_OID_MD5, NULL, GNUTLS_MAC_MD5, 16, 16, 0, 0, 0, 64},
+ {"MD5+SHA1", NULL, NULL, GNUTLS_MAC_MD5_SHA1, 36, 36, 0, 0, 0, 64},
{"SHA256", HASH_OID_SHA256, MAC_OID_SHA256, GNUTLS_MAC_SHA256, 32, 32, 0, 0, 1,
64},
{"SHA384", HASH_OID_SHA384, MAC_OID_SHA384, GNUTLS_MAC_SHA384, 48, 48, 0, 0, 1,
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index dbac6a3046..477e572b1e 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -252,6 +252,7 @@ typedef enum {
* @GNUTLS_MAC_SHA384: HMAC-SHA-384 algorithm.
* @GNUTLS_MAC_SHA512: HMAC-SHA-512 algorithm.
* @GNUTLS_MAC_SHA224: HMAC-SHA-224 algorithm.
+ * @GNUTLS_MAC_MD5_SHA1: Combined MD5+SHA1 MAC placeholder.
* @GNUTLS_MAC_AEAD: MAC implicit through AEAD cipher.
* @GNUTLS_MAC_UMAC_96: The UMAC-96 MAC algorithm.
* @GNUTLS_MAC_UMAC_128: The UMAC-128 MAC algorithm.
@@ -274,6 +275,7 @@ typedef enum {
GNUTLS_MAC_SHA3_256 = 11, /* reserved: no implementation */
GNUTLS_MAC_SHA3_384 = 12, /* reserved: no implementation */
GNUTLS_MAC_SHA3_512 = 13, /* reserved: no implementation */
+ GNUTLS_MAC_MD5_SHA1 = 14, /* reserved: no implementation */
/* If you add anything here, make sure you align with
gnutls_digest_algorithm_t. */
GNUTLS_MAC_AEAD = 200, /* indicates that MAC is on the cipher */
@@ -297,6 +299,7 @@ typedef enum {
* @GNUTLS_DIG_SHA3_256: SHA3-256 algorithm.
* @GNUTLS_DIG_SHA3_384: SHA3-384 algorithm.
* @GNUTLS_DIG_SHA3_512: SHA3-512 algorithm.
+ * @GNUTLS_DIG_MD5_SHA1: Combined MD5+SHA1 algorithm.
*
* Enumeration of different digest (hash) algorithms.
*/
@@ -314,7 +317,8 @@ typedef enum {
GNUTLS_DIG_SHA3_224 = GNUTLS_MAC_SHA3_224,
GNUTLS_DIG_SHA3_256 = GNUTLS_MAC_SHA3_256,
GNUTLS_DIG_SHA3_384 = GNUTLS_MAC_SHA3_384,
- GNUTLS_DIG_SHA3_512 = GNUTLS_MAC_SHA3_512
+ GNUTLS_DIG_SHA3_512 = GNUTLS_MAC_SHA3_512,
+ GNUTLS_DIG_MD5_SHA1 = GNUTLS_MAC_MD5_SHA1
/* If you add anything here, make sure you align with
gnutls_mac_algorithm_t. */
} gnutls_digest_algorithm_t;
diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c
index 311bd404a9..e63ff6110b 100644
--- a/lib/nettle/mac.c
+++ b/lib/nettle/mac.c
@@ -42,6 +42,11 @@ typedef void (*set_nonce_func) (void *, size_t, const uint8_t *);
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo,
void **_ctx);
+struct md5_sha1_ctx {
+ struct md5_ctx md5;
+ struct sha1_ctx sha1;
+};
+
struct nettle_hash_ctx {
union {
struct md5_ctx md5;
@@ -55,6 +60,7 @@ struct nettle_hash_ctx {
struct sha3_512_ctx sha3_512;
struct sha1_ctx sha1;
struct md2_ctx md2;
+ struct md5_sha1_ctx md5_sha1;
} ctx;
void *ctx_ptr;
gnutls_digest_algorithm_t algo;
@@ -325,6 +331,7 @@ static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
switch (algo) {
case GNUTLS_DIG_MD5:
case GNUTLS_DIG_SHA1:
+ case GNUTLS_DIG_MD5_SHA1:
case GNUTLS_DIG_SHA224:
case GNUTLS_DIG_SHA256:
@@ -350,6 +357,26 @@ static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
}
}
+static void _md5_sha1_update(void *_ctx, size_t len, const uint8_t *data)
+{
+ struct md5_sha1_ctx *ctx = _ctx;
+
+ md5_update(&ctx->md5, len, data);
+ sha1_update(&ctx->sha1, len, data);
+}
+
+static void _md5_sha1_digest(void *_ctx, size_t len, uint8_t *digest)
+{
+ struct md5_sha1_ctx *ctx = _ctx;
+
+ md5_digest(&ctx->md5, len <= MD5_DIGEST_SIZE ? len : MD5_DIGEST_SIZE,
+ digest);
+
+ if (len > MD5_DIGEST_SIZE)
+ sha1_digest(&ctx->sha1, len - MD5_DIGEST_SIZE,
+ digest + MD5_DIGEST_SIZE);
+}
+
static int _ctx_init(gnutls_digest_algorithm_t algo,
struct nettle_hash_ctx *ctx)
{
@@ -368,6 +395,14 @@ static int _ctx_init(gnutls_digest_algorithm_t algo,
ctx->ctx_ptr = &ctx->ctx.sha1;
ctx->length = SHA1_DIGEST_SIZE;
break;
+ case GNUTLS_DIG_MD5_SHA1:
+ md5_init(&ctx->ctx.md5_sha1.md5);
+ sha1_init(&ctx->ctx.md5_sha1.sha1);
+ ctx->update = (update_func) _md5_sha1_update;
+ ctx->digest = (digest_func) _md5_sha1_digest;
+ ctx->ctx_ptr = &ctx->ctx.md5_sha1;
+ ctx->length = MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE;
+ break;
case GNUTLS_DIG_SHA224:
sha224_init(&ctx->ctx.sha224);
ctx->update = (update_func) sha224_update;