Line data Source code
1 : /* crypto/evp/digest.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 : /* ====================================================================
59 : * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 : *
61 : * Redistribution and use in source and binary forms, with or without
62 : * modification, are permitted provided that the following conditions
63 : * are met:
64 : *
65 : * 1. Redistributions of source code must retain the above copyright
66 : * notice, this list of conditions and the following disclaimer.
67 : *
68 : * 2. Redistributions in binary form must reproduce the above copyright
69 : * notice, this list of conditions and the following disclaimer in
70 : * the documentation and/or other materials provided with the
71 : * distribution.
72 : *
73 : * 3. All advertising materials mentioning features or use of this
74 : * software must display the following acknowledgment:
75 : * "This product includes software developed by the OpenSSL Project
76 : * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 : *
78 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 : * endorse or promote products derived from this software without
80 : * prior written permission. For written permission, please contact
81 : * openssl-core@openssl.org.
82 : *
83 : * 5. Products derived from this software may not be called "OpenSSL"
84 : * nor may "OpenSSL" appear in their names without prior written
85 : * permission of the OpenSSL Project.
86 : *
87 : * 6. Redistributions of any form whatsoever must retain the following
88 : * acknowledgment:
89 : * "This product includes software developed by the OpenSSL Project
90 : * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 : *
92 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 : * OF THE POSSIBILITY OF SUCH DAMAGE.
104 : * ====================================================================
105 : *
106 : * This product includes cryptographic software written by Eric Young
107 : * (eay@cryptsoft.com). This product includes software written by Tim
108 : * Hudson (tjh@cryptsoft.com).
109 : *
110 : */
111 :
112 : #include <stdio.h>
113 : #include "cryptlib.h"
114 : #include <openssl/objects.h>
115 : #include <openssl/evp.h>
116 : #ifndef OPENSSL_NO_ENGINE
117 : # include <openssl/engine.h>
118 : #endif
119 :
120 : #ifdef OPENSSL_FIPS
121 : # include <openssl/fips.h>
122 : # include "evp_locl.h"
123 : #endif
124 :
125 190220 : void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
126 : {
127 : memset(ctx, '\0', sizeof *ctx);
128 190220 : }
129 :
130 2226 : EVP_MD_CTX *EVP_MD_CTX_create(void)
131 : {
132 2226 : EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
133 :
134 2226 : if (ctx)
135 : EVP_MD_CTX_init(ctx);
136 :
137 2226 : return ctx;
138 : }
139 :
140 0 : int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
141 : {
142 : EVP_MD_CTX_init(ctx);
143 0 : return EVP_DigestInit_ex(ctx, type, NULL);
144 : }
145 :
146 54099 : int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
147 : {
148 54099 : EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
149 : #ifdef OPENSSL_FIPS
150 : /* If FIPS mode switch to approved implementation if possible */
151 : if (FIPS_mode()) {
152 : const EVP_MD *fipsmd;
153 : if (type) {
154 : fipsmd = evp_get_fips_md(type);
155 : if (fipsmd)
156 : type = fipsmd;
157 : }
158 : }
159 : #endif
160 : #ifndef OPENSSL_NO_ENGINE
161 : /*
162 : * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
163 : * this context may already have an ENGINE! Try to avoid releasing the
164 : * previous handle, re-querying for an ENGINE, and having a
165 : * reinitialisation, when it may all be unecessary.
166 : */
167 54099 : if (ctx->engine && ctx->digest && (!type ||
168 : (type
169 0 : && (type->type ==
170 0 : ctx->digest->type))))
171 : goto skip_to_init;
172 54099 : if (type) {
173 : /*
174 : * Ensure an ENGINE left lying around from last time is cleared (the
175 : * previous check attempted to avoid this if the same ENGINE and
176 : * EVP_MD could be used).
177 : */
178 54099 : if (ctx->engine)
179 0 : ENGINE_finish(ctx->engine);
180 54099 : if (impl) {
181 0 : if (!ENGINE_init(impl)) {
182 0 : EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
183 0 : return 0;
184 : }
185 : } else
186 : /* Ask if an ENGINE is reserved for this job */
187 54099 : impl = ENGINE_get_digest_engine(type->type);
188 54099 : if (impl) {
189 : /* There's an ENGINE for this job ... (apparently) */
190 0 : const EVP_MD *d = ENGINE_get_digest(impl, type->type);
191 0 : if (!d) {
192 : /* Same comment from evp_enc.c */
193 0 : EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
194 0 : ENGINE_finish(impl);
195 0 : return 0;
196 : }
197 : /* We'll use the ENGINE's private digest definition */
198 : type = d;
199 : /*
200 : * Store the ENGINE functional reference so we know 'type' came
201 : * from an ENGINE and we need to release it when done.
202 : */
203 0 : ctx->engine = impl;
204 : } else
205 54099 : ctx->engine = NULL;
206 : } else {
207 0 : if (!ctx->digest) {
208 0 : EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
209 0 : return 0;
210 : }
211 : type = ctx->digest;
212 : }
213 : #endif
214 54099 : if (ctx->digest != type) {
215 32393 : if (ctx->digest && ctx->digest->ctx_size)
216 0 : OPENSSL_free(ctx->md_data);
217 32393 : ctx->digest = type;
218 32393 : if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
219 28718 : ctx->update = type->update;
220 28718 : ctx->md_data = OPENSSL_malloc(type->ctx_size);
221 28718 : if (ctx->md_data == NULL) {
222 0 : EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
223 0 : return 0;
224 : }
225 : }
226 : }
227 : #ifndef OPENSSL_NO_ENGINE
228 : skip_to_init:
229 : #endif
230 54099 : if (ctx->pctx) {
231 : int r;
232 4059 : r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
233 : EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
234 4059 : if (r <= 0 && (r != -2))
235 : return 0;
236 : }
237 54099 : if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
238 : return 1;
239 : #ifdef OPENSSL_FIPS
240 : if (FIPS_mode()) {
241 : if (FIPS_digestinit(ctx, type))
242 : return 1;
243 : OPENSSL_free(ctx->md_data);
244 : ctx->md_data = NULL;
245 : return 0;
246 : }
247 : #endif
248 50424 : return ctx->digest->init(ctx);
249 : }
250 :
251 237864 : int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
252 : {
253 : #ifdef OPENSSL_FIPS
254 : return FIPS_digestupdate(ctx, data, count);
255 : #else
256 239266 : return ctx->update(ctx, data, count);
257 : #endif
258 : }
259 :
260 : /* The caller can assume that this removes any secret data from the context */
261 0 : int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
262 : {
263 : int ret;
264 0 : ret = EVP_DigestFinal_ex(ctx, md, size);
265 0 : EVP_MD_CTX_cleanup(ctx);
266 0 : return ret;
267 : }
268 :
269 : /* The caller can assume that this removes any secret data from the context */
270 65128 : int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
271 : {
272 : #ifdef OPENSSL_FIPS
273 : return FIPS_digestfinal(ctx, md, size);
274 : #else
275 : int ret;
276 :
277 65128 : OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
278 65128 : ret = ctx->digest->final(ctx, md);
279 65128 : if (size != NULL)
280 25023 : *size = ctx->digest->md_size;
281 65128 : if (ctx->digest->cleanup) {
282 0 : ctx->digest->cleanup(ctx);
283 0 : EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
284 : }
285 65128 : memset(ctx->md_data, 0, ctx->digest->ctx_size);
286 65128 : return ret;
287 : #endif
288 : }
289 :
290 61788 : int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
291 : {
292 : EVP_MD_CTX_init(out);
293 61788 : return EVP_MD_CTX_copy_ex(out, in);
294 : }
295 :
296 100419 : int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
297 : {
298 : unsigned char *tmp_buf;
299 100419 : if ((in == NULL) || (in->digest == NULL)) {
300 0 : EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
301 0 : return 0;
302 : }
303 : #ifndef OPENSSL_NO_ENGINE
304 : /* Make sure it's safe to copy a digest context using an ENGINE */
305 100419 : if (in->engine && !ENGINE_init(in->engine)) {
306 0 : EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
307 0 : return 0;
308 : }
309 : #endif
310 :
311 100419 : if (out->digest == in->digest) {
312 15814 : tmp_buf = out->md_data;
313 15814 : EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
314 : } else
315 : tmp_buf = NULL;
316 100419 : EVP_MD_CTX_cleanup(out);
317 : memcpy(out, in, sizeof *out);
318 :
319 100419 : if (in->md_data && out->digest->ctx_size) {
320 79823 : if (tmp_buf)
321 10665 : out->md_data = tmp_buf;
322 : else {
323 69158 : out->md_data = OPENSSL_malloc(out->digest->ctx_size);
324 69158 : if (!out->md_data) {
325 0 : EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
326 0 : return 0;
327 : }
328 : }
329 79823 : memcpy(out->md_data, in->md_data, out->digest->ctx_size);
330 : }
331 :
332 100419 : out->update = in->update;
333 :
334 100419 : if (in->pctx) {
335 20980 : out->pctx = EVP_PKEY_CTX_dup(in->pctx);
336 20980 : if (!out->pctx) {
337 0 : EVP_MD_CTX_cleanup(out);
338 0 : return 0;
339 : }
340 : }
341 :
342 100419 : if (out->digest->copy)
343 0 : return out->digest->copy(out, in);
344 :
345 : return 1;
346 : }
347 :
348 1402 : int EVP_Digest(const void *data, size_t count,
349 : unsigned char *md, unsigned int *size, const EVP_MD *type,
350 : ENGINE *impl)
351 : {
352 : EVP_MD_CTX ctx;
353 : int ret;
354 :
355 : EVP_MD_CTX_init(&ctx);
356 1402 : EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
357 1402 : ret = EVP_DigestInit_ex(&ctx, type, impl)
358 1402 : && EVP_DigestUpdate(&ctx, data, count)
359 2804 : && EVP_DigestFinal_ex(&ctx, md, size);
360 1402 : EVP_MD_CTX_cleanup(&ctx);
361 :
362 1402 : return ret;
363 : }
364 :
365 2226 : void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
366 : {
367 2226 : if (ctx) {
368 2226 : EVP_MD_CTX_cleanup(ctx);
369 2226 : OPENSSL_free(ctx);
370 : }
371 2226 : }
372 :
373 : /* This call frees resources associated with the context */
374 232479 : int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
375 : {
376 : #ifndef OPENSSL_FIPS
377 : /*
378 : * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
379 : * sometimes only copies of the context are ever finalised.
380 : */
381 232479 : if (ctx->digest && ctx->digest->cleanup
382 0 : && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
383 0 : ctx->digest->cleanup(ctx);
384 232479 : if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
385 108541 : && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
386 97876 : OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
387 97876 : OPENSSL_free(ctx->md_data);
388 : }
389 : #endif
390 232479 : if (ctx->pctx)
391 25039 : EVP_PKEY_CTX_free(ctx->pctx);
392 : #ifndef OPENSSL_NO_ENGINE
393 232479 : if (ctx->engine)
394 : /*
395 : * The EVP_MD we used belongs to an ENGINE, release the functional
396 : * reference we held for this reason.
397 : */
398 0 : ENGINE_finish(ctx->engine);
399 : #endif
400 : #ifdef OPENSSL_FIPS
401 : FIPS_md_ctx_cleanup(ctx);
402 : #endif
403 : memset(ctx, '\0', sizeof *ctx);
404 :
405 232479 : return 1;
406 : }
|