155714Skris/* crypto/evp/digest.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
58109998Smarkm/* ====================================================================
59109998Smarkm * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
60109998Smarkm *
61109998Smarkm * Redistribution and use in source and binary forms, with or without
62109998Smarkm * modification, are permitted provided that the following conditions
63109998Smarkm * are met:
64109998Smarkm *
65109998Smarkm * 1. Redistributions of source code must retain the above copyright
66296341Sdelphij *    notice, this list of conditions and the following disclaimer.
67109998Smarkm *
68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
69109998Smarkm *    notice, this list of conditions and the following disclaimer in
70109998Smarkm *    the documentation and/or other materials provided with the
71109998Smarkm *    distribution.
72109998Smarkm *
73109998Smarkm * 3. All advertising materials mentioning features or use of this
74109998Smarkm *    software must display the following acknowledgment:
75109998Smarkm *    "This product includes software developed by the OpenSSL Project
76109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77109998Smarkm *
78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79109998Smarkm *    endorse or promote products derived from this software without
80109998Smarkm *    prior written permission. For written permission, please contact
81109998Smarkm *    openssl-core@openssl.org.
82109998Smarkm *
83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
84109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
85109998Smarkm *    permission of the OpenSSL Project.
86109998Smarkm *
87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
88109998Smarkm *    acknowledgment:
89109998Smarkm *    "This product includes software developed by the OpenSSL Project
90109998Smarkm *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91109998Smarkm *
92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
104109998Smarkm * ====================================================================
105109998Smarkm *
106109998Smarkm * This product includes cryptographic software written by Eric Young
107109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
108109998Smarkm * Hudson (tjh@cryptsoft.com).
109109998Smarkm *
110109998Smarkm */
11155714Skris
11255714Skris#include <stdio.h>
11355714Skris#include "cryptlib.h"
11455714Skris#include <openssl/objects.h>
11555714Skris#include <openssl/evp.h>
116111147Snectar#ifndef OPENSSL_NO_ENGINE
117296341Sdelphij# include <openssl/engine.h>
118111147Snectar#endif
11955714Skris
120238405Sjkim#ifdef OPENSSL_FIPS
121296341Sdelphij# include <openssl/fips.h>
122238405Sjkim#endif
123238405Sjkim
124109998Smarkmvoid EVP_MD_CTX_init(EVP_MD_CTX *ctx)
125296341Sdelphij{
126296341Sdelphij    memset(ctx, '\0', sizeof *ctx);
127296341Sdelphij}
12855714Skris
129109998SmarkmEVP_MD_CTX *EVP_MD_CTX_create(void)
130296341Sdelphij{
131296341Sdelphij    EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
132109998Smarkm
133296341Sdelphij    if (ctx)
134296341Sdelphij        EVP_MD_CTX_init(ctx);
135109998Smarkm
136296341Sdelphij    return ctx;
137296341Sdelphij}
138109998Smarkm
139109998Smarkmint EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
140296341Sdelphij{
141296341Sdelphij    EVP_MD_CTX_init(ctx);
142296341Sdelphij    return EVP_DigestInit_ex(ctx, type, NULL);
143296341Sdelphij}
144109998Smarkm
145238405Sjkimint EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
146296341Sdelphij{
147296341Sdelphij    EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
148111147Snectar#ifndef OPENSSL_NO_ENGINE
149296341Sdelphij    /*
150296341Sdelphij     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
151296341Sdelphij     * this context may already have an ENGINE! Try to avoid releasing the
152296341Sdelphij     * previous handle, re-querying for an ENGINE, and having a
153296341Sdelphij     * reinitialisation, when it may all be unecessary.
154296341Sdelphij     */
155296341Sdelphij    if (ctx->engine && ctx->digest && (!type ||
156296341Sdelphij                                       (type
157296341Sdelphij                                        && (type->type ==
158296341Sdelphij                                            ctx->digest->type))))
159296341Sdelphij        goto skip_to_init;
160296341Sdelphij    if (type) {
161296341Sdelphij        /*
162296341Sdelphij         * Ensure an ENGINE left lying around from last time is cleared (the
163296341Sdelphij         * previous check attempted to avoid this if the same ENGINE and
164296341Sdelphij         * EVP_MD could be used).
165296341Sdelphij         */
166296341Sdelphij        if (ctx->engine)
167296341Sdelphij            ENGINE_finish(ctx->engine);
168296341Sdelphij        if (impl) {
169296341Sdelphij            if (!ENGINE_init(impl)) {
170296341Sdelphij                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
171296341Sdelphij                return 0;
172296341Sdelphij            }
173296341Sdelphij        } else
174296341Sdelphij            /* Ask if an ENGINE is reserved for this job */
175296341Sdelphij            impl = ENGINE_get_digest_engine(type->type);
176296341Sdelphij        if (impl) {
177296341Sdelphij            /* There's an ENGINE for this job ... (apparently) */
178296341Sdelphij            const EVP_MD *d = ENGINE_get_digest(impl, type->type);
179296341Sdelphij            if (!d) {
180296341Sdelphij                /* Same comment from evp_enc.c */
181296341Sdelphij                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
182296341Sdelphij                ENGINE_finish(impl);
183296341Sdelphij                return 0;
184296341Sdelphij            }
185296341Sdelphij            /* We'll use the ENGINE's private digest definition */
186296341Sdelphij            type = d;
187296341Sdelphij            /*
188296341Sdelphij             * Store the ENGINE functional reference so we know 'type' came
189296341Sdelphij             * from an ENGINE and we need to release it when done.
190296341Sdelphij             */
191296341Sdelphij            ctx->engine = impl;
192296341Sdelphij        } else
193296341Sdelphij            ctx->engine = NULL;
194296341Sdelphij    } else {
195296341Sdelphij        if (!ctx->digest) {
196296341Sdelphij            EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
197296341Sdelphij            return 0;
198296341Sdelphij        }
199296341Sdelphij        type = ctx->digest;
200296341Sdelphij    }
201120631Snectar#endif
202296341Sdelphij    if (ctx->digest != type) {
203296341Sdelphij        if (ctx->digest && ctx->digest->ctx_size)
204296341Sdelphij            OPENSSL_free(ctx->md_data);
205296341Sdelphij        ctx->digest = type;
206296341Sdelphij        if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
207296341Sdelphij            ctx->update = type->update;
208296341Sdelphij            ctx->md_data = OPENSSL_malloc(type->ctx_size);
209296341Sdelphij            if (ctx->md_data == NULL) {
210296341Sdelphij                EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
211296341Sdelphij                return 0;
212296341Sdelphij            }
213296341Sdelphij        }
214296341Sdelphij    }
215111147Snectar#ifndef OPENSSL_NO_ENGINE
216296341Sdelphij skip_to_init:
217111147Snectar#endif
218296341Sdelphij    if (ctx->pctx) {
219296341Sdelphij        int r;
220296341Sdelphij        r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
221296341Sdelphij                              EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
222296341Sdelphij        if (r <= 0 && (r != -2))
223296341Sdelphij            return 0;
224296341Sdelphij    }
225296341Sdelphij    if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
226296341Sdelphij        return 1;
227238405Sjkim#ifdef OPENSSL_FIPS
228296341Sdelphij    if (FIPS_mode()) {
229296341Sdelphij        if (FIPS_digestinit(ctx, type))
230296341Sdelphij            return 1;
231296341Sdelphij        OPENSSL_free(ctx->md_data);
232296341Sdelphij        ctx->md_data = NULL;
233296341Sdelphij        return 0;
234296341Sdelphij    }
235238405Sjkim#endif
236296341Sdelphij    return ctx->digest->init(ctx);
237296341Sdelphij}
238109998Smarkm
239238405Sjkimint EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
240296341Sdelphij{
241194206Ssimon#ifdef OPENSSL_FIPS
242296341Sdelphij    return FIPS_digestupdate(ctx, data, count);
243238405Sjkim#else
244296341Sdelphij    return ctx->update(ctx, data, count);
245194206Ssimon#endif
246296341Sdelphij}
24755714Skris
248109998Smarkm/* The caller can assume that this removes any secret data from the context */
249109998Smarkmint EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
250296341Sdelphij{
251296341Sdelphij    int ret;
252296341Sdelphij    ret = EVP_DigestFinal_ex(ctx, md, size);
253296341Sdelphij    EVP_MD_CTX_cleanup(ctx);
254296341Sdelphij    return ret;
255296341Sdelphij}
256109998Smarkm
257109998Smarkm/* The caller can assume that this removes any secret data from the context */
258109998Smarkmint EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
259296341Sdelphij{
260238405Sjkim#ifdef OPENSSL_FIPS
261296341Sdelphij    return FIPS_digestfinal(ctx, md, size);
262238405Sjkim#else
263296341Sdelphij    int ret;
264246772Sjkim
265296341Sdelphij    OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
266296341Sdelphij    ret = ctx->digest->final(ctx, md);
267296341Sdelphij    if (size != NULL)
268296341Sdelphij        *size = ctx->digest->md_size;
269296341Sdelphij    if (ctx->digest->cleanup) {
270296341Sdelphij        ctx->digest->cleanup(ctx);
271296341Sdelphij        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
272296341Sdelphij    }
273296341Sdelphij    memset(ctx->md_data, 0, ctx->digest->ctx_size);
274296341Sdelphij    return ret;
275238405Sjkim#endif
276296341Sdelphij}
27755714Skris
278109998Smarkmint EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
279296341Sdelphij{
280296341Sdelphij    EVP_MD_CTX_init(out);
281296341Sdelphij    return EVP_MD_CTX_copy_ex(out, in);
282296341Sdelphij}
283109998Smarkm
284109998Smarkmint EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
285296341Sdelphij{
286296341Sdelphij    unsigned char *tmp_buf;
287296341Sdelphij    if ((in == NULL) || (in->digest == NULL)) {
288296341Sdelphij        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
289296341Sdelphij        return 0;
290296341Sdelphij    }
291111147Snectar#ifndef OPENSSL_NO_ENGINE
292296341Sdelphij    /* Make sure it's safe to copy a digest context using an ENGINE */
293296341Sdelphij    if (in->engine && !ENGINE_init(in->engine)) {
294296341Sdelphij        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
295296341Sdelphij        return 0;
296296341Sdelphij    }
297111147Snectar#endif
298109998Smarkm
299296341Sdelphij    if (out->digest == in->digest) {
300296341Sdelphij        tmp_buf = out->md_data;
301296341Sdelphij        EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
302296341Sdelphij    } else
303296341Sdelphij        tmp_buf = NULL;
304296341Sdelphij    EVP_MD_CTX_cleanup(out);
305296341Sdelphij    memcpy(out, in, sizeof *out);
306109998Smarkm
307296341Sdelphij    if (in->md_data && out->digest->ctx_size) {
308296341Sdelphij        if (tmp_buf)
309296341Sdelphij            out->md_data = tmp_buf;
310296341Sdelphij        else {
311296341Sdelphij            out->md_data = OPENSSL_malloc(out->digest->ctx_size);
312296341Sdelphij            if (!out->md_data) {
313296341Sdelphij                EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
314296341Sdelphij                return 0;
315296341Sdelphij            }
316296341Sdelphij        }
317296341Sdelphij        memcpy(out->md_data, in->md_data, out->digest->ctx_size);
318296341Sdelphij    }
319127128Snectar
320296341Sdelphij    out->update = in->update;
321238405Sjkim
322296341Sdelphij    if (in->pctx) {
323296341Sdelphij        out->pctx = EVP_PKEY_CTX_dup(in->pctx);
324296341Sdelphij        if (!out->pctx) {
325296341Sdelphij            EVP_MD_CTX_cleanup(out);
326296341Sdelphij            return 0;
327296341Sdelphij        }
328296341Sdelphij    }
329238405Sjkim
330296341Sdelphij    if (out->digest->copy)
331296341Sdelphij        return out->digest->copy(out, in);
332109998Smarkm
333296341Sdelphij    return 1;
334296341Sdelphij}
335296341Sdelphij
336160814Ssimonint EVP_Digest(const void *data, size_t count,
337296341Sdelphij               unsigned char *md, unsigned int *size, const EVP_MD *type,
338296341Sdelphij               ENGINE *impl)
339296341Sdelphij{
340296341Sdelphij    EVP_MD_CTX ctx;
341296341Sdelphij    int ret;
342109998Smarkm
343296341Sdelphij    EVP_MD_CTX_init(&ctx);
344296341Sdelphij    EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
345296341Sdelphij    ret = EVP_DigestInit_ex(&ctx, type, impl)
346296341Sdelphij        && EVP_DigestUpdate(&ctx, data, count)
347296341Sdelphij        && EVP_DigestFinal_ex(&ctx, md, size);
348296341Sdelphij    EVP_MD_CTX_cleanup(&ctx);
349109998Smarkm
350296341Sdelphij    return ret;
351296341Sdelphij}
352109998Smarkm
353109998Smarkmvoid EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
354296341Sdelphij{
355296341Sdelphij    if (ctx) {
356296341Sdelphij        EVP_MD_CTX_cleanup(ctx);
357296341Sdelphij        OPENSSL_free(ctx);
358296341Sdelphij    }
359296341Sdelphij}
360109998Smarkm
361109998Smarkm/* This call frees resources associated with the context */
362109998Smarkmint EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
363296341Sdelphij{
364238405Sjkim#ifndef OPENSSL_FIPS
365296341Sdelphij    /*
366296341Sdelphij     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
367296341Sdelphij     * sometimes only copies of the context are ever finalised.
368296341Sdelphij     */
369296341Sdelphij    if (ctx->digest && ctx->digest->cleanup
370296341Sdelphij        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
371296341Sdelphij        ctx->digest->cleanup(ctx);
372296341Sdelphij    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
373296341Sdelphij        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
374296341Sdelphij        OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
375296341Sdelphij        OPENSSL_free(ctx->md_data);
376296341Sdelphij    }
377238405Sjkim#endif
378296341Sdelphij    if (ctx->pctx)
379296341Sdelphij        EVP_PKEY_CTX_free(ctx->pctx);
380111147Snectar#ifndef OPENSSL_NO_ENGINE
381296341Sdelphij    if (ctx->engine)
382296341Sdelphij        /*
383296341Sdelphij         * The EVP_MD we used belongs to an ENGINE, release the functional
384296341Sdelphij         * reference we held for this reason.
385296341Sdelphij         */
386296341Sdelphij        ENGINE_finish(ctx->engine);
387111147Snectar#endif
388238405Sjkim#ifdef OPENSSL_FIPS
389296341Sdelphij    FIPS_md_ctx_cleanup(ctx);
390238405Sjkim#endif
391296341Sdelphij    memset(ctx, '\0', sizeof *ctx);
392109998Smarkm
393296341Sdelphij    return 1;
394296341Sdelphij}
395