1 | /* |
2 | * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | #include <string.h> |
10 | #include "prov/md5_sha1.h" |
11 | #include <openssl/evp.h> |
12 | |
13 | int md5_sha1_init(MD5_SHA1_CTX *mctx) |
14 | { |
15 | if (!MD5_Init(&mctx->md5)) |
16 | return 0; |
17 | return SHA1_Init(&mctx->sha1); |
18 | } |
19 | |
20 | int md5_sha1_update(MD5_SHA1_CTX *mctx, const void *data, size_t count) |
21 | { |
22 | if (!MD5_Update(&mctx->md5, data, count)) |
23 | return 0; |
24 | return SHA1_Update(&mctx->sha1, data, count); |
25 | } |
26 | |
27 | int md5_sha1_final(unsigned char *md, MD5_SHA1_CTX *mctx) |
28 | { |
29 | if (!MD5_Final(md, &mctx->md5)) |
30 | return 0; |
31 | return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); |
32 | } |
33 | |
34 | int md5_sha1_ctrl(MD5_SHA1_CTX *mctx, int cmd, int mslen, void *ms) |
35 | { |
36 | unsigned char padtmp[48]; |
37 | unsigned char md5tmp[MD5_DIGEST_LENGTH]; |
38 | unsigned char sha1tmp[SHA_DIGEST_LENGTH]; |
39 | |
40 | if (cmd != EVP_CTRL_SSL3_MASTER_SECRET) |
41 | return -2; |
42 | |
43 | if (mctx == NULL) |
44 | return 0; |
45 | |
46 | /* SSLv3 client auth handling: see RFC-6101 5.6.8 */ |
47 | if (mslen != 48) |
48 | return 0; |
49 | |
50 | /* At this point hash contains all handshake messages, update |
51 | * with master secret and pad_1. |
52 | */ |
53 | |
54 | if (md5_sha1_update(mctx, ms, mslen) <= 0) |
55 | return 0; |
56 | |
57 | /* Set padtmp to pad_1 value */ |
58 | memset(padtmp, 0x36, sizeof(padtmp)); |
59 | |
60 | if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp))) |
61 | return 0; |
62 | |
63 | if (!MD5_Final(md5tmp, &mctx->md5)) |
64 | return 0; |
65 | |
66 | if (!SHA1_Update(&mctx->sha1, padtmp, 40)) |
67 | return 0; |
68 | |
69 | if (!SHA1_Final(sha1tmp, &mctx->sha1)) |
70 | return 0; |
71 | |
72 | /* Reinitialise context */ |
73 | |
74 | if (!md5_sha1_init(mctx)) |
75 | return 0; |
76 | |
77 | if (md5_sha1_update(mctx, ms, mslen) <= 0) |
78 | return 0; |
79 | |
80 | /* Set padtmp to pad_2 value */ |
81 | memset(padtmp, 0x5c, sizeof(padtmp)); |
82 | |
83 | if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp))) |
84 | return 0; |
85 | |
86 | if (!MD5_Update(&mctx->md5, md5tmp, sizeof(md5tmp))) |
87 | return 0; |
88 | |
89 | if (!SHA1_Update(&mctx->sha1, padtmp, 40)) |
90 | return 0; |
91 | |
92 | if (!SHA1_Update(&mctx->sha1, sha1tmp, sizeof(sha1tmp))) |
93 | return 0; |
94 | |
95 | /* Now when ctx is finalised it will return the SSL v3 hash value */ |
96 | |
97 | OPENSSL_cleanse(md5tmp, sizeof(md5tmp)); |
98 | OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp)); |
99 | |
100 | return 1; |
101 | } |
102 | |