diff options
author | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2016-12-14 03:15:49 +0300 |
---|---|---|
committer | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2016-12-14 17:20:01 +0300 |
commit | ab4f250945f056efef028a9dbb6d435d1c0c1d1b (patch) | |
tree | 53d65ebbbb3ee0ce970eaa0ba1a9537c65cf7c40 | |
parent | 0991158e093c9e81dfd141fb95db3f4ff161e8d0 (diff) | |
download | gnutls-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.c | 1 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 6 | ||||
-rw-r--r-- | lib/nettle/mac.c | 35 |
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; |