mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			419 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			419 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| =pod
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free,
 | |
| EVP_MAC_is_a, EVP_MAC_number, EVP_MAC_name, EVP_MAC_names_do_all,
 | |
| EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params,
 | |
| EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup,
 | |
| EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
 | |
| EVP_MAC_CTX_get_mac_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final,
 | |
| EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params,
 | |
| EVP_MAC_do_all_provided - EVP MAC routines
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  #include <openssl/evp.h>
 | |
| 
 | |
|  typedef struct evp_mac_st EVP_MAC;
 | |
|  typedef struct evp_mac_ctx_st EVP_MAC_CTX;
 | |
| 
 | |
|  EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
 | |
|                         const char *properties);
 | |
|  int EVP_MAC_up_ref(EVP_MAC *mac);
 | |
|  void EVP_MAC_free(EVP_MAC *mac);
 | |
|  int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
 | |
|  int EVP_MAC_number(const EVP_MAC *mac);
 | |
|  const char *EVP_MAC_name(const EVP_MAC *mac);
 | |
|  void EVP_MAC_names_do_all(const EVP_MAC *mac,
 | |
|                            void (*fn)(const char *name, void *data),
 | |
|                            void *data);
 | |
|  const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
 | |
|  int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
 | |
| 
 | |
|  EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac);
 | |
|  void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
 | |
|  EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src);
 | |
|  EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
 | |
|  int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]);
 | |
|  int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);
 | |
| 
 | |
|  size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx);
 | |
|  int EVP_MAC_init(EVP_MAC_CTX *ctx);
 | |
|  int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
 | |
|  int EVP_MAC_final(EVP_MAC_CTX *ctx,
 | |
|                    unsigned char *out, size_t *outl, size_t outsize);
 | |
| 
 | |
|  const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac);
 | |
|  const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac);
 | |
|  const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac);
 | |
| 
 | |
|  void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx,
 | |
|                               void (*fn)(EVP_MAC *mac, void *arg),
 | |
|                               void *arg);
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| These types and functions help the application to calculate MACs of
 | |
| different types and with different underlying algorithms if there are
 | |
| any.
 | |
| 
 | |
| MACs are a bit complex insofar that some of them use other algorithms
 | |
| for actual computation.  HMAC uses a digest, and CMAC uses a cipher.
 | |
| Therefore, there are sometimes two contexts to keep track of, one for
 | |
| the MAC algorithm itself and one for the underlying computation
 | |
| algorithm if there is one.
 | |
| 
 | |
| To make things less ambiguous, this manual talks about a "context" or
 | |
| "MAC context", which is to denote the MAC level context, and about a
 | |
| "underlying context", or "computation context", which is to denote the
 | |
| context for the underlying computation algorithm if there is one.
 | |
| 
 | |
| =head2 Types
 | |
| 
 | |
| B<EVP_MAC> is a type that holds the implementation of a MAC.
 | |
| 
 | |
| B<EVP_MAC_CTX> is a context type that holds internal MAC information
 | |
| as well as a reference to a computation context, for those MACs that
 | |
| rely on an underlying computation algorithm.
 | |
| 
 | |
| =head2 Algorithm implementation fetching
 | |
| 
 | |
| EVP_MAC_fetch() fetches an implementation of a MAC I<algorithm>, given
 | |
| a library context I<libctx> and a set of I<properties>.
 | |
| See L<provider(7)/Fetching algorithms> for further information.
 | |
| 
 | |
| See L<OSSL_PROVIDER-default(7)/Message Authentication Code (MAC)> for the list
 | |
| of algorithms supported by the default provider.
 | |
| 
 | |
| The returned value must eventually be freed with
 | |
| L<EVP_MAC_free(3)>.
 | |
| 
 | |
| EVP_MAC_up_ref() increments the reference count of an already fetched
 | |
| MAC.
 | |
| 
 | |
| EVP_MAC_free() frees a fetched algorithm.
 | |
| NULL is a valid parameter, for which this function is a no-op.
 | |
| 
 | |
| =head2 Context manipulation functions
 | |
| 
 | |
| EVP_MAC_CTX_new() creates a new context for the MAC type I<mac>.
 | |
| The created context can then be used with most other functions
 | |
| described here.
 | |
| 
 | |
| EVP_MAC_CTX_free() frees the contents of the context, including an
 | |
| underlying context if there is one, as well as the context itself.
 | |
| NULL is a valid parameter, for which this function is a no-op.
 | |
| 
 | |
| EVP_MAC_CTX_dup() duplicates the I<src> context and returns a newly allocated
 | |
| context.
 | |
| 
 | |
| EVP_MAC_CTX_mac() returns the B<EVP_MAC> associated with the context
 | |
| I<ctx>.
 | |
| 
 | |
| =head2 Computing functions
 | |
| 
 | |
| EVP_MAC_init() sets up the underlying context with information given
 | |
| through diverse controls.
 | |
| This should be called before calling EVP_MAC_update() and
 | |
| EVP_MAC_final().
 | |
| 
 | |
| EVP_MAC_update() adds I<datalen> bytes from I<data> to the MAC input.
 | |
| 
 | |
| EVP_MAC_final() does the final computation and stores the result in
 | |
| the memory pointed at by I<out> of size I<outsize>, and sets the number
 | |
| of bytes written in I<*outl> at.
 | |
| If I<out> is NULL or I<outsize> is too small, then no computation
 | |
| is made.
 | |
| To figure out what the output length will be and allocate space for it
 | |
| dynamically, simply call with I<out> being NULL and I<outl>
 | |
| pointing at a valid location, then allocate space and make a second
 | |
| call with I<out> pointing at the allocated space.
 | |
| 
 | |
| EVP_MAC_get_params() retrieves details about the implementation
 | |
| I<mac>.
 | |
| The set of parameters given with I<params> determine exactly what
 | |
| parameters should be retrieved.
 | |
| Note that a parameter that is unknown in the underlying context is
 | |
| simply ignored.
 | |
| 
 | |
| EVP_MAC_CTX_get_params() retrieves chosen parameters, given the
 | |
| context I<ctx> and its underlying context.
 | |
| The set of parameters given with I<params> determine exactly what
 | |
| parameters should be retrieved.
 | |
| Note that a parameter that is unknown in the underlying context is
 | |
| simply ignored.
 | |
| 
 | |
| EVP_MAC_CTX_set_params() passes chosen parameters to the underlying
 | |
| context, given a context I<ctx>.
 | |
| The set of parameters given with I<params> determine exactly what
 | |
| parameters are passed down.
 | |
| Note that a parameter that is unknown in the underlying context is
 | |
| simply ignored.
 | |
| Also, what happens when a needed parameter isn't passed down is
 | |
| defined by the implementation.
 | |
| 
 | |
| EVP_MAC_gettable_params(), EVP_MAC_gettable_ctx_params() and
 | |
| EVP_MAC_settable_ctx_params() get a constant B<OSSL_PARAM> array that
 | |
| describes the retrievable and settable parameters, i.e. parameters that
 | |
| can be used with EVP_MAC_get_params(), EVP_MAC_CTX_get_params()
 | |
| and EVP_MAC_CTX_set_params(), respectively.
 | |
| See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
 | |
| 
 | |
| =head2 Information functions
 | |
| 
 | |
| EVP_MAC_CTX_get_mac_size() returns the MAC output size for the given context.
 | |
| 
 | |
| EVP_MAC_is_a() checks if the given I<mac> is an implementation of an
 | |
| algorithm that's identifiable with I<name>.
 | |
| 
 | |
| EVP_MAC_provider() returns the provider that holds the implementation
 | |
| of the given I<mac>.
 | |
| 
 | |
| EVP_MAC_do_all_provided() traverses all MAC implemented by all activated
 | |
| providers in the given library context I<libctx>, and for each of the
 | |
| implementations, calls the given function I<fn> with the implementation method
 | |
| and the given I<arg> as argument.
 | |
| 
 | |
| EVP_MAC_number() returns the internal dynamic number assigned to
 | |
| I<mac>.
 | |
| 
 | |
| EVP_MAC_name() return the name of the given MAC.  For fetched MACs
 | |
| with multiple names, only one of them is returned; it's
 | |
| recommended to use EVP_MAC_names_do_all() instead.
 | |
| 
 | |
| EVP_MAC_names_do_all() traverses all names for I<mac>, and calls
 | |
| I<fn> with each name and I<data>.
 | |
| 
 | |
| =head1 PARAMETERS
 | |
| 
 | |
| Parameters are identified by name as strings, and have an expected
 | |
| data type and maximum size.
 | |
| OpenSSL has a set of macros for parameter names it expects to see in
 | |
| its own MAC implementations.
 | |
| Here, we show all three, the OpenSSL macro for the parameter name, the
 | |
| name in string form, and a type description.
 | |
| 
 | |
| The standard parameter names are:
 | |
| 
 | |
| =over 4
 | |
| 
 | |
| =item "key" (B<OSSL_MAC_PARAM_KEY>) <octet string>
 | |
| 
 | |
| Its value is the MAC key as an array of bytes.
 | |
| 
 | |
| For MACs that use an underlying computation algorithm, the algorithm
 | |
| must be set first, see parameter names "algorithm" below.
 | |
| 
 | |
| =item "iv" (B<OSSL_MAC_PARAM_IV>) <octet string>
 | |
| 
 | |
| Some MAC implementations require an IV, this parameter sets the IV.
 | |
| 
 | |
| =item "custom" (B<OSSL_MAC_PARAM_CUSTOM>) <octet string>
 | |
| 
 | |
| Some MAC implementations (KMAC, BLAKE2) accept a Customization String,
 | |
| this parameter sets the Customization String. The default value is the
 | |
| empty string.
 | |
| 
 | |
| =item "salt" (B<OSSL_MAC_PARAM_SALT>) <octet string>
 | |
| 
 | |
| This option is used by BLAKE2 MAC.
 | |
| 
 | |
| =item "xof" (B<OSSL_MAC_PARAM_XOF>) <integer>
 | |
| 
 | |
| It's a simple flag, the value 0 or 1 are expected.
 | |
| 
 | |
| This option is used by KMAC.
 | |
| 
 | |
| =item "flags" (B<OSSL_MAC_PARAM_FLAGS>) <integer>
 | |
| 
 | |
| These will set the MAC flags to the given numbers.
 | |
| Some MACs do not support this option.
 | |
| 
 | |
| =item "properties" (B<OSSL_MAC_PARAM_PROPERTIES>) <UTF8 string>
 | |
| 
 | |
| =item "digest" (B<OSSL_MAC_PARAM_DIGEST>) <UTF8 string>
 | |
| 
 | |
| =item "cipher" (B<OSSL_MAC_PARAM_CIPHER>) <UTF8 string>
 | |
| 
 | |
| For MAC implementations that use an underlying computation cipher or
 | |
| digest, these parameters set what the algorithm should be.
 | |
| 
 | |
| The value is always the name of the intended algorithm,
 | |
| or the properties.
 | |
| 
 | |
| Note that not all algorithms may support all digests.
 | |
| HMAC does not support variable output length digests such as SHAKE128
 | |
| or SHAKE256.
 | |
| 
 | |
| =item "size" (B<OSSL_MAC_PARAM_SIZE>) <unsigned integer>
 | |
| 
 | |
| For MAC implementations that support it, set the output size that
 | |
| EVP_MAC_final() should produce.
 | |
| The allowed sizes vary between MAC implementations, but must never exceed
 | |
| what can be given with a B<size_t>.
 | |
| 
 | |
| =item "tls-data-size" (B<OSSL_MAC_PARAM_TLS_DATA_SIZE>) <unsigned integer>
 | |
| 
 | |
| This parameter is only supported by HMAC. If set then special handling is
 | |
| activated for calculating the MAC of a received mac-then-encrypt TLS record
 | |
| where variable length record padding has been used (as in the case of CBC mode
 | |
| ciphersuites). The value represents the total length of the record that is
 | |
| having the MAC calculated including the received MAC and the record padding.
 | |
| 
 | |
| When used EVP_MAC_update must be called precisely twice. The first time with
 | |
| the 13 bytes of TLS "header" data, and the second time with the entire record
 | |
| including the MAC itself and any padding. The entire record length must equal
 | |
| the value passed in the "tls-data-size" parameter. The length passed in the
 | |
| B<datalen> parameter to EVP_MAC_update() should be equal to the length of the
 | |
| record after the MAC and any padding has been removed.
 | |
| 
 | |
| =back
 | |
| 
 | |
| All these parameters should be used before the calls to any of
 | |
| EVP_MAC_init(), EVP_MAC_update() and EVP_MAC_final() for a full
 | |
| computation.
 | |
| Anything else may give undefined results.
 | |
| 
 | |
| =head1 RETURN VALUES
 | |
| 
 | |
| EVP_MAC_fetch() returns a pointer to a newly fetched EVP_MAC, or
 | |
| NULL if allocation failed.
 | |
| 
 | |
| EVP_MAC_up_ref() returns 1 on success, 0 on error.
 | |
| 
 | |
| EVP_MAC_free() returns nothing at all.
 | |
| 
 | |
| EVP_MAC_is_a() returns 1 if the given method can be identified with
 | |
| the given name, otherwise 0.
 | |
| 
 | |
| EVP_MAC_name() returns a name of the MAC, or NULL on error.
 | |
| 
 | |
| EVP_MAC_provider() returns a pointer to the provider for the MAC, or
 | |
| NULL on error.
 | |
| 
 | |
| EVP_MAC_CTX_new() and EVP_MAC_CTX_dup() return a pointer to a newly
 | |
| created EVP_MAC_CTX, or NULL if allocation failed.
 | |
| 
 | |
| EVP_MAC_CTX_free() returns nothing at all.
 | |
| 
 | |
| EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on
 | |
| success, 0 on error.
 | |
| 
 | |
| EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0
 | |
| on error.
 | |
| 
 | |
| EVP_MAC_CTX_get_mac_size() returns the expected output size, or 0 if it isn't set.
 | |
| If it isn't set, a call to EVP_MAC_init() should get it set.
 | |
| 
 | |
| EVP_MAC_do_all_provided() returns nothing at all.
 | |
| 
 | |
| =head1 EXAMPLES
 | |
| 
 | |
|   #include <stdlib.h>
 | |
|   #include <stdio.h>
 | |
|   #include <string.h>
 | |
|   #include <stdarg.h>
 | |
|   #include <unistd.h>
 | |
| 
 | |
|   #include <openssl/evp.h>
 | |
|   #include <openssl/err.h>
 | |
|   #include <openssl/params.h>
 | |
| 
 | |
|   int main() {
 | |
|       EVP_MAC *mac = EVP_MAC_fetch(NULL, getenv("MY_MAC"), NULL);
 | |
|       const char *cipher = getenv("MY_MAC_CIPHER");
 | |
|       const char *digest = getenv("MY_MAC_DIGEST");
 | |
|       const char *key = getenv("MY_KEY");
 | |
|       EVP_MAC_CTX *ctx = NULL;
 | |
| 
 | |
|       unsigned char buf[4096];
 | |
|       size_t read_l;
 | |
|       size_t final_l;
 | |
| 
 | |
|       size_t i;
 | |
| 
 | |
|       OSSL_PARAM params[4];
 | |
|       size_t params_n = 0;
 | |
| 
 | |
|       if (cipher != NULL)
 | |
|           params[params_n++] =
 | |
|               OSSL_PARAM_construct_utf8_string("cipher", (char*)cipher, 0);
 | |
|       if (digest != NULL)
 | |
|           params[params_n++] =
 | |
|               OSSL_PARAM_construct_utf8_string("digest", (char*)digest, 0);
 | |
|       params[params_n++] =
 | |
|           OSSL_PARAM_construct_octet_string("key", (void*)key, strlen(key));
 | |
|       params[params_n] = OSSL_PARAM_construct_end();
 | |
| 
 | |
|       if (mac == NULL
 | |
|           || key == NULL
 | |
|           || (ctx = EVP_MAC_CTX_new(mac)) == NULL
 | |
|           || EVP_MAC_CTX_set_params(ctx, params) <= 0)
 | |
|           goto err;
 | |
| 
 | |
|       if (!EVP_MAC_init(ctx))
 | |
|           goto err;
 | |
| 
 | |
|       while ( (read_l = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
 | |
|           if (!EVP_MAC_update(ctx, buf, read_l))
 | |
|               goto err;
 | |
|       }
 | |
| 
 | |
|       if (!EVP_MAC_final(ctx, buf, &final_l, sizeof(buf)))
 | |
|           goto err;
 | |
| 
 | |
|       printf("Result: ");
 | |
|       for (i = 0; i < final_l; i++)
 | |
|           printf("%02X", buf[i]);
 | |
|       printf("\n");
 | |
| 
 | |
|       EVP_MAC_CTX_free(ctx);
 | |
|       EVP_MAC_free(mac);
 | |
|       exit(0);
 | |
| 
 | |
|    err:
 | |
|       EVP_MAC_CTX_free(ctx);
 | |
|       EVP_MAC_free(mac);
 | |
|       fprintf(stderr, "Something went wrong\n");
 | |
|       ERR_print_errors_fp(stderr);
 | |
|       exit (1);
 | |
|   }
 | |
| 
 | |
| A run of this program, called with correct environment variables, can
 | |
| look like this:
 | |
| 
 | |
|   $ MY_MAC=cmac MY_KEY=secret0123456789 MY_MAC_CIPHER=aes-128-cbc \
 | |
|     LD_LIBRARY_PATH=. ./foo < foo.c
 | |
|   Result: C5C06683CD9DDEF904D754505C560A4E
 | |
| 
 | |
| (in this example, that program was stored in F<foo.c> and compiled to
 | |
| F<./foo>)
 | |
| 
 | |
| =head1 SEE ALSO
 | |
| 
 | |
| L<property(7)>
 | |
| L<OSSL_PARAM(3)>,
 | |
| L<EVP_MAC-BLAKE2(7)>,
 | |
| L<EVP_MAC-CMAC(7)>,
 | |
| L<EVP_MAC-GMAC(7)>,
 | |
| L<EVP_MAC-HMAC(7)>,
 | |
| L<EVP_MAC-KMAC(7)>,
 | |
| L<EVP_MAC-Siphash(7)>,
 | |
| L<EVP_MAC-Poly1305(7)>
 | |
| 
 | |
| =head1 HISTORY
 | |
| 
 | |
| These functions were added in OpenSSL 3.0.
 | |
| 
 | |
| =head1 COPYRIGHT
 | |
| 
 | |
| Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
 | |
| 
 | |
| Licensed under the Apache License 2.0 (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
 | |
| L<https://www.openssl.org/source/license.html>.
 | |
| 
 | |
| =cut
 |