1 /* $OpenBSD: evp_digest.c,v 1.10 2024/02/18 15:45:42 tb 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 130 int 131 EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) 132 { 133 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 134 135 if (ctx->digest != type) { 136 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && 137 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { 138 freezero(ctx->md_data, ctx->digest->ctx_size); 139 ctx->md_data = NULL; 140 } 141 ctx->digest = type; 142 if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { 143 ctx->update = type->update; 144 ctx->md_data = calloc(1, type->ctx_size); 145 if (ctx->md_data == NULL) { 146 EVP_PKEY_CTX_free(ctx->pctx); 147 ctx->pctx = NULL; 148 EVPerror(ERR_R_MALLOC_FAILURE); 149 return 0; 150 } 151 } 152 } 153 if (ctx->pctx) { 154 int r; 155 r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, 156 EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); 157 if (r <= 0 && (r != -2)) 158 return 0; 159 } 160 if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) 161 return 1; 162 return ctx->digest->init(ctx); 163 } 164 165 int 166 EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) 167 { 168 return ctx->update(ctx, data, count); 169 } 170 171 /* The caller can assume that this removes any secret data from the context */ 172 int 173 EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 174 { 175 int ret; 176 177 ret = EVP_DigestFinal_ex(ctx, md, size); 178 EVP_MD_CTX_cleanup(ctx); 179 return ret; 180 } 181 182 /* The caller can assume that this removes any secret data from the context */ 183 int 184 EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 185 { 186 int ret; 187 188 if ((size_t)ctx->digest->md_size > EVP_MAX_MD_SIZE) { 189 EVPerror(EVP_R_TOO_LARGE); 190 return 0; 191 } 192 ret = ctx->digest->final(ctx, md); 193 if (size != NULL) 194 *size = ctx->digest->md_size; 195 if (ctx->digest->cleanup) { 196 ctx->digest->cleanup(ctx); 197 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); 198 } 199 memset(ctx->md_data, 0, ctx->digest->ctx_size); 200 return ret; 201 } 202 203 int 204 EVP_Digest(const void *data, size_t count, 205 unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl) 206 { 207 EVP_MD_CTX ctx; 208 int ret; 209 210 EVP_MD_CTX_legacy_clear(&ctx); 211 EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); 212 ret = EVP_DigestInit_ex(&ctx, type, NULL) && 213 EVP_DigestUpdate(&ctx, data, count) && 214 EVP_DigestFinal_ex(&ctx, md, size); 215 EVP_MD_CTX_cleanup(&ctx); 216 217 return ret; 218 } 219 220 EVP_MD_CTX * 221 EVP_MD_CTX_new(void) 222 { 223 return calloc(1, sizeof(EVP_MD_CTX)); 224 } 225 226 void 227 EVP_MD_CTX_free(EVP_MD_CTX *ctx) 228 { 229 if (ctx == NULL) 230 return; 231 232 EVP_MD_CTX_cleanup(ctx); 233 234 free(ctx); 235 } 236 237 EVP_MD_CTX * 238 EVP_MD_CTX_create(void) 239 { 240 return EVP_MD_CTX_new(); 241 } 242 243 void 244 EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) 245 { 246 EVP_MD_CTX_free(ctx); 247 } 248 249 void 250 EVP_MD_CTX_init(EVP_MD_CTX *ctx) 251 { 252 memset(ctx, 0, sizeof(*ctx)); 253 } 254 255 void 256 EVP_MD_CTX_legacy_clear(EVP_MD_CTX *ctx) 257 { 258 memset(ctx, 0, sizeof(*ctx)); 259 } 260 261 int 262 EVP_MD_CTX_reset(EVP_MD_CTX *ctx) 263 { 264 return EVP_MD_CTX_cleanup(ctx); 265 } 266 267 int 268 EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) 269 { 270 if (ctx == NULL) 271 return 1; 272 273 /* 274 * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, 275 * because sometimes only copies of the context are ever finalised. 276 */ 277 if (ctx->digest && ctx->digest->cleanup && 278 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) 279 ctx->digest->cleanup(ctx); 280 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && 281 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) 282 freezero(ctx->md_data, ctx->digest->ctx_size); 283 /* 284 * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was 285 * called and its strange API contract implies we don't own ctx->pctx. 286 */ 287 if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) 288 EVP_PKEY_CTX_free(ctx->pctx); 289 memset(ctx, 0, sizeof(*ctx)); 290 291 return 1; 292 } 293 294 int 295 EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) 296 { 297 EVP_MD_CTX_legacy_clear(out); 298 return EVP_MD_CTX_copy_ex(out, in); 299 } 300 301 int 302 EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) 303 { 304 unsigned char *tmp_buf; 305 306 if ((in == NULL) || (in->digest == NULL)) { 307 EVPerror(EVP_R_INPUT_NOT_INITIALIZED); 308 return 0; 309 } 310 311 if (out->digest == in->digest) { 312 tmp_buf = out->md_data; 313 EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); 314 } else 315 tmp_buf = NULL; 316 EVP_MD_CTX_cleanup(out); 317 memcpy(out, in, sizeof *out); 318 out->md_data = NULL; 319 out->pctx = NULL; 320 321 /* 322 * Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs 323 * to free out->pctx in all cases (even if this flag is set on in). 324 */ 325 EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 326 327 if (in->md_data && out->digest->ctx_size) { 328 if (tmp_buf) { 329 out->md_data = tmp_buf; 330 } else { 331 out->md_data = calloc(1, out->digest->ctx_size); 332 if (out->md_data == NULL) { 333 EVPerror(ERR_R_MALLOC_FAILURE); 334 return 0; 335 } 336 } 337 memcpy(out->md_data, in->md_data, out->digest->ctx_size); 338 } 339 340 out->update = in->update; 341 342 if (in->pctx) { 343 out->pctx = EVP_PKEY_CTX_dup(in->pctx); 344 if (!out->pctx) { 345 EVP_MD_CTX_cleanup(out); 346 return 0; 347 } 348 } 349 350 if (out->digest->copy) 351 return out->digest->copy(out, in); 352 353 return 1; 354 } 355 356 int 357 EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) 358 { 359 int ret; 360 361 if (!ctx->digest) { 362 EVPerror(EVP_R_NO_CIPHER_SET); 363 return 0; 364 } 365 366 if (!ctx->digest->md_ctrl) { 367 EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED); 368 return 0; 369 } 370 371 ret = ctx->digest->md_ctrl(ctx, type, arg, ptr); 372 if (ret == -1) { 373 EVPerror(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); 374 return 0; 375 } 376 return ret; 377 } 378 379 const EVP_MD * 380 EVP_MD_CTX_md(const EVP_MD_CTX *ctx) 381 { 382 if (!ctx) 383 return NULL; 384 return ctx->digest; 385 } 386 387 void 388 EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) 389 { 390 ctx->flags &= ~flags; 391 } 392 393 void 394 EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) 395 { 396 ctx->flags |= flags; 397 } 398 399 int 400 EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) 401 { 402 return (ctx->flags & flags); 403 } 404 405 void * 406 EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) 407 { 408 return ctx->md_data; 409 } 410 411 EVP_PKEY_CTX * 412 EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) 413 { 414 return ctx->pctx; 415 } 416 417 void 418 EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) 419 { 420 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { 421 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 422 } else { 423 EVP_PKEY_CTX_free(ctx->pctx); 424 } 425 426 ctx->pctx = pctx; 427 428 if (pctx != NULL) { 429 /* 430 * For unclear reasons it was decided that the caller keeps 431 * ownership of pctx. So a flag was invented to make sure we 432 * don't free it in EVP_MD_CTX_cleanup(). We also need to 433 * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag 434 * isn't public... 435 */ 436 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); 437 } 438 } 439 440 int 441 EVP_MD_type(const EVP_MD *md) 442 { 443 return md->type; 444 } 445 446 int 447 EVP_MD_pkey_type(const EVP_MD *md) 448 { 449 return md->pkey_type; 450 } 451 452 int 453 EVP_MD_size(const EVP_MD *md) 454 { 455 if (!md) { 456 EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); 457 return -1; 458 } 459 return md->md_size; 460 } 461 462 unsigned long 463 EVP_MD_flags(const EVP_MD *md) 464 { 465 return md->flags; 466 } 467 468 int 469 EVP_MD_block_size(const EVP_MD *md) 470 { 471 return md->block_size; 472 } 473 474 /* 475 * XXX - remove everything below in the next bump. 476 */ 477 478 EVP_MD * 479 EVP_MD_meth_new(int md_type, int pkey_type) 480 { 481 EVP_MD *md; 482 483 if ((md = calloc(1, sizeof(*md))) == NULL) 484 return NULL; 485 486 md->type = md_type; 487 md->pkey_type = pkey_type; 488 489 return md; 490 } 491 492 EVP_MD * 493 EVP_MD_meth_dup(const EVP_MD *md) 494 { 495 EVP_MD *to; 496 497 if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL) 498 return NULL; 499 500 memcpy(to, md, sizeof(*to)); 501 502 return to; 503 } 504 505 void 506 EVP_MD_meth_free(EVP_MD *md) 507 { 508 freezero(md, sizeof(*md)); 509 } 510 511 int 512 EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) 513 { 514 md->block_size = blocksize; 515 return 1; 516 } 517 518 int 519 EVP_MD_meth_set_result_size(EVP_MD *md, int result_size) 520 { 521 md->md_size = result_size; 522 return 1; 523 } 524 525 int 526 EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) 527 { 528 md->ctx_size = datasize; 529 return 1; 530 } 531 532 int 533 EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) 534 { 535 md->flags = flags; 536 return 1; 537 } 538 539 int 540 EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) 541 { 542 md->init = init; 543 return 1; 544 } 545 546 int 547 EVP_MD_meth_set_update(EVP_MD *md, 548 int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) 549 { 550 md->update = update; 551 return 1; 552 } 553 554 int 555 EVP_MD_meth_set_final(EVP_MD *md, 556 int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) 557 { 558 md->final = final; 559 return 1; 560 } 561 562 int 563 EVP_MD_meth_set_copy(EVP_MD *md, 564 int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) 565 { 566 md->copy = copy; 567 return 1; 568 } 569 570 int 571 EVP_MD_meth_set_cleanup(EVP_MD *md, 572 int (*cleanup)(EVP_MD_CTX *ctx)) 573 { 574 md->cleanup = cleanup; 575 return 1; 576 } 577 578 int 579 EVP_MD_meth_set_ctrl(EVP_MD *md, 580 int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) 581 { 582 md->md_ctrl = ctrl; 583 return 1; 584 } 585