1 /* $OpenBSD: m_md5_sha1.c,v 1.2 2018/08/10 17:30:29 jsing Exp $ */
2 /*
3  * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/evp.h>
19 #include <openssl/md5.h>
20 #include <openssl/objects.h>
21 #include <openssl/sha.h>
22 
23 #ifndef OPENSSL_NO_RSA
24 #include <openssl/rsa.h>
25 #endif
26 
27 struct md5_sha1_ctx {
28 	MD5_CTX md5;
29 	SHA_CTX sha1;
30 };
31 
32 static int
33 md5_sha1_init(EVP_MD_CTX *ctx)
34 {
35 	struct md5_sha1_ctx *mdctx = ctx->md_data;
36 
37 	if (!MD5_Init(&mdctx->md5))
38 		return 0;
39 	if (!SHA1_Init(&mdctx->sha1))
40 		return 0;
41 
42 	return 1;
43 }
44 
45 static int
46 md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
47 {
48 	struct md5_sha1_ctx *mdctx = ctx->md_data;
49 
50 	if (!MD5_Update(&mdctx->md5, data, count))
51 		return 0;
52 	if (!SHA1_Update(&mdctx->sha1, data, count))
53 		return 0;
54 
55 	return 1;
56 }
57 
58 static int
59 md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *out)
60 {
61 	struct md5_sha1_ctx *mdctx = ctx->md_data;
62 
63 	if (!MD5_Final(out, &mdctx->md5))
64 		return 0;
65 	if (!SHA1_Final(out + MD5_DIGEST_LENGTH, &mdctx->sha1))
66 		return 0;
67 
68 	return 1;
69 }
70 
71 static const EVP_MD md5_sha1_md = {
72         .type = NID_md5_sha1,
73         .pkey_type = NID_md5_sha1,
74         .md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
75         .flags = 0,
76         .init = md5_sha1_init,
77         .update = md5_sha1_update,
78         .final = md5_sha1_final,
79         .block_size = MD5_CBLOCK, /* MD5_CBLOCK == SHA_CBLOCK */
80         .ctx_size = sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
81 #ifndef OPENSSL_NO_RSA
82 	.sign = (evp_sign_method *)RSA_sign,
83 	.verify = (evp_verify_method *)RSA_verify,
84 	.required_pkey_type = {
85 		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
86 	},
87 #endif
88 };
89 
90 const EVP_MD *
91 EVP_md5_sha1(void)
92 {
93 	return &md5_sha1_md;
94 }
95