Skip to content

Commit

Permalink
Add back support for EVP_PKEY_HMAC (aws#1324)
Browse files Browse the repository at this point in the history
Some legacy libraries still depend on `EVP_PKEY_HMAC` unfortunately,
so we're adding back support. OpenSSL 3.0 hasn't deprecated support for
this either, so we still need to support this for the SHIM layer long
term. Much of logic was reapplied from the [original commit removal]
(https://github.com/google/boringssl/commit/
65ee9b7), but I've cleaned up some
unneeded branching logic to makes things more straight forward.

We've also made modifications to remove the need for additional
`EVP_PKEY` function pointers and `ctrl` logic. Since HMAC needs to be
specially handled in many of the `EVP_DigestSign*` APIs, the additional
function pointers make much less sense. We can just directly make calls
to `HMAC_CTX` without the `EVP_PKEY_METHOD` redirections.
  • Loading branch information
samuel40791765 authored Dec 26, 2023
1 parent b201aea commit 7226be1
Show file tree
Hide file tree
Showing 16 changed files with 548 additions and 62 deletions.
4 changes: 2 additions & 2 deletions PORTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ document for a table of functions to use.

### HMAC `EVP_PKEY`s

`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
is compatible with OpenSSL.
`EVP_PKEY_HMAC` is deprecated and preserved with minimal functionality. Use the
`HMAC_*` functions in hmac.h instead.

### DSA `EVP_PKEY`s

Expand Down
1 change: 1 addition & 0 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ add_library(
evp_extra/p_ec_asn1.c
evp_extra/p_ed25519.c
evp_extra/p_ed25519_asn1.c
evp_extra/p_hmac_asn1.c
evp_extra/p_kem.c
evp_extra/p_kem_asn1.c
evp_extra/p_rsa_asn1.c
Expand Down
2 changes: 2 additions & 0 deletions crypto/evp_extra/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD dilithium3_asn1_meth;
#endif
extern const EVP_PKEY_ASN1_METHOD kem_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;

extern const EVP_PKEY_METHOD ed25519_pkey_meth;
extern const EVP_PKEY_METHOD x25519_pkey_meth;
extern const EVP_PKEY_METHOD hkdf_pkey_meth;
extern const EVP_PKEY_METHOD dilithium3_pkey_meth;
extern const EVP_PKEY_METHOD kem_pkey_meth;
extern const EVP_PKEY_METHOD hmac_pkey_meth;

// Returns a reference to the list |non_fips_pkey_evp_methods|. The list has
// size |NON_FIPS_EVP_PKEY_METHODS|.
Expand Down
93 changes: 93 additions & 0 deletions crypto/evp_extra/p_hmac_asn1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
* project 2007.
*/
/* ====================================================================
* Copyright (c) 2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [email protected].
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* ([email protected]). This product includes software written by Tim
* Hudson ([email protected]). */

#include <openssl/digest.h>
#include <openssl/evp.h>
#include <openssl/mem.h>

#include "internal.h"


static int hmac_size(OPENSSL_UNUSED const EVP_PKEY *pkey) {
return EVP_MAX_MD_SIZE;
}

static void hmac_key_free(EVP_PKEY *pkey) {
HMAC_KEY *key = pkey->pkey.ptr;
OPENSSL_free(key);
}

const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
EVP_PKEY_HMAC,
{0xff} /* placeholder oid */,
0 /* oid_len */,
NULL /* pub_decode */,
NULL /* pub_encode */,
NULL /* pub_cmp */,
NULL /*priv_decode */,
NULL /* priv_encode */,
NULL /* priv_encode_v2 */,
NULL /* set_priv_raw */,
NULL /* set_pub_raw */,
NULL /* get_priv_raw */,
NULL /* get_pub_raw */,
NULL /* pkey_opaque */,
hmac_size /* pkey_size */,
NULL /* pkey_bits */,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
hmac_key_free /* pkey_free */
};
1 change: 1 addition & 0 deletions crypto/evp_extra/p_methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static const EVP_PKEY_ASN1_METHOD *const asn1_evp_pkey_methods[] = {
&dilithium3_asn1_meth,
#endif
&kem_asn1_meth,
&hmac_asn1_meth
};

OPENSSL_STATIC_ASSERT(
Expand Down
1 change: 1 addition & 0 deletions crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
#include "evp/evp_ctx.c"
#include "evp/p_ec.c"
#include "evp/p_hkdf.c"
#include "evp/p_hmac.c"
#include "evp/p_rsa.c"
#include "hkdf/hkdf.c"
#include "hmac/hmac.c"
Expand Down
61 changes: 40 additions & 21 deletions crypto/fipsmodule/digest/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,17 @@
* [including the GNU Public Licence.] */

#include <assert.h>
#include <string.h>

#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/nid.h>

#include "internal.h"
#include "../../internal.h"
#include "../evp/internal.h"
#include "internal.h"


void EVP_MD_unstable_sha3_enable(bool enable) { /* no-op */ }
void EVP_MD_unstable_sha3_enable(bool enable) { // no-op
}

bool EVP_MD_unstable_sha3_is_enabled(void) { return true; }

Expand Down Expand Up @@ -188,9 +186,14 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {

out->digest = in->digest;
out->md_data = tmp_buf;
if (in->digest != NULL) {
if (in->digest != NULL && in->md_data != NULL) {
OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size);
}
out->update = in->update;
out->flags = in->flags;
// copied |EVP_MD_CTX| should free its newly allocated |EVP_PKEY_CTX|.
out->flags &= ~EVP_MD_CTX_FLAG_KEEP_PKEY_CTX;

out->pctx = pctx;
out->pctx_ops = in->pctx_ops;
assert(out->pctx == NULL || out->pctx_ops != NULL);
Expand Down Expand Up @@ -218,19 +221,38 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) {

int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) {
if (ctx->digest != type) {
assert(type->ctx_size != 0);
uint8_t *md_data = OPENSSL_malloc(type->ctx_size);
if (md_data == NULL) {
return 0;
}

OPENSSL_free(ctx->md_data);
ctx->md_data = md_data;
ctx->digest = type;
if (!used_for_hmac(ctx)) {
assert(type->ctx_size != 0);
ctx->update = type->update;
uint8_t *md_data = OPENSSL_malloc(type->ctx_size);
if (md_data == NULL) {
return 0;
}
OPENSSL_free(ctx->md_data);
ctx->md_data = md_data;
}
}

assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);

if (used_for_hmac(ctx)) {
// These configurations are specific to |EVP_PKEY_HMAC|. |HMAC_PKEY_CTX| is
// newly allocated by |EVP_DigestSignInit| at this point. The actual key
// data is stored in |ctx->pkey| as |HMAC_KEY|.
if (ctx->pctx == NULL || ctx->pctx->data == NULL ||
ctx->pctx->pkey == NULL || ctx->pctx->pkey->pkey.ptr == NULL) {
return 0;
}
const HMAC_KEY *key = ctx->pctx->pkey->pkey.ptr;
HMAC_PKEY_CTX *hmac_pctx = ctx->pctx->data;
if (!HMAC_Init_ex(&hmac_pctx->ctx, key->key, key->key_len, hmac_pctx->md,
ctx->pctx->engine)) {
return 0;
}
return 1;
}

ctx->digest->init(ctx);
return 1;
}
Expand All @@ -241,11 +263,10 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
}

int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
if (ctx->digest == NULL) {
if (ctx->update == NULL) {
return 0;
}

ctx->digest->update(ctx, data, len);
ctx->update(ctx, data, len);
return 1;
}

Expand Down Expand Up @@ -287,7 +308,7 @@ int EVP_Digest(const void *data, size_t count, uint8_t *out_md,
ret = EVP_DigestInit_ex(&ctx, type, impl) &&
EVP_DigestUpdate(&ctx, data, count);
if (ret == 0) {
return 0;
return 0;
}

if (EVP_MD_flags(type) & EVP_MD_FLAG_XOF) {
Expand Down Expand Up @@ -319,6 +340,4 @@ int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) {
return EVP_MD_type(EVP_MD_CTX_md(ctx));
}

int EVP_add_digest(const EVP_MD *digest) {
return 1;
}
int EVP_add_digest(const EVP_MD *digest) { return 1; }
Loading

0 comments on commit 7226be1

Please sign in to comment.