1 /* $OpenBSD: evp_digest.c,v 1.14 2024/04/10 15:00:38 beck Exp $ */ 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 <string.h> 114 115 #include <openssl/opensslconf.h> 116 117 #include <openssl/err.h> 118 #include <openssl/evp.h> 119 #include <openssl/objects.h> 120 121 #include "evp_local.h" 122 123 int 124 EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) 125 { 126 EVP_MD_CTX_legacy_clear(ctx); 127 return EVP_DigestInit_ex(ctx, type, NULL); 128 } 129 LCRYPTO_ALIAS(EVP_DigestInit); 130 131 int 132 EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) 133 { 134 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 135 136 if (ctx->digest != type) { 137 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && 138 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { 139 freezero(ctx->md_data, ctx->digest->ctx_size); 140 ctx->md_data = NULL; 141 } 142 ctx->digest = type; 143 if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { 144 ctx->update = type->update; 145 ctx->md_data = calloc(1, type->ctx_size); 146 if (ctx->md_data == NULL) { 147 EVP_PKEY_CTX_free(ctx->pctx); 148 ctx->pctx = NULL; 149 EVPerror(ERR_R_MALLOC_FAILURE); 150 return 0; 151 } 152 } 153 } 154 if (ctx->pctx) { 155 int r; 156 r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, 157 EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); 158 if (r <= 0 && (r != -2)) 159 return 0; 160 } 161 if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) 162 return 1; 163 return ctx->digest->init(ctx); 164 } 165 LCRYPTO_ALIAS(EVP_DigestInit_ex); 166 167 int 168 EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) 169 { 170 return ctx->update(ctx, data, count); 171 } 172 LCRYPTO_ALIAS(EVP_DigestUpdate); 173 174 /* The caller can assume that this removes any secret data from the context */ 175 int 176 EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 177 { 178 int ret; 179 180 ret = EVP_DigestFinal_ex(ctx, md, size); 181 EVP_MD_CTX_cleanup(ctx); 182 return ret; 183 } 184 LCRYPTO_ALIAS(EVP_DigestFinal); 185 186 /* The caller can assume that this removes any secret data from the context */ 187 int 188 EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 189 { 190 int ret; 191 192 if ((size_t)ctx->digest->md_size > EVP_MAX_MD_SIZE) { 193 EVPerror(EVP_R_TOO_LARGE); 194 return 0; 195 } 196 ret = ctx->digest->final(ctx, md); 197 if (size != NULL) 198 *size = ctx->digest->md_size; 199 if (ctx->digest->cleanup) { 200 ctx->digest->cleanup(ctx); 201 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 202 } 203 memset(ctx->md_data, 0, ctx->digest->ctx_size); 204 return ret; 205 } 206 LCRYPTO_ALIAS(EVP_DigestFinal_ex); 207 208 int 209 EVP_Digest(const void *data, size_t count, 210 unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl) 211 { 212 EVP_MD_CTX ctx; 213 int ret; 214 215 EVP_MD_CTX_legacy_clear(&ctx); 216 EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); 217 ret = EVP_DigestInit_ex(&ctx, type, NULL) && 218 EVP_DigestUpdate(&ctx, data, count) && 219 EVP_DigestFinal_ex(&ctx, md, size); 220 EVP_MD_CTX_cleanup(&ctx); 221 222 return ret; 223 } 224 LCRYPTO_ALIAS(EVP_Digest); 225 226 EVP_MD_CTX * 227 EVP_MD_CTX_new(void) 228 { 229 return calloc(1, sizeof(EVP_MD_CTX)); 230 } 231 LCRYPTO_ALIAS(EVP_MD_CTX_new); 232 233 void 234 EVP_MD_CTX_free(EVP_MD_CTX *ctx) 235 { 236 if (ctx == NULL) 237 return; 238 239 EVP_MD_CTX_cleanup(ctx); 240 241 free(ctx); 242 } 243 LCRYPTO_ALIAS(EVP_MD_CTX_free); 244 245 EVP_MD_CTX * 246 EVP_MD_CTX_create(void) 247 { 248 return EVP_MD_CTX_new(); 249 } 250 LCRYPTO_ALIAS(EVP_MD_CTX_create); 251 252 void 253 EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) 254 { 255 EVP_MD_CTX_free(ctx); 256 } 257 LCRYPTO_ALIAS(EVP_MD_CTX_destroy); 258 259 void 260 EVP_MD_CTX_legacy_clear(EVP_MD_CTX *ctx) 261 { 262 memset(ctx, 0, sizeof(*ctx)); 263 } 264 265 int 266 EVP_MD_CTX_init(EVP_MD_CTX *ctx) 267 { 268 return EVP_MD_CTX_cleanup(ctx); 269 } 270 LCRYPTO_ALIAS(EVP_MD_CTX_init); 271 272 int 273 EVP_MD_CTX_reset(EVP_MD_CTX *ctx) 274 { 275 return EVP_MD_CTX_cleanup(ctx); 276 } 277 LCRYPTO_ALIAS(EVP_MD_CTX_reset); 278 279 int 280 EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) 281 { 282 if (ctx == NULL) 283 return 1; 284 285 /* 286 * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, 287 * because sometimes only copies of the context are ever finalised. 288 */ 289 if (ctx->digest && ctx->digest->cleanup && 290 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) 291 ctx->digest->cleanup(ctx); 292 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && 293 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) 294 freezero(ctx->md_data, ctx->digest->ctx_size); 295 /* 296 * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was 297 * called and its strange API contract implies we don't own ctx->pctx. 298 */ 299 if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) 300 EVP_PKEY_CTX_free(ctx->pctx); 301 memset(ctx, 0, sizeof(*ctx)); 302 303 return 1; 304 } 305 LCRYPTO_ALIAS(EVP_MD_CTX_cleanup); 306 307 int 308 EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) 309 { 310 EVP_MD_CTX_legacy_clear(out); 311 return EVP_MD_CTX_copy_ex(out, in); 312 } 313 LCRYPTO_ALIAS(EVP_MD_CTX_copy); 314 315 int 316 EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) 317 { 318 unsigned char *tmp_buf; 319 320 if ((in == NULL) || (in->digest == NULL)) { 321 EVPerror(EVP_R_INPUT_NOT_INITIALIZED); 322 return 0; 323 } 324 325 if (out->digest == in->digest) { 326 tmp_buf = out->md_data; 327 EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); 328 } else 329 tmp_buf = NULL; 330 EVP_MD_CTX_cleanup(out); 331 memcpy(out, in, sizeof *out); 332 out->md_data = NULL; 333 out->pctx = NULL; 334 335 /* 336 * Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs 337 * to free out->pctx in all cases (even if this flag is set on in). 338 */ 339 EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 340 341 if (in->md_data && out->digest->ctx_size) { 342 if (tmp_buf) { 343 out->md_data = tmp_buf; 344 } else { 345 out->md_data = calloc(1, out->digest->ctx_size); 346 if (out->md_data == NULL) { 347 EVPerror(ERR_R_MALLOC_FAILURE); 348 return 0; 349 } 350 } 351 memcpy(out->md_data, in->md_data, out->digest->ctx_size); 352 } 353 354 out->update = in->update; 355 356 if (in->pctx) { 357 out->pctx = EVP_PKEY_CTX_dup(in->pctx); 358 if (!out->pctx) { 359 EVP_MD_CTX_cleanup(out); 360 return 0; 361 } 362 } 363 364 if (out->digest->copy) 365 return out->digest->copy(out, in); 366 367 return 1; 368 } 369 LCRYPTO_ALIAS(EVP_MD_CTX_copy_ex); 370 371 int 372 EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) 373 { 374 int ret; 375 376 if (!ctx->digest) { 377 EVPerror(EVP_R_NO_CIPHER_SET); 378 return 0; 379 } 380 381 if (!ctx->digest->md_ctrl) { 382 EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED); 383 return 0; 384 } 385 386 ret = ctx->digest->md_ctrl(ctx, type, arg, ptr); 387 if (ret == -1) { 388 EVPerror(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); 389 return 0; 390 } 391 return ret; 392 } 393 LCRYPTO_ALIAS(EVP_MD_CTX_ctrl); 394 395 const EVP_MD * 396 EVP_MD_CTX_md(const EVP_MD_CTX *ctx) 397 { 398 if (!ctx) 399 return NULL; 400 return ctx->digest; 401 } 402 LCRYPTO_ALIAS(EVP_MD_CTX_md); 403 404 void 405 EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) 406 { 407 ctx->flags &= ~flags; 408 } 409 LCRYPTO_ALIAS(EVP_MD_CTX_clear_flags); 410 411 void 412 EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) 413 { 414 ctx->flags |= flags; 415 } 416 LCRYPTO_ALIAS(EVP_MD_CTX_set_flags); 417 418 int 419 EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) 420 { 421 return (ctx->flags & flags); 422 } 423 LCRYPTO_ALIAS(EVP_MD_CTX_test_flags); 424 425 void * 426 EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) 427 { 428 return ctx->md_data; 429 } 430 LCRYPTO_ALIAS(EVP_MD_CTX_md_data); 431 432 EVP_PKEY_CTX * 433 EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) 434 { 435 return ctx->pctx; 436 } 437 LCRYPTO_ALIAS(EVP_MD_CTX_pkey_ctx); 438 439 void 440 EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) 441 { 442 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { 443 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 444 } else { 445 EVP_PKEY_CTX_free(ctx->pctx); 446 } 447 448 ctx->pctx = pctx; 449 450 if (pctx != NULL) { 451 /* 452 * For unclear reasons it was decided that the caller keeps 453 * ownership of pctx. So a flag was invented to make sure we 454 * don't free it in EVP_MD_CTX_cleanup(). We also need to 455 * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag 456 * isn't public... 457 */ 458 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 459 } 460 } 461 LCRYPTO_ALIAS(EVP_MD_CTX_set_pkey_ctx); 462 463 int 464 EVP_MD_type(const EVP_MD *md) 465 { 466 return md->type; 467 } 468 LCRYPTO_ALIAS(EVP_MD_type); 469 470 int 471 EVP_MD_pkey_type(const EVP_MD *md) 472 { 473 return md->pkey_type; 474 } 475 LCRYPTO_ALIAS(EVP_MD_pkey_type); 476 477 int 478 EVP_MD_size(const EVP_MD *md) 479 { 480 if (!md) { 481 EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); 482 return -1; 483 } 484 return md->md_size; 485 } 486 LCRYPTO_ALIAS(EVP_MD_size); 487 488 unsigned long 489 EVP_MD_flags(const EVP_MD *md) 490 { 491 return md->flags; 492 } 493 LCRYPTO_ALIAS(EVP_MD_flags); 494 495 int 496 EVP_MD_block_size(const EVP_MD *md) 497 { 498 return md->block_size; 499 } 500 LCRYPTO_ALIAS(EVP_MD_block_size); 501