Add EVP_md5_sha1.
Use it in ssl3_cert_verify_hash so signing a pre-TLS-1.2 handshake hash can go
through RSA_sign and be intercepted via RSA_METHOD appropriately. This avoids
Windows needing to intercept sign_raw. (CAPI keys cannot provide sign_raw,
unless the input size happens to be that of NID_md5_sha1.)
Also use it in processing ServerKeyExchange to avoid special-casing RSA.
BUG=crbug.com/437023
Change-Id: Ia07433f468b75fdf7bfc8fa90c9751639b2478e6
Reviewed-on: https://boringssl-review.googlesource.com/2420
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/digest/digest_test.c b/crypto/digest/digest_test.c
index 7c37cb5..6c73e95 100644
--- a/crypto/digest/digest_test.c
+++ b/crypto/digest/digest_test.c
@@ -112,6 +112,10 @@
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
+
+ /* MD5-SHA1 tests. */
+ { &EVP_md5_sha1, NULL, "abc", 1,
+ "900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
};
static int compare_digest(const TEST_VECTOR *test,
diff --git a/crypto/digest/digests.c b/crypto/digest/digests.c
index e3d3a87..52d446f 100644
--- a/crypto/digest/digests.c
+++ b/crypto/digest/digests.c
@@ -193,6 +193,45 @@
const EVP_MD *EVP_sha512(void) { return &sha512_md; }
+
+typedef struct {
+ MD5_CTX md5;
+ SHA_CTX sha1;
+} MD5_SHA1_CTX;
+
+static int md5_sha1_init(EVP_MD_CTX *md_ctx) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ return MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1);
+}
+
+static int md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, size_t count) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ return MD5_Update(&ctx->md5, data, count) && SHA1_Update(&ctx->sha1, data, count);
+}
+
+static int md5_sha1_final(EVP_MD_CTX *md_ctx, unsigned char *out) {
+ MD5_SHA1_CTX *ctx = md_ctx->md_data;
+ if (!MD5_Final(out, &ctx->md5) ||
+ !SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)) {
+ return 0;
+ }
+ return 1;
+}
+
+static const EVP_MD md5_sha1_md = {
+ NID_md5_sha1,
+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
+ 0 /* flags */,
+ md5_sha1_init,
+ md5_sha1_update,
+ md5_sha1_final,
+ 64 /* block size */,
+ sizeof(MD5_SHA1_CTX),
+};
+
+const EVP_MD *EVP_md5_sha1(void) { return &md5_sha1_md; }
+
+
struct nid_to_digest {
int nid;
const EVP_MD *(*md_func)();
@@ -205,6 +244,7 @@
{ NID_sha256, EVP_sha256 },
{ NID_sha384, EVP_sha384 },
{ NID_sha512, EVP_sha512 },
+ { NID_md5_sha1, EVP_md5_sha1 },
{ NID_dsaWithSHA, EVP_sha1 },
{ NID_dsaWithSHA1, EVP_sha1 },
{ NID_ecdsa_with_SHA1, EVP_sha1 },