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/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 },