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. 8280304Sjkim * 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). 15280304Sjkim * 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. 22280304Sjkim * 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 :-). 37280304Sjkim * 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)" 40280304Sjkim * 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. 52280304Sjkim * 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 66280304Sjkim * 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 117280304Sjkim# include <openssl/engine.h> 118111147Snectar#endif 11955714Skris 120238405Sjkim#ifdef OPENSSL_FIPS 121280304Sjkim# include <openssl/fips.h> 122238405Sjkim#endif 123238405Sjkim 124109998Smarkmvoid EVP_MD_CTX_init(EVP_MD_CTX *ctx) 125280304Sjkim{ 126280304Sjkim memset(ctx, '\0', sizeof *ctx); 127280304Sjkim} 12855714Skris 129109998SmarkmEVP_MD_CTX *EVP_MD_CTX_create(void) 130280304Sjkim{ 131280304Sjkim EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx); 132109998Smarkm 133280304Sjkim if (ctx) 134280304Sjkim EVP_MD_CTX_init(ctx); 135109998Smarkm 136280304Sjkim return ctx; 137280304Sjkim} 138109998Smarkm 139109998Smarkmint EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) 140280304Sjkim{ 141280304Sjkim EVP_MD_CTX_init(ctx); 142280304Sjkim return EVP_DigestInit_ex(ctx, type, NULL); 143280304Sjkim} 144109998Smarkm 145238405Sjkimint EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) 146280304Sjkim{ 147280304Sjkim EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 148111147Snectar#ifndef OPENSSL_NO_ENGINE 149280304Sjkim /* 150280304Sjkim * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so 151280304Sjkim * this context may already have an ENGINE! Try to avoid releasing the 152280304Sjkim * previous handle, re-querying for an ENGINE, and having a 153280304Sjkim * reinitialisation, when it may all be unecessary. 154280304Sjkim */ 155280304Sjkim if (ctx->engine && ctx->digest && (!type || 156280304Sjkim (type 157280304Sjkim && (type->type == 158280304Sjkim ctx->digest->type)))) 159280304Sjkim goto skip_to_init; 160280304Sjkim if (type) { 161280304Sjkim /* 162280304Sjkim * Ensure an ENGINE left lying around from last time is cleared (the 163280304Sjkim * previous check attempted to avoid this if the same ENGINE and 164280304Sjkim * EVP_MD could be used). 165280304Sjkim */ 166280304Sjkim if (ctx->engine) 167280304Sjkim ENGINE_finish(ctx->engine); 168280304Sjkim if (impl) { 169280304Sjkim if (!ENGINE_init(impl)) { 170280304Sjkim EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); 171280304Sjkim return 0; 172280304Sjkim } 173280304Sjkim } else 174280304Sjkim /* Ask if an ENGINE is reserved for this job */ 175280304Sjkim impl = ENGINE_get_digest_engine(type->type); 176280304Sjkim if (impl) { 177280304Sjkim /* There's an ENGINE for this job ... (apparently) */ 178280304Sjkim const EVP_MD *d = ENGINE_get_digest(impl, type->type); 179280304Sjkim if (!d) { 180280304Sjkim /* Same comment from evp_enc.c */ 181280304Sjkim EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); 182280304Sjkim ENGINE_finish(impl); 183280304Sjkim return 0; 184280304Sjkim } 185280304Sjkim /* We'll use the ENGINE's private digest definition */ 186280304Sjkim type = d; 187280304Sjkim /* 188280304Sjkim * Store the ENGINE functional reference so we know 'type' came 189280304Sjkim * from an ENGINE and we need to release it when done. 190280304Sjkim */ 191280304Sjkim ctx->engine = impl; 192280304Sjkim } else 193280304Sjkim ctx->engine = NULL; 194280304Sjkim } else { 195280304Sjkim if (!ctx->digest) { 196280304Sjkim EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET); 197280304Sjkim return 0; 198280304Sjkim } 199280304Sjkim type = ctx->digest; 200280304Sjkim } 201120631Snectar#endif 202280304Sjkim if (ctx->digest != type) { 203298999Sjkim if (ctx->digest && ctx->digest->ctx_size) { 204280304Sjkim OPENSSL_free(ctx->md_data); 205298999Sjkim ctx->md_data = NULL; 206298999Sjkim } 207280304Sjkim ctx->digest = type; 208280304Sjkim if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { 209280304Sjkim ctx->update = type->update; 210280304Sjkim ctx->md_data = OPENSSL_malloc(type->ctx_size); 211280304Sjkim if (ctx->md_data == NULL) { 212280304Sjkim EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); 213280304Sjkim return 0; 214280304Sjkim } 215280304Sjkim } 216280304Sjkim } 217111147Snectar#ifndef OPENSSL_NO_ENGINE 218280304Sjkim skip_to_init: 219111147Snectar#endif 220280304Sjkim if (ctx->pctx) { 221280304Sjkim int r; 222280304Sjkim r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, 223280304Sjkim EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); 224280304Sjkim if (r <= 0 && (r != -2)) 225280304Sjkim return 0; 226280304Sjkim } 227280304Sjkim if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) 228280304Sjkim return 1; 229238405Sjkim#ifdef OPENSSL_FIPS 230280304Sjkim if (FIPS_mode()) { 231280304Sjkim if (FIPS_digestinit(ctx, type)) 232280304Sjkim return 1; 233280304Sjkim OPENSSL_free(ctx->md_data); 234280304Sjkim ctx->md_data = NULL; 235280304Sjkim return 0; 236280304Sjkim } 237238405Sjkim#endif 238280304Sjkim return ctx->digest->init(ctx); 239280304Sjkim} 240109998Smarkm 241238405Sjkimint EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) 242280304Sjkim{ 243194206Ssimon#ifdef OPENSSL_FIPS 244306196Sjkim if (FIPS_mode()) 245306196Sjkim return FIPS_digestupdate(ctx, data, count); 246306196Sjkim#endif 247280304Sjkim return ctx->update(ctx, data, count); 248280304Sjkim} 24955714Skris 250109998Smarkm/* The caller can assume that this removes any secret data from the context */ 251109998Smarkmint EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 252280304Sjkim{ 253280304Sjkim int ret; 254280304Sjkim ret = EVP_DigestFinal_ex(ctx, md, size); 255280304Sjkim EVP_MD_CTX_cleanup(ctx); 256280304Sjkim return ret; 257280304Sjkim} 258109998Smarkm 259109998Smarkm/* The caller can assume that this removes any secret data from the context */ 260109998Smarkmint EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 261280304Sjkim{ 262306196Sjkim int ret; 263238405Sjkim#ifdef OPENSSL_FIPS 264306196Sjkim if (FIPS_mode()) 265306196Sjkim return FIPS_digestfinal(ctx, md, size); 266306196Sjkim#endif 267246772Sjkim 268280304Sjkim OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); 269280304Sjkim ret = ctx->digest->final(ctx, md); 270280304Sjkim if (size != NULL) 271280304Sjkim *size = ctx->digest->md_size; 272280304Sjkim if (ctx->digest->cleanup) { 273280304Sjkim ctx->digest->cleanup(ctx); 274280304Sjkim EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 275280304Sjkim } 276306196Sjkim OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); 277280304Sjkim return ret; 278280304Sjkim} 27955714Skris 280109998Smarkmint EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) 281280304Sjkim{ 282280304Sjkim EVP_MD_CTX_init(out); 283280304Sjkim return EVP_MD_CTX_copy_ex(out, in); 284280304Sjkim} 285109998Smarkm 286109998Smarkmint EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) 287280304Sjkim{ 288280304Sjkim unsigned char *tmp_buf; 289280304Sjkim if ((in == NULL) || (in->digest == NULL)) { 290280304Sjkim EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED); 291280304Sjkim return 0; 292280304Sjkim } 293111147Snectar#ifndef OPENSSL_NO_ENGINE 294280304Sjkim /* Make sure it's safe to copy a digest context using an ENGINE */ 295280304Sjkim if (in->engine && !ENGINE_init(in->engine)) { 296280304Sjkim EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB); 297280304Sjkim return 0; 298280304Sjkim } 299111147Snectar#endif 300109998Smarkm 301280304Sjkim if (out->digest == in->digest) { 302280304Sjkim tmp_buf = out->md_data; 303280304Sjkim EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); 304280304Sjkim } else 305280304Sjkim tmp_buf = NULL; 306280304Sjkim EVP_MD_CTX_cleanup(out); 307280304Sjkim memcpy(out, in, sizeof *out); 308109998Smarkm 309280304Sjkim if (in->md_data && out->digest->ctx_size) { 310280304Sjkim if (tmp_buf) 311280304Sjkim out->md_data = tmp_buf; 312280304Sjkim else { 313280304Sjkim out->md_data = OPENSSL_malloc(out->digest->ctx_size); 314280304Sjkim if (!out->md_data) { 315280304Sjkim EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE); 316280304Sjkim return 0; 317280304Sjkim } 318280304Sjkim } 319280304Sjkim memcpy(out->md_data, in->md_data, out->digest->ctx_size); 320280304Sjkim } 321127128Snectar 322280304Sjkim out->update = in->update; 323238405Sjkim 324280304Sjkim if (in->pctx) { 325280304Sjkim out->pctx = EVP_PKEY_CTX_dup(in->pctx); 326280304Sjkim if (!out->pctx) { 327280304Sjkim EVP_MD_CTX_cleanup(out); 328280304Sjkim return 0; 329280304Sjkim } 330280304Sjkim } 331238405Sjkim 332280304Sjkim if (out->digest->copy) 333280304Sjkim return out->digest->copy(out, in); 334109998Smarkm 335280304Sjkim return 1; 336280304Sjkim} 337280304Sjkim 338160814Ssimonint EVP_Digest(const void *data, size_t count, 339280304Sjkim unsigned char *md, unsigned int *size, const EVP_MD *type, 340280304Sjkim ENGINE *impl) 341280304Sjkim{ 342280304Sjkim EVP_MD_CTX ctx; 343280304Sjkim int ret; 344109998Smarkm 345280304Sjkim EVP_MD_CTX_init(&ctx); 346280304Sjkim EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); 347280304Sjkim ret = EVP_DigestInit_ex(&ctx, type, impl) 348280304Sjkim && EVP_DigestUpdate(&ctx, data, count) 349280304Sjkim && EVP_DigestFinal_ex(&ctx, md, size); 350280304Sjkim EVP_MD_CTX_cleanup(&ctx); 351109998Smarkm 352280304Sjkim return ret; 353280304Sjkim} 354109998Smarkm 355109998Smarkmvoid EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) 356280304Sjkim{ 357280304Sjkim if (ctx) { 358280304Sjkim EVP_MD_CTX_cleanup(ctx); 359280304Sjkim OPENSSL_free(ctx); 360280304Sjkim } 361280304Sjkim} 362109998Smarkm 363109998Smarkm/* This call frees resources associated with the context */ 364109998Smarkmint EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) 365280304Sjkim{ 366238405Sjkim#ifndef OPENSSL_FIPS 367280304Sjkim /* 368280304Sjkim * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because 369280304Sjkim * sometimes only copies of the context are ever finalised. 370280304Sjkim */ 371280304Sjkim if (ctx->digest && ctx->digest->cleanup 372280304Sjkim && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) 373280304Sjkim ctx->digest->cleanup(ctx); 374280304Sjkim if (ctx->digest && ctx->digest->ctx_size && ctx->md_data 375280304Sjkim && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { 376280304Sjkim OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); 377280304Sjkim OPENSSL_free(ctx->md_data); 378280304Sjkim } 379238405Sjkim#endif 380280304Sjkim if (ctx->pctx) 381280304Sjkim EVP_PKEY_CTX_free(ctx->pctx); 382111147Snectar#ifndef OPENSSL_NO_ENGINE 383280304Sjkim if (ctx->engine) 384280304Sjkim /* 385280304Sjkim * The EVP_MD we used belongs to an ENGINE, release the functional 386280304Sjkim * reference we held for this reason. 387280304Sjkim */ 388280304Sjkim ENGINE_finish(ctx->engine); 389111147Snectar#endif 390238405Sjkim#ifdef OPENSSL_FIPS 391280304Sjkim FIPS_md_ctx_cleanup(ctx); 392238405Sjkim#endif 393280304Sjkim memset(ctx, '\0', sizeof *ctx); 394109998Smarkm 395280304Sjkim return 1; 396280304Sjkim} 397