1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to.  The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 *    notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 *    notice, this list of conditions and the following disclaimer in the
29 *    documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 *    must display the following acknowledgement:
32 *    "This product includes cryptographic software written by
33 *     Eric Young (eay@cryptsoft.com)"
34 *    The word 'cryptographic' can be left out if the rouines from the library
35 *    being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 *    the apps directory (application code) you must include an acknowledgement:
38 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <openssl/digest.h>
58
59#include <assert.h>
60#include <string.h>
61
62#include <openssl/md4.h>
63#include <openssl/md5.h>
64#include <openssl/nid.h>
65#include <openssl/sha.h>
66
67#include "internal.h"
68#include "../delocate.h"
69#include "../../internal.h"
70
71#if defined(NDEBUG)
72#define CHECK(x) (void) (x)
73#else
74#define CHECK(x) assert(x)
75#endif
76
77
78static void md4_init(EVP_MD_CTX *ctx) {
79  CHECK(MD4_Init(ctx->md_data));
80}
81
82static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
83  CHECK(MD4_Update(ctx->md_data, data, count));
84}
85
86static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) {
87  CHECK(MD4_Final(out, ctx->md_data));
88}
89
90DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) {
91  out->type = NID_md4;
92  out->md_size = MD4_DIGEST_LENGTH;
93  out->flags = 0;
94  out->init = md4_init;
95  out->update = md4_update;
96  out->final = md4_final;
97  out->block_size = 64;
98  out->ctx_size = sizeof(MD4_CTX);
99}
100
101
102static void md5_init(EVP_MD_CTX *ctx) {
103  CHECK(MD5_Init(ctx->md_data));
104}
105
106static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
107  CHECK(MD5_Update(ctx->md_data, data, count));
108}
109
110static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) {
111  CHECK(MD5_Final(out, ctx->md_data));
112}
113
114DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) {
115  out->type = NID_md5;
116  out->md_size = MD5_DIGEST_LENGTH;
117  out->flags = 0;
118  out->init = md5_init;
119  out->update = md5_update;
120  out->final = md5_final;
121  out->block_size = 64;
122  out->ctx_size = sizeof(MD5_CTX);
123}
124
125
126static void sha1_init(EVP_MD_CTX *ctx) {
127  CHECK(SHA1_Init(ctx->md_data));
128}
129
130static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
131  CHECK(SHA1_Update(ctx->md_data, data, count));
132}
133
134static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) {
135  CHECK(SHA1_Final(md, ctx->md_data));
136}
137
138DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) {
139  out->type = NID_sha1;
140  out->md_size = SHA_DIGEST_LENGTH;
141  out->flags = 0;
142  out->init = sha1_init;
143  out->update = sha1_update;
144  out->final = sha1_final;
145  out->block_size = 64;
146  out->ctx_size = sizeof(SHA_CTX);
147}
148
149
150static void sha224_init(EVP_MD_CTX *ctx) {
151  CHECK(SHA224_Init(ctx->md_data));
152}
153
154static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
155  CHECK(SHA224_Update(ctx->md_data, data, count));
156}
157
158static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) {
159  CHECK(SHA224_Final(md, ctx->md_data));
160}
161
162DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) {
163  out->type = NID_sha224;
164  out->md_size = SHA224_DIGEST_LENGTH;
165  out->flags = 0;
166  out->init = sha224_init;
167  out->update = sha224_update;
168  out->final = sha224_final;
169  out->block_size = 64;
170  out->ctx_size = sizeof(SHA256_CTX);
171}
172
173
174static void sha256_init(EVP_MD_CTX *ctx) {
175  CHECK(SHA256_Init(ctx->md_data));
176}
177
178static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
179  CHECK(SHA256_Update(ctx->md_data, data, count));
180}
181
182static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) {
183  CHECK(SHA256_Final(md, ctx->md_data));
184}
185
186DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) {
187  out->type = NID_sha256;
188  out->md_size = SHA256_DIGEST_LENGTH;
189  out->flags = 0;
190  out->init = sha256_init;
191  out->update = sha256_update;
192  out->final = sha256_final;
193  out->block_size = 64;
194  out->ctx_size = sizeof(SHA256_CTX);
195}
196
197
198static void sha384_init(EVP_MD_CTX *ctx) {
199  CHECK(SHA384_Init(ctx->md_data));
200}
201
202static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
203  CHECK(SHA384_Update(ctx->md_data, data, count));
204}
205
206static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) {
207  CHECK(SHA384_Final(md, ctx->md_data));
208}
209
210DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) {
211  out->type = NID_sha384;
212  out->md_size = SHA384_DIGEST_LENGTH;
213  out->flags = 0;
214  out->init = sha384_init;
215  out->update = sha384_update;
216  out->final = sha384_final;
217  out->block_size = 128;
218  out->ctx_size = sizeof(SHA512_CTX);
219}
220
221
222static void sha512_init(EVP_MD_CTX *ctx) {
223  CHECK(SHA512_Init(ctx->md_data));
224}
225
226static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
227  CHECK(SHA512_Update(ctx->md_data, data, count));
228}
229
230static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) {
231  CHECK(SHA512_Final(md, ctx->md_data));
232}
233
234DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) {
235  out->type = NID_sha512;
236  out->md_size = SHA512_DIGEST_LENGTH;
237  out->flags = 0;
238  out->init = sha512_init;
239  out->update = sha512_update;
240  out->final = sha512_final;
241  out->block_size = 128;
242  out->ctx_size = sizeof(SHA512_CTX);
243}
244
245
246typedef struct {
247  MD5_CTX md5;
248  SHA_CTX sha1;
249} MD5_SHA1_CTX;
250
251static void md5_sha1_init(EVP_MD_CTX *md_ctx) {
252  MD5_SHA1_CTX *ctx = md_ctx->md_data;
253  CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1));
254}
255
256static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
257                            size_t count) {
258  MD5_SHA1_CTX *ctx = md_ctx->md_data;
259  CHECK(MD5_Update(&ctx->md5, data, count) &&
260        SHA1_Update(&ctx->sha1, data, count));
261}
262
263static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) {
264  MD5_SHA1_CTX *ctx = md_ctx->md_data;
265  CHECK(MD5_Final(out, &ctx->md5) &&
266        SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1));
267}
268
269DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) {
270  out->type = NID_md5_sha1;
271  out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
272  out->flags = 0;
273  out->init = md5_sha1_init;
274  out->update = md5_sha1_update;
275  out->final = md5_sha1_final;
276  out->block_size = 64;
277  out->ctx_size = sizeof(MD5_SHA1_CTX);
278}
279
280#undef CHECK
281