The branch master has been updated via 388de53c274dee20c07eee7ff892108668fb3a61 (commit) via f8c9a8e325b23f4b3de67e9a0d385355f81bd6fc (commit) via 6723f86746ab7e8ff9a914603db4f85c53eafc7c (commit) from 56adb7d93721a72bfae532845cbebc4a565ceb65 (commit)
- Log ----------------------------------------------------------------- commit 388de53c274dee20c07eee7ff892108668fb3a61 Author: Richard Levitte <levi...@openssl.org> Date: Wed Oct 24 22:49:49 2018 +0200 Make sure at least one HMAC test still uses the EVP_PKEY method Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/7483) commit f8c9a8e325b23f4b3de67e9a0d385355f81bd6fc Author: Richard Levitte <levi...@openssl.org> Date: Wed Oct 24 21:25:00 2018 +0200 EVP_MAC: Integrate HMAC EVP_PKEY_METHOD into generic MAC EVP_PKEY_METHOD Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/7483) commit 6723f86746ab7e8ff9a914603db4f85c53eafc7c Author: Richard Levitte <levi...@openssl.org> Date: Wed Oct 24 21:20:00 2018 +0200 EVP_MAC: Add HMAC implementation Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/7483) ----------------------------------------------------------------------- Summary of changes: crypto/evp/c_allm.c | 1 + crypto/evp/pkey_mac.c | 33 ++++ crypto/hmac/build.info | 2 +- crypto/hmac/hm_meth.c | 173 +++++++++++++++++++ crypto/hmac/hm_pmeth.c | 212 ------------------------ crypto/include/internal/evp_int.h | 1 + doc/man3/EVP_MAC.pod | 3 +- doc/man7/{EVP_MAC_CMAC.pod => EVP_MAC_HMAC.pod} | 16 +- include/openssl/evp.h | 1 + test/recipes/30-test_evp_data/evpmac.txt | 2 +- 10 files changed, 224 insertions(+), 220 deletions(-) create mode 100644 crypto/hmac/hm_meth.c delete mode 100644 crypto/hmac/hm_pmeth.c copy doc/man7/{EVP_MAC_CMAC.pod => EVP_MAC_HMAC.pod} (70%) diff --git a/crypto/evp/c_allm.c b/crypto/evp/c_allm.c index 862b639..edf8ba5 100644 --- a/crypto/evp/c_allm.c +++ b/crypto/evp/c_allm.c @@ -15,4 +15,5 @@ void openssl_add_all_macs_int(void) #ifndef OPENSSL_NO_CMAC EVP_add_mac(&cmac_meth); #endif + EVP_add_mac(&hmac_meth); } diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c index ecf70bb..9f3817c 100644 --- a/crypto/evp/pkey_mac.c +++ b/crypto/evp/pkey_mac.c @@ -359,3 +359,36 @@ const EVP_PKEY_METHOD cmac_pkey_meth = { pkey_mac_ctrl, pkey_mac_ctrl_str }; + +const EVP_PKEY_METHOD hmac_pkey_meth = { + EVP_PKEY_HMAC, + 0, + pkey_mac_init, + pkey_mac_copy, + pkey_mac_cleanup, + + 0, 0, + + 0, + pkey_mac_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_mac_signctx_init, + pkey_mac_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_mac_ctrl, + pkey_mac_ctrl_str +}; diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info index 09f67c2..f63524d 100644 --- a/crypto/hmac/build.info +++ b/crypto/hmac/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - hmac.c hm_ameth.c hm_pmeth.c + hmac.c hm_ameth.c hm_meth.c diff --git a/crypto/hmac/hm_meth.c b/crypto/hmac/hm_meth.c new file mode 100644 index 0000000..fb48830 --- /dev/null +++ b/crypto/hmac/hm_meth.c @@ -0,0 +1,173 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/ossl_typ.h> +#include <openssl/asn1.h> +#include <openssl/hmac.h> +#include "internal/evp_int.h" + +/* local HMAC context structure */ + +/* typedef EVP_MAC_IMPL */ +struct evp_mac_impl_st { + /* tmpmd and tmpengine are set to NULL after a CMAC_Init call */ + const EVP_MD *tmpmd; /* HMAC digest */ + const ENGINE *tmpengine; /* HMAC digest engine */ + HMAC_CTX *ctx; /* HMAC context */ +}; + +static EVP_MAC_IMPL *hmac_new(void) +{ + EVP_MAC_IMPL *hctx; + + if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL + || (hctx->ctx = HMAC_CTX_new()) == NULL) { + OPENSSL_free(hctx); + return NULL; + } + + return hctx; +} + +static void hmac_free(EVP_MAC_IMPL *hctx) +{ + if (hctx != NULL) { + HMAC_CTX_free(hctx->ctx); + OPENSSL_free(hctx); + } +} + +static int hmac_copy(EVP_MAC_IMPL *hdst, EVP_MAC_IMPL *hsrc) +{ + if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx)) + return 0; + + hdst->tmpengine = hsrc->tmpengine; + hdst->tmpmd = hsrc->tmpmd; + return 1; +} + +static size_t hmac_size(EVP_MAC_IMPL *hctx) +{ + return HMAC_size(hctx->ctx); +} + +static int hmac_init(EVP_MAC_IMPL *hctx) +{ + int rv = 1; + + /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */ + if (hctx->tmpmd != NULL) + rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd, + (ENGINE * )hctx->tmpengine); + hctx->tmpengine = NULL; + hctx->tmpmd = NULL; + return rv; +} + +static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data, + size_t datalen) +{ + return HMAC_Update(hctx->ctx, data, datalen); +} + +static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out) +{ + unsigned int hlen; + + return HMAC_Final(hctx->ctx, out, &hlen); +} + +static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args) +{ + switch (cmd) { + case EVP_MAC_CTRL_SET_FLAGS: + { + unsigned long flags = va_arg(args, unsigned long); + + HMAC_CTX_set_flags(hctx->ctx, flags); + } + break; + case EVP_MAC_CTRL_SET_KEY: + { + const unsigned char *key = va_arg(args, const unsigned char *); + size_t keylen = va_arg(args, size_t); + int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd, + (ENGINE *)hctx->tmpengine); + + hctx->tmpengine = NULL; + hctx->tmpmd = NULL; + return rv; + } + break; + case EVP_MAC_CTRL_SET_MD: + hctx->tmpmd = va_arg(args, const EVP_MD *); + break; + case EVP_MAC_CTRL_SET_ENGINE: + hctx->tmpengine = va_arg(args, const ENGINE *); + break; + default: + return -2; + + } + return 1; +} + +static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...) +{ + int rv; + va_list args; + + va_start(args, cmd); + rv = hmac_ctrl(hctx, cmd, args); + va_end(args); + + return rv; +} + +static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen) +{ + return hmac_ctrl_int(hctx, cmd, buf, buflen); +} + +static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type, + const char *value) +{ + if (!value) + return 0; + if (strcmp(type, "digest") == 0) { + const EVP_MD *d = EVP_get_digestbyname(value); + + if (d == NULL) + return 0; + return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d); + } + if (strcmp(type, "key") == 0) + return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY, + value); + if (strcmp(type, "hexkey") == 0) + return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY, + value); + return -2; +} + +const EVP_MAC hmac_meth = { + EVP_MAC_HMAC, + hmac_new, + hmac_copy, + hmac_free, + hmac_size, + hmac_init, + hmac_update, + hmac_final, + hmac_ctrl, + hmac_ctrl_str +}; diff --git a/crypto/hmac/hm_pmeth.c b/crypto/hmac/hm_pmeth.c deleted file mode 100644 index 55dd27d..0000000 --- a/crypto/hmac/hm_pmeth.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdio.h> -#include "internal/cryptlib.h" -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include <openssl/err.h> -#include "internal/evp_int.h" - -/* HMAC pkey context structure */ - -typedef struct { - const EVP_MD *md; /* MD for HMAC use */ - ASN1_OCTET_STRING ktmp; /* Temp storage for key */ - HMAC_CTX *ctx; -} HMAC_PKEY_CTX; - -static int pkey_hmac_init(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx; - - if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { - CRYPTOerr(CRYPTO_F_PKEY_HMAC_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - hctx->ktmp.type = V_ASN1_OCTET_STRING; - hctx->ctx = HMAC_CTX_new(); - if (hctx->ctx == NULL) { - OPENSSL_free(hctx); - return 0; - } - - ctx->data = hctx; - ctx->keygen_info_count = 0; - - return 1; -} - -static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx); - -static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - HMAC_PKEY_CTX *sctx, *dctx; - - /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */ - if (!pkey_hmac_init(dst)) - return 0; - sctx = EVP_PKEY_CTX_get_data(src); - dctx = EVP_PKEY_CTX_get_data(dst); - dctx->md = sctx->md; - if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx)) - goto err; - if (sctx->ktmp.data) { - if (!ASN1_OCTET_STRING_set(&dctx->ktmp, - sctx->ktmp.data, sctx->ktmp.length)) - goto err; - } - return 1; -err: - /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */ - pkey_hmac_cleanup (dst); - return 0; -} - -static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - - if (hctx != NULL) { - HMAC_CTX_free(hctx->ctx); - OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length); - OPENSSL_free(hctx); - EVP_PKEY_CTX_set_data(ctx, NULL); - } -} - -static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *hkey = NULL; - HMAC_PKEY_CTX *hctx = ctx->data; - if (!hctx->ktmp.data) - return 0; - hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); - if (!hkey) - return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data; - if (!HMAC_Update(hctx->ctx, data, count)) - return 0; - return 1; -} - -static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - HMAC_CTX_set_flags(hctx->ctx, - EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - return 1; -} - -static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - unsigned int hlen; - HMAC_PKEY_CTX *hctx = ctx->data; - int l = EVP_MD_CTX_size(mctx); - - if (l < 0) - return 0; - *siglen = l; - if (!sig) - return 1; - - if (!HMAC_Final(hctx->ctx, sig, &hlen)) - return 0; - *siglen = (size_t)hlen; - return 1; -} - -static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - ASN1_OCTET_STRING *key; - switch (type) { - - case EVP_PKEY_CTRL_SET_MAC_KEY: - if ((!p2 && p1 > 0) || (p1 < -1)) - return 0; - if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) - return 0; - break; - - case EVP_PKEY_CTRL_MD: - hctx->md = p2; - break; - - case EVP_PKEY_CTRL_DIGESTINIT: - key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, - ctx->engine)) - return 0; - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - return 0; - } - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - return -2; -} - -const EVP_PKEY_METHOD hmac_pkey_meth = { - EVP_PKEY_HMAC, - 0, - pkey_hmac_init, - pkey_hmac_copy, - pkey_hmac_cleanup, - - 0, 0, - - 0, - pkey_hmac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - hmac_signctx_init, - hmac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_hmac_ctrl, - pkey_hmac_ctrl_str -}; diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index 8bbc23b..e84205c 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -129,6 +129,7 @@ struct evp_mac_st { }; extern const EVP_MAC cmac_meth; +extern const EVP_MAC hmac_meth; /* * This function is internal for now, but can be made external when needed. diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index 2b48940..02a4866 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -326,7 +326,8 @@ F<./foo>) =head1 SEE ALSO -L<EVP_MAC_CMAC(7)> +L<EVP_MAC_CMAC(7)>, +L<EVP_MAC_HMAC(7)> =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC_CMAC.pod b/doc/man7/EVP_MAC_HMAC.pod similarity index 70% copy from doc/man7/EVP_MAC_CMAC.pod copy to doc/man7/EVP_MAC_HMAC.pod index bb37472..8276ff3 100644 --- a/doc/man7/EVP_MAC_CMAC.pod +++ b/doc/man7/EVP_MAC_HMAC.pod @@ -2,15 +2,15 @@ =head1 NAME -EVP_MAC_CMAC - The CMAC EVP_MAC implementation +EVP_MAC_HMAC - The HMAC EVP_MAC implementation =head1 DESCRIPTION -Support for computing CMAC MACs through the B<EVP_MAC> API. +Support for computing HMAC MACs through the B<EVP_MAC> API. =head2 Numeric identity -B<EVP_MAC_CMAC> is the numeric identity for this implementation, and +B<EVP_MAC_HMAC> is the numeric identity for this implementation, and can be used in functions like EVP_MAC_CTX_new_id() and EVP_get_macbynid(). @@ -37,13 +37,19 @@ decoded before passing on as control value. =back +=item B<EVP_MAC_CTRL_SET_FLAGS> + +Sets HMAC flags. This is passed directly to HMAC_CTX_set_flags(). + +There are no corresponding string control types. + =item B<EVP_MAC_CTRL_SET_ENGINE> -=item B<EVP_MAC_CTRL_SET_CIPHER> +=item B<EVP_MAC_CTRL_SET_MD> These work as described in L<EVP_MAC(3)/CONTROLS>. -EVP_MAC_ctrl_str() type string for B<EVP_MAC_CTRL_SET_CIPHER>: "cipher" +EVP_MAC_ctrl_str() type string for B<EVP_MAC_CTRL_SET_DIGEST>: "digest" The value is expected to be the name of a cipher. diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 5e6c039..657bedb 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -988,6 +988,7 @@ void EVP_MD_do_all_sorted(void (*fn) /* MAC stuff */ # define EVP_MAC_CMAC NID_cmac +# define EVP_MAC_HMAC NID_hmac EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac); EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid); diff --git a/test/recipes/30-test_evp_data/evpmac.txt b/test/recipes/30-test_evp_data/evpmac.txt index 2506e7d..1d0d5da 100644 --- a/test/recipes/30-test_evp_data/evpmac.txt +++ b/test/recipes/30-test_evp_data/evpmac.txt @@ -345,7 +345,7 @@ Input = "Sample message for keylen=blocklen" Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647 Output = 544e257ea2a3e5ea19a590e6a24b724ce6327757723fe2751b75bf007d80f6b360744bf1b7a88ea585f9765b47911976d3191cf83c039f5ffab0d29cc9d9b6da -MAC = HMAC +MAC = HMAC by EVP_PKEY Algorithm = SHA3-512 Input = "Sample message for keylen>blocklen" Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687 _____ openssl-commits mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits