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