summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2022-01-09 15:15:25 +0000
committertb <>2022-01-09 15:15:25 +0000
commit12dd2352d38b1ef2237d623bc6b869d169e71567 (patch)
treeb42edbe525fc7c43874d4c14d0981bb1cb4e2d3d /src
parent98fb653e64884887dde11a1e705e45a6290548d1 (diff)
downloadopenbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.tar.gz
openbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.tar.bz2
openbsd-12dd2352d38b1ef2237d623bc6b869d169e71567.zip
Prepare to provide EVP_MD_CTX{,_set}_pkey_ctx()
This API with very strange ownership handling is used by Ruby 3.1, unfortunately. For unclear reasons, it was decided that the caller retains ownership of the pctx passed in. EVP_PKEY_CTX aren't refcounted, so a flag was added to make sure that md_ctx->pctx is not freed in EVP_MD_CTX_{cleanup,reset}(). Since EVP_MD_CTX_copy_ex() duplicates the md_ctx->pctx, the flag also needs to be unset on the duplicated EVP_MD_CTX. ok inoguchi jsing
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/evp/digest.c15
-rw-r--r--src/lib/libcrypto/evp/evp.h6
-rw-r--r--src/lib/libcrypto/evp/evp_lib.c31
-rw-r--r--src/lib/libcrypto/evp/evp_locl.h8
4 files changed, 55 insertions, 5 deletions
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c
index 59c98b57b8..fd42318044 100644
--- a/src/lib/libcrypto/evp/digest.c
+++ b/src/lib/libcrypto/evp/digest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest.c,v 1.32 2021/12/12 21:30:13 tb Exp $ */ 1/* $OpenBSD: digest.c,v 1.33 2022/01/09 15:15:25 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -282,6 +282,12 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
282 EVP_MD_CTX_cleanup(out); 282 EVP_MD_CTX_cleanup(out);
283 memcpy(out, in, sizeof *out); 283 memcpy(out, in, sizeof *out);
284 284
285 /*
286 * Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs
287 * to free out->pctx in all cases (even if this flag is set on in).
288 */
289 EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
290
285 if (in->md_data && out->digest->ctx_size) { 291 if (in->md_data && out->digest->ctx_size) {
286 if (tmp_buf) { 292 if (tmp_buf) {
287 out->md_data = tmp_buf; 293 out->md_data = tmp_buf;
@@ -383,7 +389,12 @@ EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
383 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && 389 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data &&
384 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) 390 !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
385 freezero(ctx->md_data, ctx->digest->ctx_size); 391 freezero(ctx->md_data, ctx->digest->ctx_size);
386 EVP_PKEY_CTX_free(ctx->pctx); 392 /*
393 * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was
394 * called and its strange API contract implies we don't own ctx->pctx.
395 */
396 if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
397 EVP_PKEY_CTX_free(ctx->pctx);
387#ifndef OPENSSL_NO_ENGINE 398#ifndef OPENSSL_NO_ENGINE
388 ENGINE_finish(ctx->engine); 399 ENGINE_finish(ctx->engine);
389#endif 400#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index b5afa477da..aa5b35f67c 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp.h,v 1.91 2022/01/07 21:58:17 tb Exp $ */ 1/* $OpenBSD: evp.h,v 1.92 2022/01/09 15:15:25 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -497,6 +497,10 @@ unsigned long EVP_MD_flags(const EVP_MD *md);
497 497
498const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); 498const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
499void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); 499void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);
500#if defined(LIBRESSL_CRYPTO_INTERANL) || defined(LIBRESSL_NEXT_API)
501EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);
502void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx);
503#endif
500#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) 504#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e))
501#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) 505#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e))
502#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) 506#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e))
diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c
index 8070fa45ae..c96813987f 100644
--- a/src/lib/libcrypto/evp/evp_lib.c
+++ b/src/lib/libcrypto/evp/evp_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_lib.c,v 1.22 2022/01/07 11:13:54 tb Exp $ */ 1/* $OpenBSD: evp_lib.c,v 1.23 2022/01/09 15:15:25 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -385,6 +385,35 @@ EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
385 return ctx->md_data; 385 return ctx->md_data;
386} 386}
387 387
388EVP_PKEY_CTX *
389EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
390{
391 return ctx->pctx;
392}
393
394void
395EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
396{
397 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
398 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
399 } else {
400 EVP_PKEY_CTX_free(ctx->pctx);
401 }
402
403 ctx->pctx = pctx;
404
405 if (pctx != NULL) {
406 /*
407 * For unclear reasons it was decided that the caller keeps
408 * ownership of pctx. So a flag was invented to make sure we
409 * don't free it in EVP_MD_CTX_cleanup(). We also need to
410 * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag
411 * isn't public...
412 */
413 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
414 }
415}
416
388void 417void
389EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) 418EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
390{ 419{
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h
index ec4cc6d63d..5eef0b244f 100644
--- a/src/lib/libcrypto/evp/evp_locl.h
+++ b/src/lib/libcrypto/evp/evp_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_locl.h,v 1.17 2021/12/12 21:21:58 tb Exp $ */ 1/* $OpenBSD: evp_locl.h,v 1.18 2022/01/09 15:15:25 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -61,6 +61,12 @@
61 61
62__BEGIN_HIDDEN_DECLS 62__BEGIN_HIDDEN_DECLS
63 63
64/*
65 * Don't free md_ctx->pctx in EVP_MD_CTX_cleanup(). Needed for ownership
66 * handling in EVP_MD_CTX_set_pkey_ctx().
67 */
68#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400
69
64/* Macros to code block cipher wrappers */ 70/* Macros to code block cipher wrappers */
65 71
66/* Wrapper functions for each cipher mode */ 72/* Wrapper functions for each cipher mode */