aboutsummaryrefslogtreecommitdiff
path: root/doc/internal
diff options
context:
space:
mode:
Diffstat (limited to 'doc/internal')
-rw-r--r--doc/internal/man3/OPENSSL_SA.pod131
-rw-r--r--doc/internal/man3/OPTIONS.pod343
-rw-r--r--doc/internal/man3/OSSL_DEPRECATED.pod54
-rw-r--r--doc/internal/man3/OSSL_METHOD_STORE.pod144
-rw-r--r--doc/internal/man3/bn_mul_words.pod231
-rw-r--r--doc/internal/man3/cms_add1_signing_cert.pod46
-rw-r--r--doc/internal/man3/evp_generic_fetch.pod285
-rw-r--r--doc/internal/man3/evp_keymgmt_newdata.pod88
-rw-r--r--doc/internal/man3/evp_keymgmt_util_export_to_provider.pod106
-rw-r--r--doc/internal/man3/evp_md_get_number.pod112
-rw-r--r--doc/internal/man3/evp_pkey_export_to_provider.pod80
-rw-r--r--doc/internal/man3/evp_pkey_get1_ED25519.pod43
-rw-r--r--doc/internal/man3/ossl_DER_w_begin_sequence.pod48
-rw-r--r--doc/internal/man3/ossl_DER_w_bn.pod66
-rw-r--r--doc/internal/man3/ossl_DER_w_precompiled.pod48
-rw-r--r--doc/internal/man3/ossl_algorithm_do_all.pod63
-rw-r--r--doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod44
-rw-r--r--doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod45
-rw-r--r--doc/internal/man3/ossl_cmp_certreq_new.pod178
-rw-r--r--doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod76
-rw-r--r--doc/internal/man3/ossl_cmp_hdr_init.pod151
-rw-r--r--doc/internal/man3/ossl_cmp_mock_srv_new.pod89
-rw-r--r--doc/internal/man3/ossl_cmp_msg_check_update.pod95
-rw-r--r--doc/internal/man3/ossl_cmp_msg_create.pod134
-rw-r--r--doc/internal/man3/ossl_cmp_msg_protect.pod66
-rw-r--r--doc/internal/man3/ossl_cmp_pkisi_get_status.pod99
-rw-r--r--doc/internal/man3/ossl_cmp_print_log.pod108
-rw-r--r--doc/internal/man3/ossl_ends_with_dirsep.pod45
-rw-r--r--doc/internal/man3/ossl_global_properties_no_mirrored.pod56
-rw-r--r--doc/internal/man3/ossl_init_thread_deregister.pod66
-rw-r--r--doc/internal/man3/ossl_lib_ctx_get_data.pod154
-rw-r--r--doc/internal/man3/ossl_method_construct.pod158
-rw-r--r--doc/internal/man3/ossl_namemap_new.pod129
-rw-r--r--doc/internal/man3/ossl_provider_add_conf_module.pod41
-rw-r--r--doc/internal/man3/ossl_provider_new.pod400
-rw-r--r--doc/internal/man3/ossl_punycode_decode.pod60
-rw-r--r--doc/internal/man3/ossl_rand_get_entropy.pod66
-rw-r--r--doc/internal/man3/ossl_random_add_conf_module.pod42
-rw-r--r--doc/internal/man3/ossl_rsa_get0_all_params.pod75
-rw-r--r--doc/internal/man3/x509v3_cache_extensions.pod41
-rw-r--r--doc/internal/man7/DERlib.pod149
-rw-r--r--doc/internal/man7/EVP_PKEY.pod212
-rw-r--r--doc/internal/man7/VERSION.pod149
-rw-r--r--doc/internal/man7/build.info.pod644
-rw-r--r--doc/internal/man7/deprecation.pod140
45 files changed, 5600 insertions, 0 deletions
diff --git a/doc/internal/man3/OPENSSL_SA.pod b/doc/internal/man3/OPENSSL_SA.pod
new file mode 100644
index 000000000000..8124003d77a6
--- /dev/null
+++ b/doc/internal/man3/OPENSSL_SA.pod
@@ -0,0 +1,131 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_SA, ossl_sa_TYPE_new, ossl_sa_TYPE_free,
+ossl_sa_TYPE_free_leaves, ossl_sa_TYPE_num, ossl_sa_TYPE_doall,
+ossl_sa_TYPE_doall_arg, ossl_sa_TYPE_get, ossl_sa_TYPE_set
+- sparse array container
+
+=head1 SYNOPSIS
+
+ #include "crypto/sparse_array.h"
+
+ typedef struct sparse_array_st OPENSSL_SA;
+
+ SPARSE_ARRAY_OF(TYPE)
+ DEFINE_SPARSE_ARRAY_OF(TYPE)
+
+ SPARSE_ARRAY_OF(TYPE) *ossl_sa_TYPE_new(void);
+ void ossl_sa_TYPE_free(const SPARSE_ARRAY_OF(TYPE) *sa);
+ void ossl_sa_TYPE_free_leaves(const SPARSE_ARRAY_OF(TYPE) *sa);
+ size_t ossl_sa_TYPE_num(const SPARSE_ARRAY_OF(TYPE) *sa);
+ void ossl_sa_TYPE_doall(const OPENSSL_SA *sa, void (*leaf)(ossl_uintmax_t,
+ void *));
+ void ossl_sa_TYPE_doall_arg(const OPENSSL_SA *sa,
+ void (*leaf)(ossl_uintmax_t, void *, void *),
+ void *arg);
+ TYPE *ossl_sa_TYPE_get(const SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx);
+ int ossl_sa_TYPE_set(SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx,
+ TYPE *value);
+
+=head1 DESCRIPTION
+
+=begin comment
+
+POD is pretty good at recognising function names and making them appropriately
+bold... however, when part of the function name is variable, we have to help
+the processor along
+
+=end comment
+
+SPARSE_ARRAY_OF() returns the name for a sparse array of the specified
+B<I<TYPE>>. DEFINE_SPARSE_ARRAY_OF() creates set of functions for a sparse
+array of B<I<TYPE>>. This will mean that a pointer to type B<I<TYPE>>
+is stored in each element of a sparse array, the type is referenced by
+B<SPARSE_ARRAY_OF>(B<I<TYPE>>) and each function name begins with
+B<ossl_sa_I<TYPE>_>. For example:
+
+ TYPE *ossl_sa_TYPE_get(SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx);
+
+B<ossl_sa_I<TYPE>_num>() returns the number of elements in I<sa> or 0 if I<sa>
+is NULL.
+
+B<ossl_sa_I<TYPE>_get>() returns element I<idx> in I<sa>, where I<idx> starts
+at zero. If I<idx> refers to a value that has not been set then NULL is
+returned.
+
+B<ossl_sa_I<TYPE>_set>() sets element I<idx> in I<sa> to I<value>, where I<idx>
+starts at zero. The sparse array will be resized as required.
+
+B<ossl_sa_I<TYPE>_new>() allocates a new empty sparse array.
+
+B<ossl_sa_I<TYPE>_free>() frees up the I<sa> structure. It does I<not> free up any
+elements of I<sa>. After this call I<sa> is no longer valid.
+
+B<ossl_sa_I<TYPE>_free_leaves>() frees up the I<sa> structure and all of its
+elements. After this call I<sa> is no longer valid.
+
+B<ossl_sa_I<TYPE>_doall>() calls the function I<leaf> for each element in I<sa>
+in ascending index order. The index position, within the sparse array,
+of each item is passed as the first argument to the leaf function and a
+pointer to the associated value is passed as the second argument.
+
+B<ossl_sa_I<TYPE>_doall_arg>() calls the function I<leaf> for each element in
+I<sa> in ascending index order. The index position, within the sparse
+array, of each item is passed as the first argument to the leaf function,
+a pointer to the associated value is passed as the second argument and
+the third argument is the user supplied I<arg>.
+
+
+=head1 NOTES
+
+Sparse arrays are an internal data structure and should B<not> be used by user
+applications.
+
+Care should be taken when accessing sparse arrays in multi-threaded
+environments. The B<ossl_sa_I<TYPE>_set>() operation can cause the internal
+structure of the sparse array to change which causes race conditions if the
+sparse array is accessed in a different thread.
+
+SPARSE_ARRAY_OF() and DEFINE_SPARSE_ARRAY_OF() are implemented as macros.
+
+The underlying utility B<OPENSSL_SA_> API should not be used directly. It
+defines these functions: OPENSSL_SA_doall, OPENSSL_SA_doall_arg,
+OPENSSL_SA_free, OPENSSL_SA_free_leaves, OPENSSL_SA_get, OPENSSL_SA_new,
+OPENSSL_SA_num and OPENSSL_SA_set.
+
+=head1 RETURN VALUES
+
+B<ossl_sa_I<TYPE>_num>() returns the number of elements in the sparse array or
+B<0> if the passed sparse array is NULL.
+
+B<ossl_sa_I<TYPE>_get>() returns a pointer to a sparse array element or NULL if
+the element has not be set.
+
+B<ossl_sa_I<TYPE>_set>() return B<1> on success and B<0> on error. In the latter
+case, the elements of the sparse array remain unchanged, although the internal
+structures might have.
+
+B<ossl_sa_I<TYPE>_new>() returns an empty sparse array or NULL if an error
+occurs.
+
+B<ossl_sa_I<TYPE>_doall>(), B<ossl_sa_I<TYPE>_doall_arg>(),
+B<ossl_sa_I<TYPE>_free>() and B<ossl_sa_I<TYPE>_free_leaves>()
+do not return values.
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. Copyright
+(c) 2019, Oracle and/or its affiliates. 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
diff --git a/doc/internal/man3/OPTIONS.pod b/doc/internal/man3/OPTIONS.pod
new file mode 100644
index 000000000000..dbdd39a2ee64
--- /dev/null
+++ b/doc/internal/man3/OPTIONS.pod
@@ -0,0 +1,343 @@
+=pod
+
+=head1 NAME
+
+OPTIONS, OPT_PAIR, OPT_COMMON, OPT_ERR, OPT_EOF, OPT_HELP,
+opt_init, opt_progname, opt_appname, opt_getprog, opt_help,
+opt_begin, opt_next, opt_flag, opt_arg, opt_unknown, opt_cipher,
+opt_cipher_any, opt_cipher_silent, opt_md,
+opt_int, opt_int_arg, opt_long, opt_ulong, opt_intmax, opt_uintmax,
+opt_format, opt_isdir, opt_string, opt_pair,
+opt_num_rest, opt_rest, opt_legacy_okay
+- Option parsing for commands and tests
+
+=head1 SYNOPSIS
+
+ #include "opt.h"
+
+ typedef struct { ... } OPTIONS;
+ typedef struct { ... } OPT_PAIR;
+ #define OPT_COMMON
+ #define OPT_ERR
+ #define OPT_EOF
+ #define OPT_HELP
+
+ char *opt_init(int argc, char **argv, const OPTIONS *o);
+ char *opt_progname(const char *argv0);
+ char *opt_appname(const char *argv0);
+ char *opt_getprog(void);
+ void opt_help(const OPTIONS *list);
+
+ void opt_begin(void);
+ int opt_next(void);
+ char *opt_flag(void);
+ char *opt_arg(void);
+ char *opt_unknown(void);
+ int opt_cipher(const char *name, EVP_CIPHER **cipherp);
+ int opt_cipher_any(const char *name, EVP_CIPHER **cipherp);
+ int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp);
+ int opt_md(const char *name, EVP_MD **mdp);
+
+ int opt_int(const char *value, int *result);
+ int opt_int_arg(void);
+ int opt_long(const char *value, long *result);
+ int opt_ulong(const char *value, unsigned long *result);
+ int opt_intmax(const char *value, intmax_t *result);
+ int opt_uintmax(const char *value, uintmax_t *result);
+
+ int opt_format(const char *s, unsigned long flags, int *result);
+ int opt_isdir(const char *name);
+ int opt_string(const char *name, const char **options);
+ int opt_pair(const char *name, const OPT_PAIR* pairs, int *result);
+
+ int opt_num_rest(void);
+ char **opt_rest(void);
+
+ int opt_legacy_okay(void);
+
+=head1 DESCRIPTION
+
+The functions on this page provide a common set of option-parsing for
+the OpenSSL command and the internal test programs.
+It is intended to be used like the standard getopt(3) routine, except
+that multi-character flag names are supported, and a variety of parsing
+and other utility functions are also provided.
+
+Programs that use this should make sure to set the appropriate C<-I>
+flag.
+
+These routines expect a global B<BIO> named B<bio_err> to point to
+the equivalent of B<stderr>. This is already done in the OpenSSL
+application.
+
+=head2 Data Types
+
+Each program should define, near the main() routine, an enumeration
+that is the set of options the program accepts. For example:
+
+ typedef enum OPTION_choice {
+ OPT_COMMON,
+ OPT_YES, OPT_NAME, OPT_COUNT, OPT_OFILE,
+ ...
+ } OPTION_CHOICE;
+
+The first two lines must appear exactly as shown.
+OPT_COMMON is a macro that expands to C<OPT_ERR = -1, OPT_EOF = 0, OPT_HELP>.
+In addition to defining symbolic names for the constants that opt_next()
+returns, it also helps guarantee that every command has a C<-help> option.
+The third line is a sample
+set of flags, and the closing C<typedef> name is used for error-checking
+as discussed below.
+By declaring the variable as an C<OPTION_CHOICE>, with the right warning
+flags, the compiler could check that all specified options are handled.
+
+The B<OPTIONS> C<typedef> specifies an option: what type of argument
+it takes (if any), and an optional "help" string. It is a C<struct>
+containing these fields:
+
+ const char *name;
+ int retval;
+ int valtype;
+ const char *helpstr;
+
+The B<name> is the name of the option that the user would type. Options
+are words prefaced with a minus sign. If the user uses two minus signs,
+this is also accepted for compatibility with other GNU software. Some
+names are special, and are described below.
+
+The B<retval> is the value to return if the option is found. It should be
+one of the choices in the enumeration above.
+
+The B<valtype> defines what the option's parameter must be. It should
+be chosen from the following set:
+
+ \0 No value
+ '-' No value
+ 's' A text string
+ '/' A directory
+ '<' Name of file to open for input
+ '>' Name of file to open for output
+ 'n' A signed number that fits in the C<int> type
+ 'p' A positive number that fits in the C<int> type
+ 'N' A nonnegative number that fits in the C<int> type
+ 'M' A signed number that fits in the C<intmax_t> type
+ 'U' An unsigned number that fits in the C<uintmax_t> type
+ 'l' A signed number that fits in the C<long> type
+ 'u' An unsigned number that fits in the C<unsigned long> type
+ 'c' File in PEM, DER, or S/MIME format
+ 'F' A file in PEM or DER format
+ 'E' Like 'F' but also allows ENGINE
+ 'f' Any file format
+
+The B<helpstr> is what to display when the user uses the help option,
+which should be C<"help">.
+
+A program should declare its options right after the enumeration,
+and should follow the ordering of the enumeration as this helps
+readability and maintainability:
+
+ static OPTIONS my_options[] = {
+ {"help", OPT_HELP, '-', "Display this summary"},
+ {"yes", OPT_YES, '-', "Print an affirmative reply"},
+ {"count", OPT_COUNT, 'p', "Repeat count"},
+ {"output" OPT_OFILE, '>', "Output file; default is stdout"},
+ {NULL}
+ };
+
+Note that the B<OPT_HELP> option is explicitly listed, and the list ends with
+an entry of all-null's. The other two special options, B<OPT_ERR> and B<OPT_EOF>
+should not appear in the array.
+
+If the help string is too long to fit into one line, it may be continued
+on multiple lines; each entry should use B<OPT_MORE_STR>, like this:
+
+ {"output" OPT_OFILE, '>', "Output file; default is stdout"},
+ {OPT_MORE_STR, 0, 0,
+ "This flag is not really needed on Unix systems"},
+ {OPT_MORE_STR, 0, 0,
+ "(Unix and descendents for the win!)"}
+
+Each subsequent line will be indented the correct amount.
+
+By default, the help display will include a standard prolog:
+
+ Usage: PROGRAM [options]
+ Valid options are:
+ ...detailed list of options...
+
+Sometimes there are parameters that should appear in the synopsis.
+Use B<OPT_HELP_STR> as the first entry in your array:
+
+ {OPT_HELP_STR, 1, '-', Usage: %s [options] [text...]\n"}
+
+The B<retval> and B<valtype> are ignored, and the B<helpstr> should
+follow the general construction as shown. The C<%s> will get the program
+name.
+
+If a command has a large set of options, it can be useful to break them
+into sections. Use the macro B<OPT_SECTION> or B<OPT_SECTION_STR>
+to indicate this. The two lines below are equivalent:
+
+ OPT_SECTION("Validation"),
+ {OPT_SECTION_STR, 1, '-', "Validation options:\n"},
+
+In addition to providing help about options, you can provide a description
+of the parameters a command takes. These should appear at the end of
+the options and are indicated by using B<OPT_PARAM_STR> or the
+B<OPT_PARAMETERS> macro:
+
+ OPT_PARAMETERS()
+ {OPT_PARAM_STR, 1, '-', "Parameters:\n"}
+
+Every "option" after after this should contain the parameter and
+the help string:
+
+ {"text", 0, 0, "Words to display (optional)"},
+
+=head2 Functions
+
+The opt_init() function takes the I<argc> and I<argv> arguments given to main()
+and a pointer I<o> to the list of options. It returns the simple program
+name, as defined by opt_progname().
+
+The opt_progname() function takes the full pathname C<argv[0]> in its I<arg0>
+parameter and returns
+the simple short name of the executable, to be used for error messages and
+the like.
+
+The opt_appname() function takes in its I<argv0> parameter
+the "application" name (such
+as the specific command from L<openssl(1)> and appends it to the program
+name. This function should only be called once.
+
+The opt_getprog() function returns the value set by opt_appname().
+
+The opt_help() function takes a list of option definitions and prints a
+nicely-formatted output.
+
+The opt_begin() function, which is called automatically by opt_init(),
+can be used to reset the option parsing loop.
+
+The opt_next() function is called, once opt_init() has been called,
+in a loop to fetch each option in turn. It returns -1, or B<OPT_EOF> when the
+end of arguments has been reached. This is typically done like this:
+
+ prog = opt_init(argc, argv, my_options);
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ case OPT_EOF:
+ case OPT_ERR:
+ opthelp:
+ fprintf(stderr, "%s: Use -help for summary\n", prog);
+ exit(1);
+ case OPT_HELP:
+ opt_help(my_options);
+ exit(0);
+ ...other options...
+ }
+ }
+
+Within the option parsing loop, the following functions may be called.
+
+The opt_flag() function returns the most recent option name
+including the preceding C<->.
+
+The opt_arg() function returns the option's argument value, if there is one.
+
+The opt_unknown() function returns the unknown option.
+In an option list, there can be at most one option with the empty string.
+This is a "wildcard" or "unknown" option. For example, it allows an
+option to be be taken as digest algorithm, like C<-sha1>. The function
+opt_md() takes the specified I<name> and fills in the digest into I<mdp>.
+The functions opt_cipher(), opt_cipher_any() and opt_cipher_silent()
+each takes the specified I<name> and fills in the cipher into I<cipherp>.
+The function opt_cipher() only accepts ciphers which are not
+AEAD and are not using XTS mode. The functions opt_cipher_any() and
+opt_cipher_silent() accept any cipher, the latter not emitting an error
+if the cipher is not located.
+
+There are a several useful functions for parsing numbers. These are
+opt_int(), opt_long(), opt_ulong(), opt_intmax(), and opt_uintmax(). They all
+take C<0x> to mean hexadecimal and C<0> to mean octal, and will do the
+necessary range-checking. They return 1 if successful and fill in the
+C<result> pointer with the value, or 0 on error. Note that opt_next()
+will also do range-check on the argument if the appropriate B<valtype>
+field is specified for the option. This means that error-checking inside
+the C<switch> C<case> can often be elided.
+
+The opt_int_arg() function is a convenience abbreviation to opt_int().
+It parses and returns an integer, assuming its range has been checked before.
+
+The opt_format() function takes a string value,
+such as used with the B<-informat> or similar option, and fills
+the value from the constants in F<fmt.h> file.
+
+The opt_isdir() function returns 1 if the specified I<name> is
+a directory, or 0 if not.
+
+The opt_string() function checks that I<name> appears in the
+NULL-terminated array of strings. It returns 1 if found,
+or prints a diagnostic and returns 0 if not.
+
+The opt_pair() function takes a list of I<pairs>, each of which
+has a text name and an integer. The specified I<name> is
+found on the list, it puts the index in I<*result>, and returns
+1. If not found, it returns 0.
+
+The following functions can be used after processing all the options.
+
+The opt_num_rest() function returns what is left.
+
+The opt_rest() function returns a pointer to the first non-option.
+If there were no parameters, it will point to the NULL that is
+at the end of the standard I<argv> array.
+
+The opt_legacy_okay() function returns true if no options have been
+specified that would preclude using legacy code paths. Currently,
+the various provider options preclude legacy operation. This means,
+for example, that specifying both B<-provider> and B<-engine> in the
+same command line will not work as expected.
+
+=head2 Common Options
+
+There are a few groups of options that are common to many OpenSSL programs.
+These are handled with sets of macros that define common option names
+and common code to handle them. The categories are identified by a
+letter:
+
+ V Validation
+ X Extended certificate
+ S TLS/SSL
+ R Random state
+
+The B<OPT_x_ENUM> macro is used to define the numeration values, where B<x>
+is one of the letters above. The B<OPT_x_OPTIONS> macro is used to
+list the set of common options, and the B<OPT_x_CASES> is used in
+the C<switch> statement.
+
+The common options are used throughout the sources for the OpenSSL commands.
+They are also used with common descriptions when generating the
+manpages, in the file F<doc/perlvars.pm>, which follow a similar naming
+convention.
+
+=head1 RETURN VALUES
+
+Detailed above.
+
+=head1 EXAMPLES
+
+The best examples can be found in sources for the commands in the F<apps>
+directory of the source tree.
+A notable exception is F<apps/cmp.c> which uses this API, but does
+things very differently.
+
+=head1 COPYRIGHT
+
+Copyright 2021-2024 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
diff --git a/doc/internal/man3/OSSL_DEPRECATED.pod b/doc/internal/man3/OSSL_DEPRECATED.pod
new file mode 100644
index 000000000000..8370d60f18fb
--- /dev/null
+++ b/doc/internal/man3/OSSL_DEPRECATED.pod
@@ -0,0 +1,54 @@
+=pod
+
+=head1 NAME
+
+OSSL_DEPRECATED, OSSL_DEPRECATED_FOR - General deprecation macros
+
+=head1 SYNOPSIS
+
+ #include <openssl/macros.h>
+
+ #define OSSL_DEPRECATED(since)
+ #define OSSL_DEPRECATED_FOR(since, msg)
+
+=head1 DESCRIPTION
+
+OSSL_DEPRECATED() implements the deprecated attribute if the compiler
+supports it, otherwise it expands to nothing. It takes one argument
+I<since> that should be set to the OpenSSL version where the symbol was
+deprecated, and will be displayed with the deprecation warning message,
+for compilers that support user specified deprecation messages.
+
+OSSL_DEPRECATED_FOR() does the same as OSSL_DEPRECATED(), but also takes a
+second argument I<msg>, which is an additional text messages to be displayed
+with the deprecation warning along with the OpenSSL version number, for
+compilers that support user specified deprecation messages.
+
+These macros are used to define the version specific deprecation macros
+described in L<deprecation(7)>.
+
+=begin comment
+
+[RETURN VALUES isn't relevant for these macros, but find-doc-nits demands
+the presence of this section]
+
+=head1 RETURN VALUES
+
+[podchecker doesn't like empty sections]
+
+=end comment
+
+=head1 SEE ALSO
+
+L<deprecation(7)>
+
+=head1 COPYRIGHT
+
+Copyright 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
diff --git a/doc/internal/man3/OSSL_METHOD_STORE.pod b/doc/internal/man3/OSSL_METHOD_STORE.pod
new file mode 100644
index 000000000000..70f6eb520ff3
--- /dev/null
+++ b/doc/internal/man3/OSSL_METHOD_STORE.pod
@@ -0,0 +1,144 @@
+=pod
+
+=head1 NAME
+
+OSSL_METHOD_STORE, ossl_method_store_new, ossl_method_store_free,
+ossl_method_store_init, ossl_method_store_cleanup,
+ossl_method_store_add, ossl_method_store_fetch,
+ossl_method_store_remove, ossl_method_store_remove_all_provided,
+ossl_method_store_cache_get, ossl_method_store_cache_set,
+ossl_method_store_cache_flush_all
+- implementation method store and query
+
+=head1 SYNOPSIS
+
+ #include "internal/property.h"
+
+ typedef struct ossl_method_store_st OSSL_METHOD_STORE;
+
+ OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx);
+ void ossl_method_store_free(OSSL_METHOD_STORE *store);
+ int ossl_method_store_init(OSSL_LIB_CTX *ctx);
+ void ossl_method_store_cleanup(OSSL_LIB_CTX *ctx);
+ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
+ int nid, const char *properties, void *method,
+ int (*method_up_ref)(void *),
+ void (*method_destruct)(void *));
+ int ossl_method_store_remove(OSSL_METHOD_STORE *store,
+ int nid, const void *method);
+ int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
+ int nid, const char *properties,
+ void **method, const OSSL_PROVIDER **prov_rw);
+ int ossl_method_store_remove_all_provided(OSSL_METHOD_STORE *store,
+ const OSSL_PROVIDER *prov);
+
+ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
+ int nid, const char *prop_query, void **method);
+ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
+ int nid, const char *prop_query, void *method,
+ int (*method_up_ref)(void *),
+ void (*method_destruct)(void *));
+ void ossl_method_store_cache_flush_all(OSSL_METHOD_STORE *store);
+
+=head1 DESCRIPTION
+
+OSSL_METHOD_STORE stores methods that can be queried using properties and a
+numeric identity (nid).
+
+Methods are expected to be library internal structures.
+It's left to the caller to define the exact contents.
+
+Numeric identities are expected to be an algorithm identity for the methods.
+It's left to the caller to define exactly what an algorithm is, and to allocate
+these numeric identities accordingly.
+
+The B<OSSL_METHOD_STORE> also holds an internal query cache, which is accessed
+separately (see L</Cache Functions> below).
+
+=head2 Store Functions
+
+ossl_method_store_init() initialises the method store subsystem in the scope of
+the library context I<ctx>.
+
+ossl_method_store_cleanup() cleans up and shuts down the implementation method
+store subsystem in the scope of the library context I<ctx>.
+
+ossl_method_store_new() create a new empty method store using the supplied
+I<ctx> to allow access to the required underlying property data.
+
+ossl_method_store_free() frees resources allocated to I<store>.
+
+ossl_method_store_add() adds the I<method> constructed from an implementation in
+the provider I<prov> to the I<store> as an instance of an algorithm indicated by
+I<nid> and the property definition I<properties>, unless the I<store> already
+has a method from the same provider with the same I<nid> and I<properties>.
+If the I<method_up_ref> function is given, it's called to increment the
+reference count of the method.
+If the I<method_destruct> function is given, it's called when this function
+fails to add the method to the store, or later on when it is being released from
+the I<store>.
+
+ossl_method_store_remove() removes the I<method> identified by I<nid> from the
+I<store>.
+
+ossl_method_store_fetch() queries I<store> for a method identified by I<nid>
+that matches the property query I<prop_query>.
+I<*prop> may be a pointer to a provider, which will narrow the search
+to methods from that provider.
+The result, if any, is returned in I<*method>, and its provider in I<*prov>.
+
+ossl_method_store_remove_all_provided() removes all methods from I<store>
+that are provided by I<prov>.
+When doing so, it also flushes the corresponding cache entries.
+
+=head2 Cache Functions
+
+ossl_method_store_cache_get() queries the cache associated with the I<store>
+for a method identified by I<nid> that matches the property query
+I<prop_query>.
+Additionally, if I<prov> isn't NULL, it will be used to narrow the search
+to only include methods from that provider.
+The result, if any, is returned in I<method>.
+
+ossl_method_store_cache_set() sets a cache entry identified by I<nid> from the
+provider I<prov>, with the property query I<prop_query> in the I<store>.
+Future calls to ossl_method_store_cache_get() will return the specified I<method>.
+The I<method_up_ref> function is called to increment the
+reference count of the method and the I<method_destruct> function is called
+to decrement it.
+
+ossl_method_store_cache_flush_all() flushes all cached entries associated with
+I<store>.
+
+=head1 NOTES
+
+The I<prop_query> argument to ossl_method_store_cache_get() and
+ossl_method_store_cache_set() is not allowed to be NULL. Use "" for an
+empty property definition or query.
+
+=head1 RETURN VALUES
+
+ossl_method_store_new() returns a new method store object or NULL on failure.
+
+ossl_method_store_free(), ossl_method_store_add(),
+ossl_method_store_remove(), ossl_method_store_fetch(),
+ossl_method_store_cache_get(), ossl_method_store_cache_set() and
+ossl_method_store_flush_cache() return B<1> on success and B<0> on error.
+
+ossl_method_store_free() and ossl_method_store_cleanup() do not return any value.
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+Copyright (c) 2019, Oracle and/or its affiliates. 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
diff --git a/doc/internal/man3/bn_mul_words.pod b/doc/internal/man3/bn_mul_words.pod
new file mode 100644
index 000000000000..d2d8e3397a14
--- /dev/null
+++ b/doc/internal/man3/bn_mul_words.pod
@@ -0,0 +1,231 @@
+=pod
+
+=head1 NAME
+
+bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
+bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
+bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,
+bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,
+bn_mul_low_recursive, bn_sqr_normal, bn_sqr_recursive,
+bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top,
+mul, mul_add, sqr - BIGNUM
+library internal functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num,
+ BN_ULONG w);
+ void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+ BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
+ int num);
+ BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
+ int num);
+
+ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+ void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a);
+ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a);
+
+ int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n);
+
+ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
+ int nb);
+ void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
+ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ int dna, int dnb, BN_ULONG *tmp);
+ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+ int n, int tna, int tnb, BN_ULONG *tmp);
+ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+ int n2, BN_ULONG *tmp);
+
+ void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+ void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp);
+
+ BIGNUM *bn_expand(BIGNUM *a, int bits);
+ BIGNUM *bn_wexpand(BIGNUM *a, int n);
+ BIGNUM *bn_expand2(BIGNUM *a, int n);
+ void bn_fix_top(BIGNUM *a);
+
+The following are macros:
+
+ void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
+ void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
+ void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a);
+
+ void bn_check_top(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+This page documents the internal functions used by the OpenSSL
+B<BIGNUM> implementation. They are described here to facilitate
+debugging and extending the library. They are I<not> to be used by
+applications.
+
+=head2 The BIGNUM structure
+
+ typedef struct bignum_st BIGNUM;
+
+ struct bignum_st
+ {
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int dmax; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+ };
+
+
+The integer value is stored in B<d>, a malloc()ed array of words (B<BN_ULONG>),
+least significant word first. A B<BN_ULONG> can be either 16, 32 or 64 bits
+in size, depending on the 'number of bits' (B<BITS2>) specified in
+C<openssl/bn.h>.
+
+B<dmax> is the size of the B<d> array that has been allocated. B<top>
+is the number of words being used, so for a value of 4, bn.d[0]=4 and
+bn.top=1. B<neg> is 1 if the number is negative. When a B<BIGNUM> is
+B<0>, the B<d> field can be B<NULL> and B<top> == B<0>.
+
+B<flags> is a bit field of flags which are defined in C<openssl/bn.h>. The
+flags begin with B<BN_FLG_>. The macros BN_set_flags(b, n) and
+BN_get_flags(b, n) exist to enable or fetch flag(s) B<n> from B<BIGNUM>
+structure B<b>.
+
+Various routines in this library require the use of temporary
+B<BIGNUM> variables during their execution. Since dynamic memory
+allocation to create B<BIGNUM>s is rather expensive when used in
+conjunction with repeated subroutine calls, the B<BN_CTX> structure is
+used. This structure contains B<BN_CTX_NUM> B<BIGNUM>s, see
+L<BN_CTX_start(3)>.
+
+=head2 Low-level arithmetic operations
+
+These functions are implemented in C and for several platforms in
+assembly language:
+
+bn_mul_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num> word
+arrays B<rp> and B<ap>. It computes B<ap> * B<w>, places the result
+in B<rp>, and returns the high word (carry).
+
+bn_mul_add_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num>
+word arrays B<rp> and B<ap>. It computes B<ap> * B<w> + B<rp>, places
+the result in B<rp>, and returns the high word (carry).
+
+bn_sqr_words(B<rp>, B<ap>, B<n>) operates on the B<num> word array
+B<ap> and the 2*B<num> word array B<ap>. It computes B<ap> * B<ap>
+word-wise, and places the low and high bytes of the result in B<rp>.
+
+bn_div_words(B<h>, B<l>, B<d>) divides the two word number (B<h>, B<l>)
+by B<d> and returns the result.
+
+bn_add_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
+arrays B<ap>, B<bp> and B<rp>. It computes B<ap> + B<bp>, places the
+result in B<rp>, and returns the high word (carry).
+
+bn_sub_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
+arrays B<ap>, B<bp> and B<rp>. It computes B<ap> - B<bp>, places the
+result in B<rp>, and returns the carry (1 if B<bp> E<gt> B<ap>, 0
+otherwise).
+
+bn_mul_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
+B<b> and the 8 word array B<r>. It computes B<a>*B<b> and places the
+result in B<r>.
+
+bn_mul_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
+B<b> and the 16 word array B<r>. It computes B<a>*B<b> and places the
+result in B<r>.
+
+bn_sqr_comba4(B<r>, B<a>, B<b>) operates on the 4 word arrays B<a> and
+B<b> and the 8 word array B<r>.
+
+bn_sqr_comba8(B<r>, B<a>, B<b>) operates on the 8 word arrays B<a> and
+B<b> and the 16 word array B<r>.
+
+The following functions are implemented in C:
+
+bn_cmp_words(B<a>, B<b>, B<n>) operates on the B<n> word arrays B<a>
+and B<b>. It returns 1, 0 and -1 if B<a> is greater than, equal and
+less than B<b>.
+
+bn_mul_normal(B<r>, B<a>, B<na>, B<b>, B<nb>) operates on the B<na>
+word array B<a>, the B<nb> word array B<b> and the B<na>+B<nb> word
+array B<r>. It computes B<a>*B<b> and places the result in B<r>.
+
+bn_mul_low_normal(B<r>, B<a>, B<b>, B<n>) operates on the B<n> word
+arrays B<r>, B<a> and B<b>. It computes the B<n> low words of
+B<a>*B<b> and places the result in B<r>.
+
+bn_mul_recursive(B<r>, B<a>, B<b>, B<n2>, B<dna>, B<dnb>, B<t>) operates
+on the word arrays B<a> and B<b> of length B<n2>+B<dna> and B<n2>+B<dnb>
+(B<dna> and B<dnb> are currently allowed to be 0 or negative) and the 2*B<n2>
+word arrays B<r> and B<t>. B<n2> must be a power of 2. It computes
+B<a>*B<b> and places the result in B<r>.
+
+bn_mul_part_recursive(B<r>, B<a>, B<b>, B<n>, B<tna>, B<tnb>, B<tmp>)
+operates on the word arrays B<a> and B<b> of length B<n>+B<tna> and
+B<n>+B<tnb> and the 4*B<n> word arrays B<r> and B<tmp>.
+
+bn_mul_low_recursive(B<r>, B<a>, B<b>, B<n2>, B<tmp>) operates on the
+B<n2> word arrays B<r> and B<tmp> and the B<n2>/2 word arrays B<a>
+and B<b>.
+
+BN_mul() calls bn_mul_normal(), or an optimized implementation if the
+factors have the same size: bn_mul_comba8() is used if they are 8
+words long, bn_mul_recursive() if they are larger than
+B<BN_MULL_SIZE_NORMAL> and the size is an exact multiple of the word
+size, and bn_mul_part_recursive() for others that are larger than
+B<BN_MULL_SIZE_NORMAL>.
+
+bn_sqr_normal(B<r>, B<a>, B<n>, B<tmp>) operates on the B<n> word array
+B<a> and the 2*B<n> word arrays B<tmp> and B<r>.
+
+The implementations use the following macros which, depending on the
+architecture, may use "long long" C operations or inline assembler.
+They are defined in C<bn_local.h>.
+
+mul(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<c> and places the
+low word of the result in B<r> and the high word in B<c>.
+
+mul_add(B<r>, B<a>, B<w>, B<c>) computes B<w>*B<a>+B<r>+B<c> and
+places the low word of the result in B<r> and the high word in B<c>.
+
+sqr(B<r0>, B<r1>, B<a>) computes B<a>*B<a> and places the low word
+of the result in B<r0> and the high word in B<r1>.
+
+=head2 Size changes
+
+bn_expand() ensures that B<b> has enough space for a B<bits> bit
+number. bn_wexpand() ensures that B<b> has enough space for an
+B<n> word number. If the number has to be expanded, both macros
+call bn_expand2(), which allocates a new B<d> array and copies the
+data. They return B<NULL> on error, B<b> otherwise.
+
+The bn_fix_top() macro reduces B<a-E<gt>top> to point to the most
+significant nonzero word plus one when B<a> has shrunk.
+
+=head2 Debugging
+
+bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top
+E<lt>= (a)-E<gt>dmax)>. A violation will cause the program to abort.
+
+If B<BN_DEBUG> is not defined, bn_check_top() is
+defined as an empty macro.
+
+=head1 RETURN VALUES
+
+Described above.
+
+=head1 COPYRIGHT
+
+Copyright 2000-2025 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
diff --git a/doc/internal/man3/cms_add1_signing_cert.pod b/doc/internal/man3/cms_add1_signing_cert.pod
new file mode 100644
index 000000000000..cc2747dcde6e
--- /dev/null
+++ b/doc/internal/man3/cms_add1_signing_cert.pod
@@ -0,0 +1,46 @@
+=pod
+
+=head1 NAME
+
+cms_add1_signing_cert, cms_add1_signing_cert_v2
+- add ESS signing-certificate signed attribute to a
+CMS_SignerInfo data structure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc);
+
+ int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc2);
+
+=head1 DESCRIPTION
+
+cms_add1_signing_cert() adds an ESS Signing Certificate I<sc> (version 1) signed
+attribute to the CMS_SignerInfo I<si>.
+cms_add1_signing_cert_v2() adds an ESS Signing Certificate I<sc2> (version 2) signed
+attribute to the CMS_SignerInfo I<si>.
+The ESS Signing Certificate attributes version 1 and 2 are defined in RFC 5035
+which updates Section 5.4 of RFC 2634.
+
+=head1 NOTES
+
+This attribute is mandatory to make a CMS compliant with CAdES-BES
+(European Standard ETSI EN 319 122-1 V1.1.1).
+For a fuller description see L<openssl-cms(1)>).
+
+=head1 RETURN VALUES
+
+cms_add1_signing_cert() and cms_add1_signing_cert_v2() return 1 if attribute
+is added or 0 if an error occurred.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod
new file mode 100644
index 000000000000..b23d2ec0eaa2
--- /dev/null
+++ b/doc/internal/man3/evp_generic_fetch.pod
@@ -0,0 +1,285 @@
+=pod
+
+=head1 NAME
+
+evp_generic_fetch, evp_generic_fetch_by_number, evp_generic_fetch_from_prov
+- generic algorithm fetchers and method creators for EVP
+
+=head1 SYNOPSIS
+
+ /* Only for EVP source */
+ #include "evp_local.h"
+
+ void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
+ const char *name, const char *properties,
+ void *(*new_method)(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *method_data),
+ void *method_data,
+ int (*up_ref_method)(void *),
+ void (*free_method)(void *));
+
+ void *evp_generic_fetch_by_number(OSSL_LIB_CTX *ctx, int operation_id,
+ int name_id, const char *properties,
+ void *(*new_method)(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *method_data),
+ void *method_data,
+ int (*up_ref_method)(void *),
+ void (*free_method)(void *));
+ void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
+ int name_id, const char *properties,
+ void *(*new_method)(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *method_data),
+ void *method_data,
+ int (*up_ref_method)(void *),
+ void (*free_method)(void *));
+
+=head1 DESCRIPTION
+
+evp_generic_fetch() calls ossl_method_construct() with the given
+I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
+it to create an EVP method with the help of the functions
+I<new_method>, I<up_ref_method>, and I<free_method>.
+
+evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(),
+but takes a numeric I<name_id> instead of a name.
+I<name_id> must always be nonzero; as a matter of fact, it being zero
+is considered a programming error.
+This is meant to be used when one method needs to fetch an associated
+method, and is typically called from inside the given function
+I<new_method>.
+
+evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(),
+but limits the search of methods to the provider given with I<prov>.
+This is meant to be used when one method needs to fetch an associated
+method in the same provider.
+
+The three functions I<new_method>, I<up_ref_method>, and
+I<free_method> are supposed to:
+
+=over 4
+
+=item new_method()
+
+creates an internal method from function pointers found in the
+dispatch table I<fns>, with name identity I<name_id>.
+The provider I<prov> and I<method_data> are also passed to be used as
+new_method() sees fit.
+
+=item up_ref_method()
+
+increments the reference counter for the given method, if there is
+one.
+
+=item free_method()
+
+frees the given method.
+
+=back
+
+=head1 RETURN VALUES
+
+evp_generic_fetch() returns a method on success, or NULL on error.
+
+=head1 EXAMPLES
+
+This is a short example of the fictitious EVP API and operation called
+B<EVP_FOO>.
+
+To begin with, let's assume something like this in
+F<include/openssl/core_dispatch.h>:
+
+ #define OSSL_OP_FOO 100
+
+ #define OSSL_FUNC_FOO_NEWCTX_FUNC 2001
+ #define OSSL_FUNC_FOO_INIT 2002
+ #define OSSL_FUNC_FOO_OPERATE 2003
+ #define OSSL_FUNC_FOO_CLEANCTX_FUNC 2004
+ #define OSSL_FUNC_FOO_FREECTX_FUNC 2005
+
+ OSSL_CORE_MAKE_FUNC(void *, foo_newctx, (void))
+ OSSL_CORE_MAKE_FUNC(int, foo_init, (void *vctx))
+ OSSL_CORE_MAKE_FUNC(int, foo_operate, (void *vctx,
+ unsigned char *out, size_t *out_l,
+ unsigned char *in, size_t in_l))
+ OSSL_CORE_MAKE_FUNC(void, foo_cleanctx, (void *vctx))
+ OSSL_CORE_MAKE_FUNC(void, foo_freectx, (void *vctx))
+
+And here's the implementation of the FOO method fetcher:
+
+ /* typedef struct evp_foo_st EVP_FOO */
+ struct evp_foo_st {
+ OSSL_PROVIDER *prov;
+ int name_id;
+ CRYPTO_REF_COUNT refcnt;
+ OSSL_FUNC_foo_newctx_fn *newctx;
+ OSSL_FUNC_foo_init_fn *init;
+ OSSL_FUNC_foo_operate_fn *operate;
+ OSSL_FUNC_foo_cleanctx_fn *cleanctx;
+ OSSL_FUNC_foo_freectx_fn *freectx;
+ };
+
+ /*
+ * In this example, we have a public method creator and destructor.
+ * It's not absolutely necessary, but is in the spirit of OpenSSL.
+ */
+ EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *data)
+ {
+ EVP_FOO *foo = NULL;
+
+ if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
+ return NULL;
+
+ foo->name_id = name_id;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_FOO_NEWCTX:
+ foo->newctx = OSSL_FUNC_foo_newctx(fns);
+ break;
+ case OSSL_FUNC_FOO_INIT:
+ foo->init = OSSL_FUNC_foo_init(fns);
+ break;
+ case OSSL_FUNC_FOO_OPERATE:
+ foo->operate = OSSL_FUNC_foo_operate(fns);
+ break;
+ case OSSL_FUNC_FOO_CLEANCTX:
+ foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
+ break;
+ case OSSL_FUNC_FOO_FREECTX:
+ foo->freectx = OSSL_FUNC_foo_freectx(fns);
+ break;
+ }
+ }
+ foo->prov = prov;
+ if (prov)
+ ossl_provider_up_ref(prov);
+
+ return foo;
+ }
+
+ EVP_FOO_meth_free(EVP_FOO *foo)
+ {
+ if (foo != NULL) {
+ OSSL_PROVIDER *prov = foo->prov;
+
+ OPENSSL_free(foo);
+ ossl_provider_free(prov);
+ }
+ }
+
+ static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov)
+ {
+ return EVP_FOO_meth_from_algorithm(fns, prov);
+ }
+
+ static int foo_up_ref(void *vfoo)
+ {
+ EVP_FOO *foo = vfoo;
+ int ref = 0;
+
+ CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock);
+ return 1;
+ }
+
+ static void foo_free(void *vfoo)
+ {
+ EVP_FOO_meth_free(vfoo);
+ }
+
+ EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
+ const char *name,
+ const char *properties)
+ {
+ EVP_FOO *foo =
+ evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
+ foo_from_algorithm, foo_up_ref, foo_free);
+
+ /*
+ * If this method exists in legacy form, with a constant NID for the
+ * given |name|, this is the spot to find that NID and set it in
+ * the newly constructed EVP_FOO instance.
+ */
+
+ return foo;
+
+ }
+
+And finally, the library functions:
+
+ /* typedef struct evp_foo_st EVP_FOO_CTX */
+ struct evp_foo_ctx_st {
+ const EVP_FOO *foo;
+ void *provctx; /* corresponding provider context */
+ };
+
+ int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
+ {
+ if (c == NULL)
+ return 1;
+ if (c->foo != NULL && c->foo->cleanctx != NULL)
+ c->foo->cleanctx(c->provctx);
+ return 1;
+ }
+
+ EVP_FOO_CTX *EVP_FOO_CTX_new(void)
+ {
+ return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
+ }
+
+ void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
+ {
+ EVP_FOO_CTX_reset(c);
+ c->foo->freectx(c->provctx);
+ OPENSSL_free(c);
+ }
+
+ int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
+ {
+ int ok = 1;
+
+ c->foo = foo;
+ if (c->provctx == NULL)
+ c->provctx = c->foo->newctx();
+
+ ok = c->foo->init(c->provctx);
+
+ return ok;
+ }
+
+ int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
+ const unsigned char *in, size_t inl)
+ {
+ int ok = 1;
+
+ ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
+ return ok;
+ }
+
+=head1 SEE ALSO
+
+L<ossl_method_construct(3)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man3/evp_keymgmt_newdata.pod b/doc/internal/man3/evp_keymgmt_newdata.pod
new file mode 100644
index 000000000000..9b3f2c55f160
--- /dev/null
+++ b/doc/internal/man3/evp_keymgmt_newdata.pod
@@ -0,0 +1,88 @@
+=pod
+
+=head1 NAME
+
+evp_keymgmt_newdata, evp_keymgmt_freedata,
+evp_keymgmt_get_params,
+evp_keymgmt_has, evp_keymgmt_validate,
+evp_keymgmt_import, evp_keymgmt_import_types,
+evp_keymgmt_export, evp_keymgmt_export_types
+- internal KEYMGMT interface functions
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt);
+ void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata);
+ int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt,
+ void *keydata, OSSL_PARAM params[]);
+
+ int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
+ int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection);
+
+ int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection, const OSSL_PARAM params[]);
+ const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
+ int selection);
+ int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
+ int selection, OSSL_CALLBACK *param_cb, void *cbarg);
+ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
+ int selection);
+
+=head1 DESCRIPTION
+
+All these functions are helpers to call the provider's corresponding
+function. They all have in common that they take a B<EVP_KEYMGMT> as
+first argument, which they also retrieve a provider context from when
+needed. The rest of the arguments are simply passed on to the
+function they wrap around.
+
+evp_keymgmt_newdata() calls the method's new() function.
+
+evp_keymgmt_freedata() calls the method's free() function.
+
+(the name evp_keymgmt_freedata() was chosen to avoid a clash with
+EVP_KEYMGMT_free() on case insensitive systems, the name
+evp_keymgmt_newdata() was chosen for consistency)
+
+evp_keymgmt_get_params() calls the method's get_params() function.
+
+evp_keymgmt_has() calls the method's has() function.
+
+evp_keymgmt_validate() calls the method's validate() function.
+
+evp_keymgmt_import() calls the method's import() function.
+
+evp_keymgmt_import_types() calls the method's import_types() function.
+
+evp_keymgmt_export() calls the method's export() function.
+
+evp_keymgmt_export_types() calls the method's export_types() function.
+
+=head1 RETURN VALUES
+
+evp_keymgmt_newdata() returns a pointer to a provider side key object,
+or NULL on error.
+
+evp_keymgmt_import_types(), and evp_keymgmt_export_types() return a parameter
+descriptor for importing and exporting key data, or NULL if there are no such
+descriptors.
+
+All other functions return 1 on success and 0 on error.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-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
diff --git a/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
new file mode 100644
index 000000000000..7099e4496473
--- /dev/null
+++ b/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
@@ -0,0 +1,106 @@
+=pod
+
+=head1 NAME
+
+evp_keymgmt_util_export,
+evp_keymgmt_util_export_to_provider,
+evp_keymgmt_util_find_operation_cache,
+evp_keymgmt_util_clear_operation_cache,
+evp_keymgmt_util_cache_keydata,
+evp_keymgmt_util_cache_keyinfo,
+evp_keymgmt_util_fromdata,
+OP_CACHE_ELEM
+- internal KEYMGMT utility functions
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ typedef struct OP_CACHE_ELEM;
+
+ int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
+ OSSL_CALLBACK *export_cb, void *export_cbarg);
+ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int selection);
+ OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk,
+ EVP_KEYMGMT *keymgmt,
+ int selection);
+ int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking);
+ int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ void *keydata, int selection);
+ void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk);
+ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
+ int selection, const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+evp_keymgmt_util_export() calls L<evp_keymgmt_export(3)> with the
+I<keymgmt> and I<keydata> from I<pk>. This is used as a
+helper for L<EVP_PKEY_todata(3)>.
+
+evp_keymgmt_util_export_to_provider() exports cached key material
+(provider side key material) from the given key I<pk> to a provider
+via a B<EVP_KEYMGMT> interface, if this hasn't already been done.
+It maintains a cache of provider key references in I<pk> to keep track
+of all provider side keys.
+
+To export a legacy key, use L<evp_pkey_export_to_provider(3)> instead,
+as this function ignores any legacy key data.
+
+evp_keymgmt_util_find_operation_cache() finds
+I<keymgmt> in I<pk>'s cache of provided keys for operations.
+It should only be called while holding I<pk>'s lock (read or write).
+
+evp_keymgmt_util_clear_operation_cache() can be used to explicitly
+clear the cache of operation key references. If I<locking> is set to 1 then
+then I<pk>'s lock will be obtained while doing the clear. Otherwise it will be
+assumed that the lock has already been obtained or is not required.
+
+evp_keymgmt_util_cache_keydata() can be used to add a provider key
+object to a B<PKEY>.
+
+evp_keymgmt_util_cache_keyinfo() can be used to get all kinds of
+information from the provvider "origin" and save it in I<pk>'s
+information cache.
+
+evp_keymgmt_util_fromdata() can be used to add key object data to a
+given key I<target> via a B<EVP_KEYMGMT> interface. This is used as a
+helper for L<EVP_PKEY_fromdata(3)>.
+
+In all functions that take a I<selection> argument, the selection is used to
+constraint the information requested on export. It is also used in the cache
+so that key data is guaranteed to contain all the information requested in
+the selection.
+
+=head1 RETURN VALUES
+
+evp_keymgmt_export_to_provider() and evp_keymgmt_util_fromdata()
+return a pointer to the appropriate provider side key (created or
+found again), or NULL on error.
+
+evp_keymgmt_util_find_operation_cache() returns a pointer to the
+operation cache slot. If I<keymgmt> is NULL, or if there is no slot
+with a match for I<keymgmt>, NULL is returned.
+
+evp_keymgmt_util_cache_keydata() and evp_keymgmt_util_clear_operation_cache()
+return 1 on success or 0 otherwise.
+
+=head1 NOTES
+
+"Legacy key" is the term used for any key that has been assigned to an
+B<EVP_PKEY> with EVP_PKEY_assign_RSA() and similar functions.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_ASN1_METHOD(3)>, L<EVP_PKEY_assign_RSA(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man3/evp_md_get_number.pod b/doc/internal/man3/evp_md_get_number.pod
new file mode 100644
index 000000000000..1f913551aad6
--- /dev/null
+++ b/doc/internal/man3/evp_md_get_number.pod
@@ -0,0 +1,112 @@
+=pod
+
+=head1 NAME
+
+ossl_decoder_get_number, evp_md_get_number, evp_cipher_get_number,
+evp_mac_get_number, evp_rand_get_number, evp_keymgmt_get_number,
+evp_signature_get_number, evp_asym_cipher_get_number, evp_kem_get_number,
+evp_keyexch_get_number, evp_kdf_get_number, ossl_encoder_get_number,
+ossl_store_loader_get_number - EVP get internal identification numbers
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher);
+ int evp_cipher_get_number(const EVP_CIPHER *e);
+ int evp_kdf_get_number(const EVP_KDF *kdf);
+ int evp_kem_get_number(const EVP_KEM *kem);
+ int evp_keyexch_get_number(const EVP_KEYEXCH *exchange);
+ int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt);
+ int evp_mac_get_number(const EVP_MAC *mac);
+ int evp_md_get_number(const EVP_MD *md);
+ int evp_rand_get_number(const EVP_RAND *rand);
+ int evp_signature_get_number(const EVP_SIGNATURE *signature);
+ int ossl_decoder_get_number(const OSSL_DECODER *decoder);
+ int ossl_encoder_get_number(const OSSL_ENCODER *encoder);
+ int ossl_store_loader_get_number(const OSSL_STORE_LOADER *loader);
+
+=head1 DESCRIPTION
+
+All provided algorithms get an associated integer identification number.
+This number is dynamic and should be expected to vary from run to run.
+These numbers should only be considered to be unique per provider per
+library context.
+
+=over 4
+
+=item evp_asym_cipher_get_number()
+
+Returns the internal dynamic number assigned to I<cipher>.
+
+=item evp_cipher_get_number()
+
+Returns the internal dynamic number assigned to the I<cipher>. This is only
+useful with fetched B<EVP_CIPHER>s.
+
+=item evp_kdf_get_number()
+
+Keturns the internal dynamic number assigned to I<kdf>.
+
+=item evp_kem_get_number()
+
+Returns the internal dynamic number assigned to I<kem>.
+
+=item evp_keyexch_get_number()
+
+Returns the internal dynamic number assigned to the I<exchange>.
+
+=item evp_keymgmt_get_number()
+
+Returns the internal dynamic number assigned to the I<keymgmt>.
+
+=item evp_mac_get_number()
+
+Returns the internal dynamic number assigned to I<mac>.
+
+=item evp_md_get_number()
+
+Returns the internal dynamic number assigned to the I<md>. This is
+only useful with fetched B<EVP_MD>s.
+
+=item evp_rand_get_number()
+
+Returns the internal dynamic number assigned to I<rand>.
+
+=item evp_signature_get_number()
+
+Returns the internal dynamic number assigned to I<signature>.
+
+=item ossl_decoder_get_number()
+
+Returns the internal dynamic number assigned to the given I<decoder>.
+
+=item ossl_encoder_get_number()
+
+Returns the internal dynamic number assigned to the given I<encoder>.
+
+=item ossl_store_loader_get_number()
+
+Returns the internal dynamic number assigned to the given I<loader>.
+
+=back
+
+=head1 RETURN VALUES
+
+All of these functions return the provider specific identification number
+for the specified algorithm.
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2021 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
diff --git a/doc/internal/man3/evp_pkey_export_to_provider.pod b/doc/internal/man3/evp_pkey_export_to_provider.pod
new file mode 100644
index 000000000000..44efbbe2668f
--- /dev/null
+++ b/doc/internal/man3/evp_pkey_export_to_provider.pod
@@ -0,0 +1,80 @@
+=pod
+
+=head1 NAME
+
+evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_get_legacy
+- internal EVP_PKEY support functions for providers
+
+=head1 SYNOPSIS
+
+ /* Only for EVP source */
+ #include "evp_local.h"
+
+ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
+ EVP_KEYMGMT **keymgmt,
+ const char *propquery);
+ int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
+ void *evp_pkey_get_legacy(EVP_PKEY *pk);
+
+=head1 DESCRIPTION
+
+This manual uses the term "origin", which is explained in internal
+L<EVP_PKEY(7)>.
+
+evp_pkey_export_to_provider() exports the "origin" key contained in I<pk>
+to its operation cache to make it suitable for an B<EVP_KEYMGMT> given either
+with I<*keymgmt> or with an implicit fetch using I<libctx> (NULL means the
+default context), the name of the legacy type of I<pk>, and the I<propquery>
+(NULL means the default property query settings).
+
+If I<keymgmt> isn't NULL but I<*keymgmt> is, and the "origin" was successfully
+exported, then I<*keymgmt> is assigned the implicitly fetched B<EVP_KEYMGMT>.
+
+evp_pkey_copy_downgraded() makes a copy of I<src> in legacy form into I<*dest>,
+if there's a corresponding legacy implementation. This should be used if the
+use of a downgraded key is temporary.
+For example, L<PEM_write_bio_PrivateKey_traditional(3)> uses this to try its
+best to get "traditional" PEM output even if the input B<EVP_PKEY> has a
+provider-native internal key.
+
+evp_pkey_get_legacy() obtains and returns a legacy key structure. If the
+EVP_PKEY already contains a legacy key then it is simply returned. If it is a
+provider based key, then a new legacy key is constructed based on the provider
+key. The legacy key is cached inside the EVP_PKEY and its value returned from
+this function. Subsequent calls to evp_pkey_get_legacy() will return the cached
+key. Subsequent changes to the provider key are not reflected back in the
+legacy key. Similarly changes to the legacy key are not reflected back in the
+provider key.
+
+=head1 RETURN VALUES
+
+evp_pkey_export_to_provider() returns the provider key data if there was any
+allocated. It also either sets I<*keymgmt> to the B<EVP_KEYMGMT> associated
+with the returned key data, or NULL on error.
+
+evp_pkey_get_legacy() returns the legacy key or NULL on error.
+
+=head1 NOTES
+
+Some functions calling evp_pkey_export_to_provider() may have received a const
+key, and may therefore have to cast the key to non-const form to call this
+function. Since B<EVP_PKEY> is always dynamically allocated, this is OK.
+
+=head1 SEE ALSO
+
+L<OSSL_LIB_CTX(3)>, L<EVP_KEYMGMT(3)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020-2021 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
diff --git a/doc/internal/man3/evp_pkey_get1_ED25519.pod b/doc/internal/man3/evp_pkey_get1_ED25519.pod
new file mode 100644
index 000000000000..37b41e459166
--- /dev/null
+++ b/doc/internal/man3/evp_pkey_get1_ED25519.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+evp_pkey_get1_ED25519, evp_pkey_get1_ED448,
+evp_pkey_get1_X25519, evp_pkey_get1_X448
+- internal ECX from EVP_PKEY getter functions
+
+=head1 SYNOPSIS
+
+ #include "internal/evp.h"
+
+ ECX_KEY *evp_pkey_get1_ED25519(EVP_PKEY *pkey);
+ ECX_KEY *evp_pkey_get1_ED448(EVP_PKEY *pkey);
+ ECX_KEY *evp_pkey_get1_X25519(EVP_PKEY *pkey);
+ ECX_KEY *evp_pkey_get1_X448(EVP_PKEY *pkey);
+
+=head1 DESCRIPTION
+
+evp_pkey_get1_ED25519(), evp_pkey_get1_ED448(), evp_pkey_get1_X25519() and
+evp_pkey_get1_X448() return the referenced key in I<pkey> or NULL if the key
+is not of the correct type. The returned key must be freed after use.
+
+=head1 RETURN VALUES
+
+evp_pkey_get1_ED25519(), evp_pkey_get1_ED448(), evp_pkey_get1_X25519() and
+evp_pkey_get1_X448() return the referenced key or NULL if an error
+occurred.
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 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
diff --git a/doc/internal/man3/ossl_DER_w_begin_sequence.pod b/doc/internal/man3/ossl_DER_w_begin_sequence.pod
new file mode 100644
index 000000000000..b78056f6e121
--- /dev/null
+++ b/doc/internal/man3/ossl_DER_w_begin_sequence.pod
@@ -0,0 +1,48 @@
+=pod
+
+=head1 NAME
+
+ossl_DER_w_begin_sequence, ossl_DER_w_end_sequence
+- internal DER writers for DER constructed elements
+
+=head1 SYNOPSIS
+
+ #include "internal/der.h"
+
+ int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag);
+ int ossl_DER_w_end_sequence(WPACKET *pkt, int tag);
+
+=head1 DESCRIPTION
+
+All functions described here are wrappers for constructed structures,
+i.e. the ASN.1 SEQUENCE, SET and CHOICE specifications. They all come
+in pairs, as noted by the function names containing the words C<begin>
+and B<end>.
+
+When using these, special care must be taken to ensure that the ASN.1 tag
+value I<tag> is the same in the matching C<begin> and C<end> function calls.
+
+ossl_DER_w_begin_sequence() and ossl_DER_w_end_sequence() begins and ends a
+SEQUENCE.
+
+=head1 RETURN VALUES
+
+All the functions return 1 on success and 0 on failure. Failure may
+mean that the buffer held by the I<pkt> is too small, but may also
+mean that the values given to the functions are invalid, such as the provided
+I<tag> value being too large for the implementation.
+
+=head1 SEE ALSO
+
+L<DERlib(7)>
+
+=head1 COPYRIGHT
+
+Copyright 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
diff --git a/doc/internal/man3/ossl_DER_w_bn.pod b/doc/internal/man3/ossl_DER_w_bn.pod
new file mode 100644
index 000000000000..49644ffd058f
--- /dev/null
+++ b/doc/internal/man3/ossl_DER_w_bn.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+ossl_DER_w_boolean, ossl_DER_w_uint32, ossl_DER_w_bn, ossl_DER_w_null,
+ossl_DER_w_octet_string, ossl_DER_w_octet_string_uint32
+- internal DER writers for DER primitives
+
+=head1 SYNOPSIS
+
+ #include "internal/der.h"
+
+ int ossl_DER_w_boolean(WPACKET *pkt, int tag, int b);
+ int ossl_DER_w_uint32(WPACKET *pkt, int tag, uint32_t v);
+ int ossl_DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v);
+ int ossl_DER_w_null(WPACKET *pkt, int tag);
+ int ossl_DER_w_octet_string(WPACKET *pkt, int tag,
+ const unsigned char *data, size_t data_n);
+ int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value);
+
+=head1 DESCRIPTION
+
+All functions described here behave the same way, they prepend
+(remember that DER writers are used backwards) the DER encoding of
+their respective value to the already written output buffer held by
+I<pkt>.
+
+ossl_DER_w_boolean() writes the primitive BOOLEAN using the value I<b>.
+Any value that evaluates as true will render a B<true> BOOLEAN,
+otherwise a B<false> BOOLEAN.
+
+ossl_DER_w_uint32() and ossl_DER_w_bn() both write the primitive INTEGER using
+the value I<v>.
+
+=for comment Other similar functions for diverse C integers should be
+added.
+
+ossl_DER_w_null() writes the primitive NULL.
+
+ossl_DER_w_octet_string() writes the primitive OCTET STRING using the bytes
+from I<data> with a length of I<data_n>.
+
+ossl_DER_w_octet_string_uint32() writes the primitive OCTET STRING using a
+32 bit value in I<value>.
+
+=head1 RETURN VALUES
+
+All the functions return 1 on success and 0 on failure. Failure may
+mean that the buffer held by the I<pkt> is too small, but may also
+mean that the values given to the functions are invalid, such as the provided
+I<tag> value being too large for the implementation.
+
+=head1 SEE ALSO
+
+L<DERlib(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2020-2022 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
diff --git a/doc/internal/man3/ossl_DER_w_precompiled.pod b/doc/internal/man3/ossl_DER_w_precompiled.pod
new file mode 100644
index 000000000000..aa7fa3930f89
--- /dev/null
+++ b/doc/internal/man3/ossl_DER_w_precompiled.pod
@@ -0,0 +1,48 @@
+=pod
+
+=head1 NAME
+
+ossl_DER_w_precompiled
+- internal DER writers for precompiled DER blobs
+
+=head1 SYNOPSIS
+
+ #include "internal/der.h"
+
+ int ossl_DER_w_precompiled(WPACKET *pkt, int tag,
+ const unsigned char *precompiled,
+ size_t precompiled_n);
+
+=head1 DESCRIPTION
+
+There may be already existing DER blobs that can simply be copied to
+the buffer held by I<pkt>. For example, precompiled values, such as
+OIDs (for example, C<id-sha256>) or complete AlgorithmIdentifiers
+(for example, C<sha256Identifier>). To add those as an element in a
+structure being DER encoded, use ossl_DER_w_precompiled().
+
+ossl_DER_w_precompiled() will simply take the DER encoded blob given as
+I<precompiled> with length I<precompiled_n> and add it to the buffer
+held by I<pkt>.
+
+=head1 RETURN VALUES
+
+ossl_DER_w_precompiled() returns 1 on success and 0 on failure. Failure
+may mean that the buffer held by the I<pkt> is too small, but may also
+mean that the values given to the functions are invalid, such as the provided
+I<tag> value being too large for the implementation.
+
+=head1 SEE ALSO
+
+L<DERlib(7)>
+
+=head1 COPYRIGHT
+
+Copyright 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
diff --git a/doc/internal/man3/ossl_algorithm_do_all.pod b/doc/internal/man3/ossl_algorithm_do_all.pod
new file mode 100644
index 000000000000..7a321d492a04
--- /dev/null
+++ b/doc/internal/man3/ossl_algorithm_do_all.pod
@@ -0,0 +1,63 @@
+=pod
+
+=head1 NAME
+
+ossl_algorithm_do_all - generic algorithm implementation iterator
+
+=head1 SYNOPSIS
+
+ void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id,
+ OSSL_PROVIDER *provider,
+ void (*fn)(OSSL_PROVIDER *provider,
+ const OSSL_ALGORITHM *algo,
+ int no_store, void *data),
+ void *data);
+
+=head1 DESCRIPTION
+
+ossl_algorithm_do_all() looks up every algorithm it can find, given a
+library context I<libctx>, an operation identity I<operation_id> and a
+provider I<provider>.
+I<libctx> may be NULL to signify that the default library context should
+be used.
+I<operation_id> may be zero to signify that all kinds of operations
+will be looked up.
+I<provider> may be NULL to signify that all loaded providers will be
+queried.
+
+For each implementation found, the function I<fn> is called with the
+I<provider> for the implementation, the algorithm descriptor I<algo>,
+the flag I<no_store> indicating whether the algorithm descriptor may
+be remembered or not, and the caller I<data> that was passed to
+ossl_algorithm_do_all().
+
+=head1 RETURN VALUES
+
+ossl_algorithm_do_all() doesn't return any value.
+
+=head1 NOTES
+
+The function described here are mainly useful for discovery, and
+possibly display of what has been discovered, for example an
+application that wants to display the loaded providers and what they
+may offer, but also for constructors, such as
+L<ossl_method_construct(3)>.
+
+=head1 SEE ALSO
+
+L<ossl_method_construct(3)>, L<EVP_MAC_do_all_provided(3)>
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-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
diff --git a/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod b/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod
new file mode 100644
index 000000000000..97304ee40d92
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod
@@ -0,0 +1,44 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_X509_STORE_add1_certs,
+ossl_cmp_X509_STORE_get1_certs
+- functions manipulating stores of certificates
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp_util.h>
+
+ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
+ int only_self_signed);
+ STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store);
+
+=head1 DESCRIPTION
+
+ossl_cmp_X509_STORE_add1_certs() adds all or only self-signed certificates from
+the given stack to given store. The I<certs> parameter may be NULL.
+
+ossl_cmp_X509_STORE_get1_certs() retrieves a copy of all certificates in the
+given store.
+
+=head1 RETURN VALUES
+
+ossl_cmp_X509_STORE_add1_certs() returns 1 on success, 0 on error.
+
+ossl_cmp_X509_STORE_get1_certs() returns a list of certificates, NULL on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-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
diff --git a/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod
new file mode 100644
index 000000000000..a154cda1c989
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_asn1_octet_string_set1,
+ossl_cmp_asn1_octet_string_set1_bytes
+- ASN.1 octet string utility functions
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
+ const ASN1_OCTET_STRING *src);
+ int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
+ const unsigned char *bytes, int len);
+
+=head1 DESCRIPTION
+
+ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable
+referenced via the I<tgt> argument and assigns either a copy of
+the ASN1_OCTET_STRING given as the I<src> argument or NULL.
+
+ossl_cmp_asn1_octet_string_set1_bytes() frees any previous value of the variable
+referenced via the I<tgt> argument and assigns either a copy of the given byte
+string (with the given length) or NULL.
+
+=head1 RETURN VALUES
+
+All functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-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
diff --git a/doc/internal/man3/ossl_cmp_certreq_new.pod b/doc/internal/man3/ossl_cmp_certreq_new.pod
new file mode 100644
index 000000000000..37a234066d36
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_certreq_new.pod
@@ -0,0 +1,178 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_certreq_new,
+ossl_cmp_certrep_new,
+ossl_cmp_rr_new,
+ossl_cmp_rp_new,
+ossl_cmp_certConf_new,
+ossl_cmp_pkiconf_new,
+ossl_cmp_pollReq_new,
+ossl_cmp_pollRep_new,
+ossl_cmp_genm_new,
+ossl_cmp_genp_new,
+ossl_cmp_error_new
+- functions for generating CMP messages
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ OSSL_ossl_cmp_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int bodytype,
+ const OSSL_CRMF_MSG *crm);
+ OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype,
+ int certReqId, const OSSL_CMP_PKISI *si,
+ X509 *cert, const X509 *encryption_recip,
+ STACK_OF(X509) *chain, STACK_OF(X509) *caPubs,
+ int unprotectedErrors);
+ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
+ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
+ const OSSL_CRMF_CERTID *cid,
+ int unprotectedErrors);
+ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId,
+ int fail_info, const char *text);
+ OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx);
+ OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid);
+ OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, int poll_after);
+ OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx);
+ OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx);
+ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si,
+ int64_t errorCode, const char *details,
+ int unprotected);
+
+=head1 DESCRIPTION
+
+This is the internal API for creating various CMP PKIMESSAGES.
+All functions are based on L<ossl_cmp_msg_create(3)>.
+The allocate a new message, fill it with the relevant data derived from
+the given B<OSSL_CMP_CTX>, and create the applicable protection.
+
+ossl_cmp_certreq_new() creates a PKIMessage for requesting a certificate,
+which can be either of IR/CR/KUR/P10CR, depending on the given I<bodytype>.
+The CRMF message to use may be given explicitly via a non-NULL I<crm> argument,
+otherwise it is created from the information in the I<ctx>.
+
+Available CMP certificate request PKIMessage I<bodytype>s are:
+
+=over 4
+
+=item * B<OSSL_CMP_PKIBODY_IR> - Initialization Request
+
+=item * B<OSSL_CMP_PKIBODY_CR> - Certification Request
+
+=item * B<OSSL_CMP_PKIBODY_P10CR> - PKCS#10 Certification Request
+
+=item * B<OSSL_CMP_PKIBODY_KUR> - Key Update Request
+
+=back
+
+ossl_cmp_certrep_new() creates a PKIMessage for certificate response,
+which can be either of IP/CP/KUP, depending on the given I<bodytype>,
+with the given I<certReqId> and I<si> values and optionally with I<cert>,
+I<chain>, and I<caPubs>. The I<cert>, I<chain>, and I<caPubs> arguments
+are not consumed if present but their internal reference counter is increased.
+The I<encryption_recip> is currently unsupported.
+The function does not protect the message if the B<status> value in I<si>
+is B<rejected> and I<unprotectedErrors> is nonzero.
+
+Available CMP certificate response PKIMessage I<bodytype>s are:
+
+=over 4
+
+=item * B<OSSL_CMP_PKIBODY_IP> - Initialization Response
+
+=item * B<OSSL_CMP_PKIBODY_CP> - Certification Response
+
+=item * B<OSSL_CMP_PKIBODY_KUP> - Key Update Response
+
+=back
+
+The list of all CMP PKIMessage I<bodytype>s is:
+
+ #define OSSL_CMP_PKIBODY_IR 0
+ #define OSSL_CMP_PKIBODY_IP 1
+ #define OSSL_CMP_PKIBODY_CR 2
+ #define OSSL_CMP_PKIBODY_CP 3
+ #define OSSL_CMP_PKIBODY_P10CR 4
+ #define OSSL_CMP_PKIBODY_POPDECC 5
+ #define OSSL_CMP_PKIBODY_POPDECR 6
+ #define OSSL_CMP_PKIBODY_KRR 9
+ #define OSSL_CMP_PKIBODY_KRP 10
+ #define OSSL_CMP_PKIBODY_RR 11
+ #define OSSL_CMP_PKIBODY_RP 12
+ #define OSSL_CMP_PKIBODY_CCR 13
+ #define OSSL_CMP_PKIBODY_CCP 14
+ #define OSSL_CMP_PKIBODY_CKUANN 15
+ #define OSSL_CMP_PKIBODY_CANN 16
+ #define OSSL_CMP_PKIBODY_RANN 17
+ #define OSSL_CMP_PKIBODY_CRLANN 18
+ #define OSSL_CMP_PKIBODY_PKICONF 19
+ #define OSSL_CMP_PKIBODY_NESTED 20
+ #define OSSL_CMP_PKIBODY_GENM 21
+ #define OSSL_CMP_PKIBODY_GENP 22
+ #define OSSL_CMP_PKIBODY_ERROR 23
+ #define OSSL_CMP_PKIBODY_CERTCONF 24
+ #define OSSL_CMP_PKIBODY_POLLREQ 25
+ #define OSSL_CMP_PKIBODY_POLLREP 26
+
+ossl_cmp_rr_new() creates a Revocation Request message from the
+information set via OSSL_CMP_CTX_set1_oldClCert().
+
+ossl_cmp_rp_new() creates a Revocation Response message with I<si> and I<cid>.
+It does not protect the message if the B<status> value in I<si> is B<rejected>
+and I<unprotectedErrors> is nonzero.
+
+ossl_cmp_certConf_new() creates a Certificate Confirmation message for the last
+received certificate with the given I<certReqId>.
+The PKIStatus defaults to B<accepted> if the I<fail_info> bit field is 0.
+Otherwise it is taken as the failInfo of the PKIStatusInfo, PKIStatus is
+set to B<rejected>, and I<text> is copied to statusString unless it is NULL.
+
+ossl_cmp_pkiconf_new() creates a PKI Confirmation message.
+
+ossl_cmp_pollReq_new() creates a Polling Request message with certReqId set to
+I<crid>.
+
+ossl_cmp_pollRep_new() creates a Polling Response message with certReqId set to
+I<crid> and pollAfter to I<poll_after>.
+
+ossl_cmp_genm_new() creates a new General Message with an empty ITAV stack.
+
+ossl_cmp_genp_new() creates a new General Response with an empty ITAV stack.
+
+ossl_cmp_error_new() creates a new Error Message with the given contents
+I<si>, I<errorCode>, and optional I<details>.
+If I<errorCode> is positive and in the range of an OpenSSL error code,
+the library and reason strings are included in the B<errorDetails> field.
+If given, the I<details> are added to the contents of the B<errorDetails> field.
+The function does not protect the message if I<unprotectedErrors> is nonzero.
+
+=head1 NOTES
+
+CMP is specified in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+All of the functions return a new OSSL_CMP_MSG structure containing
+the generated message on success, or NULL on error.
+
+=head1 SEE ALSO
+
+L<ossl_cmp_msg_create(3)>,
+L<OSSL_CMP_CTX_new(3)>, L<ERR_load_strings(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2023 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
diff --git a/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod b/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod
new file mode 100644
index 000000000000..f3c45ed56c65
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_ctx_set1_caPubs,
+ossl_cmp_ctx_set0_validatedSrvCert,
+ossl_cmp_ctx_set_status,
+ossl_cmp_ctx_set0_statusString,
+ossl_cmp_ctx_set_failInfoCode,
+ossl_cmp_ctx_set0_newCert,
+ossl_cmp_ctx_set1_extraCertsIn,
+ossl_cmp_ctx_set1_recipNonce
+- internal functions for managing the CMP client context datastructure
+
+=head1 SYNOPSIS
+
+ #include <openssl/cmp.h>
+
+ int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs);
+ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert);
+ int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status);
+ int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx,
+ OSSL_CMP_PKIFREETEXT *text);
+ int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info);
+ int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert);
+ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
+ STACK_OF(X509) *extraCertsIn);
+ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
+ const ASN1_OCTET_STRING *nonce);
+
+=head1 DESCRIPTION
+
+ossl_cmp_ctx_set1_caPubs() copies the given stack of CA certificates
+to the caPubs field of the context.
+The reference counts of those certificates handled successfully are increased.
+
+ossl_cmp_ctx_set0_validatedSrvCert() sets the validatedSrvCert of the context,
+which caches any already validated server cert, or NULL if not available.
+
+ossl_cmp_ctx_set_status() sets the status field of the context.
+
+ossl_cmp_ctx_set0_statusString() sets the statusString field of the context.
+
+ossl_cmp_ctx_set_failInfoCode() sets the error code bits in the failInfoCode
+field of the context based on the given OSSL_CMP_PKIFAILUREINFO structure.
+
+ossl_cmp_ctx_set0_newCert() sets the given (newly enrolled) certificate
+in the context.
+
+ossl_cmp_ctx_set1_extraCertsIn() sets the extraCertsIn field of the context.
+The reference counts of those certificates handled successfully are increased.
+
+ossl_cmp_ctx_set1_recipNonce() sets the given recipient nonce in the context.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+All functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2018 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
diff --git a/doc/internal/man3/ossl_cmp_hdr_init.pod b/doc/internal/man3/ossl_cmp_hdr_init.pod
new file mode 100644
index 000000000000..a0804aa4cf2a
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_hdr_init.pod
@@ -0,0 +1,151 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_hdr_set_pvno,
+ossl_cmp_hdr_get_pvno,
+ossl_cmp_hdr_get_protection_nid,
+ossl_cmp_hdr_get0_sendernonce,
+ossl_cmp_general_name_is_NULL_DN,
+ossl_cmp_hdr_set1_sender,
+ossl_cmp_hdr_set1_recipient,
+ossl_cmp_hdr_update_messagetime,
+ossl_cmp_hdr_set1_senderKID,
+ossl_cmp_hdr_push0_freeText,
+ossl_cmp_hdr_push1_freeText,
+ossl_cmp_hdr_generalinfo_item_push0,
+ossl_cmp_hdr_generalinfo_items_push1,
+ossl_cmp_hdr_set_implicitConfirm,
+ossl_cmp_hdr_has_implicitConfirm,
+ossl_cmp_hdr_set_transactionID,
+ossl_cmp_hdr_init
+- functions handling CMP message headers
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
+ int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr);
+ ASN1_OCTET_STRING
+ *ossl_cmp_hdr_get0_sendernonce(const OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name);
+
+ int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
+ int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
+ int ossl_cmp_hdr_update_messagetime(OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
+ const ASN1_OCTET_STRING *senderKID);
+ int ossl_cmp_hdr_generalinfo_item_push0(OSSL_CMP_PKIHEADER *hdr,
+ OSSL_CMP_ITAV *itav);
+ int ossl_cmp_hdr_generalinfo_items_push1(OSSL_CMP_PKIHEADER *hdr,
+ STACK_OF(OSSL_CMP_ITAV) *itavs);
+ int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr,
+ ASN1_UTF8STRING *text);
+ int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr,
+ ASN1_UTF8STRING *text);
+ int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_has_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
+ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
+
+=head1 DESCRIPTION
+
+ossl_cmp_hdr_set_pvno() sets hdr->pvno to the given B<pvno>.
+
+ossl_cmp_hdr_get_pvno() returns the pvno of the given B<hdr> or -1 on error.
+
+ossl_cmp_hdr_get_protection_nid returns the NID of the protection algorithm
+in B<hdr> or NID_undef on error.
+
+ossl_cmp_hdr_get0_sendernonce() returns the sender nonce of the given PKIHeader.
+
+ossl_cmp_general_name_is_NULL_DN() determines if the given GENERAL_NAME
+is the NULL-DN.
+
+ossl_cmp_hdr_set1_sender() sets the sender field in the given PKIHeader
+to the given X509 Name value, without consuming the pointer.
+
+ossl_cmp_hdr_set1_recipient() sets the recipient field in the given
+PKIHeader to the given X509 Name value, without consuming the pointer.
+If B<nm> is NULL, recipient is set to the NULL DN (the empty list of strings).
+
+ossl_cmp_hdr_update_messagetime() (re-)sets the messageTime to the current
+system time. As written in RFC 4210, section 5.1.1:
+The messageTime field contains the time at which the sender created the message.
+This may be useful to allow end entities to correct/check their local time for
+consistency with the time on a central system.
+
+ossl_cmp_hdr_set1_senderKID() Sets hdr->senderKID to the given string.
+In an PBMAC-protected IR this usually is a reference number issued by the CA,
+else the subject key ID of the sender's protecting certificate.
+
+ossl_cmp_hdr_push0_freeText() pushes an ASN1_UTF8STRING to
+hdr->freeText and consumes the given pointer.
+
+ossl_cmp_hdr_push1_freeText() pushes an ASN1_UTF8STRING to
+hdr->freeText and does not consume the pointer.
+
+ossl_cmp_hdr_generalinfo_item_push0() adds the given InfoTypeAndValue
+item to the hdr->generalInfo stack. Consumes the B<itav> pointer.
+
+ossl_cmp_hdr_generalinfo_items_push1() adds a copy of the B<itavs> stack to
+the generalInfo field of PKIheader of the B<hdr>. Does not consume the B<itavs>
+pointer.
+
+ossl_cmp_hdr_set_implicitConfirm() sets implicitConfirm in the generalInfo field
+of the PKIMessage header.
+
+ossl_cmp_hdr_has_implicitConfirm() returns 1 if implicitConfirm is
+set int generalInfo field of the given PKIMessage header, 0 if not.
+
+ossl_cmp_hdr_set_transactionID() sets the B<transactionID> field in C<hdr>.
+In case ctx->transactionID is NULL, it starts a new transaction
+by creating and storing a new random valuee with 128 bits length.
+
+ossl_cmp_hdr_init() initializes a PKIHeader structure based on the
+values in the given OSSL_CMP_CTX structure.
+This starts a new transaction in case ctx->transactionID is NULL.
+The sender name is copied from the subject of the client cert, if any,
+or else from the subject name provided for certification requests.
+As required by RFC 4210 section 5.1.1., if the sender name is not known
+to the client it set to the NULL-DN. In this case for identification at least
+the senderKID must be set, which we take from any referenceValue provided.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+ossl_cmp_hdr_get_pvno() returns the pvno of the given B<hdr> or -1 on error.
+
+ossl_cmp_hdr_get_protection_nid returns the respective NID, NID_undef on error.
+
+ossl_cmp_hdr_get0_sendernonce() returns the respective nonce, or NULL.
+
+ossl_cmp_general_name_is_NULL_DN() returns 1 given a NULL-DN, else 0.
+
+All other functions return 1 on success, 0 on error.
+
+See the individual functions above.
+
+=head1 SEE ALSO
+
+L<ossl_cmp_msg_create(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2021 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
diff --git a/doc/internal/man3/ossl_cmp_mock_srv_new.pod b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
new file mode 100644
index 000000000000..7bc449a84352
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_mock_srv_new.pod
@@ -0,0 +1,89 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_mock_srv_new,
+ossl_cmp_mock_srv_free,
+ossl_cmp_mock_srv_set1_certOut,
+ossl_cmp_mock_srv_set1_chainOut,
+ossl_cmp_mock_srv_set1_caPubsOut,
+ossl_cmp_mock_srv_set_statusInfo,
+ossl_cmp_mock_srv_set_sendError,
+ossl_cmp_mock_srv_set_pollCount,
+ossl_cmp_mock_srv_set_checkAfterTime
+- functions used for testing with CMP mock server
+
+=head1 SYNOPSIS
+
+ #include "apps/cmp_mock_srv.h"
+
+ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq);
+ void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
+
+ int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
+ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *chain);
+ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
+ STACK_OF(X509) *caPubs);
+ int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
+ int fail_info, const char *text);
+ int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype);
+ int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
+ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
+
+=head1 DESCRIPTION
+
+ossl_cmp_mock_srv_new() allocates the contexts for the CMP mock server
+associated with the library context I<libctx> and property query string
+I<propq>, both of which may be NULL to select the defaults.
+
+ossl_cmp_mock_srv_free() deallocates the contexts for the CMP mock server.
+
+ossl_cmp_mock_srv_set1_certOut() sets the certificate to be returned in
+cp/ip/kup.
+
+ossl_cmp_mock_srv_set1_chainOut() sets the certificate chain to be added to
+the extraCerts in a cp/ip/kup.
+It should be useful for the validation of the certificate given via
+ossl_cmp_mock_srv_set1_certOut().
+
+ossl_cmp_mock_srv_set1_caPubsOut() sets the caPubs to be returned in an ip.
+
+ossl_cmp_mock_srv_set_statusInfo() sets the status info to be returned.
+
+ossl_cmp_mock_srv_set_sendError() enables enforcement of error responses
+for requests of the given I<bodytype>, or for all requests if I<bodytype> is 1.
+A I<bodytype> of -1 can be used to disable this feature, which is the default.
+
+ossl_cmp_mock_srv_set_pollCount() sets the number of polls before cert response.
+
+ossl_cmp_mock_srv_set_checkAfterTime() sets the number of seconds
+the client should wait for the next poll.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+ossl_cmp_mock_srv() returns a B<OSSL_CMP_SRV_CTX> structure on success,
+NULL on error.
+
+ossl_cmp_mock_srv_free() does not return a value.
+
+All other functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2023 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
diff --git a/doc/internal/man3/ossl_cmp_msg_check_update.pod b/doc/internal/man3/ossl_cmp_msg_check_update.pod
new file mode 100644
index 000000000000..4e7a9224afdd
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_msg_check_update.pod
@@ -0,0 +1,95 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_allow_unprotected_cb_t,
+ossl_cmp_msg_check_update
+- generic checks on a received CMP message, updating the context
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
+ const OSSL_CMP_MSG *msg,
+ int invalid_protection, int arg);
+
+ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
+ ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
+
+=head1 DESCRIPTION
+
+ossl_cmp_msg_check_update() does all generic checks on the given message B<msg>,
+which may be a server response or a request by some client,
+and updates the B<ctx> accordingly.
+
+The B<msg> is checked for the following:
+
+=over 4
+
+=item its sender is of appropriate type (currently only B<X509_NAME>)
+ and matches any expected sender or srvCert subject given in B<ctx>,
+
+=item its protection is present and valid (or a callback function B<cb>
+is present and indicates that a missing or invalid protection is acceptable),
+
+=item its CMP protocol version is acceptable, namely B<OSSL_CMP_PVNO>,
+
+=item its body type is valid,
+
+=item its transaction ID matches any transaction ID given in B<ctx>, and
+
+=item its recipNonce matches any senderNonce given in B<ctx>.
+
+=back
+
+In case no protection is present and B<cb> is not NULL then this callback
+function is called with its B<invalid_protection> parameter being 0, while in
+case an invalid protection is present the B<invalid_protection> parameter is 1.
+The callback is passed also the arguments B<ctx>, B<msg>, and <cb_arg>
+(which typically contains the expected message type).
+The callback should return 1 on acceptance, 0 on rejection, or -1 on error.
+It should not put an error on the error stack since this could be misleading.
+
+ossl_cmp_msg_check_update() adds all extraCerts contained in the <msg> to
+the list of untrusted certificates in B<ctx> such that they are already usable
+for OSSL_CMP_validate_msg(), which is called internally, and for future use.
+Thus they are available also to the certificate confirmation callback, and the
+peer does not need to send them again (at least not in the same transaction).
+Note that it does not help validating the message before storing the extraCerts
+because they are not part of the protected portion of the message anyway.
+For efficiency, the extraCerts are prepended to the list so they get used first.
+
+If all checks pass then ossl_cmp_msg_check_update()
+records in B<ctx> the senderNonce of the received message as the new recipNonce
+and learns the transaction ID if none is currently present in B<ctx>.
+
+Moreover, according to RFC 4210 section 5.3.2, if the message protection is
+PBM-based then any certificates in the caPubs field are added to the list of
+trusted certificates (if set via L<OSSL_CMP_CTX_set0_trustedStore(3)>).
+This way these certs are available for validating subsequent messages in the
+same context and could apply to any Polling Response (pollRep), error, or PKI
+Confirmation (PKIConf) messages following in the same or future transactions.
+
+=head1 RETURN VALUES
+
+ossl_cmp_msg_check_update() returns 1 on success, -1 on error.
+
+=head1 SEE ALSO
+
+L<OSSL_CMP_validate_msg(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-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
diff --git a/doc/internal/man3/ossl_cmp_msg_create.pod b/doc/internal/man3/ossl_cmp_msg_create.pod
new file mode 100644
index 000000000000..d4294d3e9fa6
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_msg_create.pod
@@ -0,0 +1,134 @@
+=pod
+
+=head1 NAME
+
+OSSL_CMP_PKIBODY_IR,
+OSSL_CMP_PKIBODY_IP,
+OSSL_CMP_PKIBODY_CR,
+OSSL_CMP_PKIBODY_CP,
+OSSL_CMP_PKIBODY_P10CR,
+OSSL_CMP_PKIBODY_POPDECC,
+OSSL_CMP_PKIBODY_POPDECR,
+OSSL_CMP_PKIBODY_KUR,
+OSSL_CMP_PKIBODY_KUP,
+OSSL_CMP_PKIBODY_KRR,
+OSSL_CMP_PKIBODY_KRP,
+OSSL_CMP_PKIBODY_RR,
+OSSL_CMP_PKIBODY_RP,
+OSSL_CMP_PKIBODY_CCR,
+OSSL_CMP_PKIBODY_CCP,
+OSSL_CMP_PKIBODY_CKUANN,
+OSSL_CMP_PKIBODY_CANN,
+OSSL_CMP_PKIBODY_RANN,
+OSSL_CMP_PKIBODY_CRLANN,
+OSSL_CMP_PKIBODY_PKICONF,
+OSSL_CMP_PKIBODY_NESTED,
+OSSL_CMP_PKIBODY_GENM,
+OSSL_CMP_PKIBODY_GENP,
+OSSL_CMP_PKIBODY_ERROR,
+OSSL_CMP_PKIBODY_CERTCONF,
+OSSL_CMP_PKIBODY_POLLREQ,
+OSSL_CMP_PKIBODY_POLLREP,
+ossl_cmp_bodytype_to_string,
+ossl_cmp_msg_get_bodytype,
+ossl_cmp_msg_set_bodytype,
+ossl_cmp_msg_create,
+ossl_cmp_msg_gen_ITAV_push0,
+ossl_cmp_msg_gen_ITAVs_push1
+- functions handling CMP messages
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ #define OSSL_CMP_PKIBODY_IR 0
+ #define OSSL_CMP_PKIBODY_IP 1
+ #define OSSL_CMP_PKIBODY_CR 2
+ #define OSSL_CMP_PKIBODY_CP 3
+ #define OSSL_CMP_PKIBODY_P10CR 4
+ #define OSSL_CMP_PKIBODY_POPDECC 5
+ #define OSSL_CMP_PKIBODY_POPDECR 6
+ #define OSSL_CMP_PKIBODY_KUR 7
+ #define OSSL_CMP_PKIBODY_KUP 8
+ #define OSSL_CMP_PKIBODY_KRR 9
+ #define OSSL_CMP_PKIBODY_KRP 10
+ #define OSSL_CMP_PKIBODY_RR 11
+ #define OSSL_CMP_PKIBODY_RP 12
+ #define OSSL_CMP_PKIBODY_CCR 13
+ #define OSSL_CMP_PKIBODY_CCP 14
+ #define OSSL_CMP_PKIBODY_CKUANN 15
+ #define OSSL_CMP_PKIBODY_CANN 16
+ #define OSSL_CMP_PKIBODY_RANN 17
+ #define OSSL_CMP_PKIBODY_CRLANN 18
+ #define OSSL_CMP_PKIBODY_PKICONF 19
+ #define OSSL_CMP_PKIBODY_NESTED 20
+ #define OSSL_CMP_PKIBODY_GENM 21
+ #define OSSL_CMP_PKIBODY_GENP 22
+ #define OSSL_CMP_PKIBODY_ERROR 23
+ #define OSSL_CMP_PKIBODY_CERTCONF 24
+ #define OSSL_CMP_PKIBODY_POLLREQ 25
+ #define OSSL_CMP_PKIBODY_POLLREP 26
+
+ const char *ossl_cmp_bodytype_to_string(int type);
+ int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
+ int ossl_cmp_msg_set_bodytype( OSSL_CMP_MSG *msg, int type);
+ OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype);
+ int ossl_cmp_msg_gen_ITAV_push0(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav);
+ int ossl_cmp_msg_gen_ITAVs_push1(OSSL_CMP_MSG *msg,
+ STACK_OF(OSSL_CMP_ITAV) *itavs);
+
+=head1 DESCRIPTION
+
+ossl_cmp_bodytype_to_string() returns the name of the given body type as string,
+or "illegal body type" on error.
+
+ossl_cmp_msg_get_bodytype() returns the body type of the given PKIMessage,
+or -1 on error.
+
+ossl_cmp_msg_set_bodytype() sets the type of the message contained in
+the PKIMessage body field.
+Returns 1 on success, 0 on error.
+
+ossl_cmp_msg_create() creates and initializes an B<OSSL_CMP_MSG> structure,
+using fields of B<ctx> for the header and B<bodytype> for the body.
+If the current B<transactionID> field in I<ctx> indicates that there is no
+current transaction, it creates and stores a random one with 128 bits length.
+Thus, the I<ctx> may be modified by this and related ossl_cmp_*_new() functions.
+Returns pointer to created B<OSSL_CMP_MSG> on success, NULL on error.
+
+ossl_cmp_msg_gen_ITAV_push0() pushes the B<itav> to the body of the
+PKIMessage B<msg> of GenMsg or GenRep type. Consumes the B<itavs> pointer.
+Returns 1 on success, 0 on error.
+
+ossl_cmp_msg_gen_ITAVs_push1() adds a copy of the B<itavs> stack to the body
+of the PKIMessage B<msg> of GenMsg or GenRep type.
+Does not consume the B<itavs> pointer nor its elements.
+Returns 1 on success, 0 on error.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+See the individual functions above.
+
+=head1 SEE ALSO
+
+L<ossl_cmp_hdr_init(3)>,
+L<OSSL_CMP_CTX_new(3)>, L<OSSL_CMP_exec_certreq(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2021 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
diff --git a/doc/internal/man3/ossl_cmp_msg_protect.pod b/doc/internal/man3/ossl_cmp_msg_protect.pod
new file mode 100644
index 000000000000..744fbce576ca
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_msg_protect.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_calc_protection,
+ossl_cmp_msg_protect,
+ossl_cmp_msg_add_extraCerts
+- functions for producing CMP message protection
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
+ const OSSL_CMP_MSG *msg);
+ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
+ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
+
+=head1 DESCRIPTION
+
+ossl_cmp_calc_protection() calculates the protection for the given I<msg>
+according to the algorithm and parameters in the message header's protectionAlg
+using the credentials, library context, and property criteria in the I<ctx>.
+
+ossl_cmp_msg_protect() (re-)protects the given message I<msg> using an algorithm
+depending on the available context information given in the I<ctx>.
+If there is a secretValue it selects PBMAC, else if there is a protection cert
+it selects Signature and uses ossl_cmp_msg_add_extraCerts (see below).
+It also sets the protectionAlg field in the message header accordingly.
+
+ossl_cmp_msg_add_extraCerts() adds elements to the extraCerts field in I<msg>.
+If signature-based message protection is used it adds first the CMP signer cert
+ctx->cert and then its chain ctx->chain. If this chain is not present in I<ctx>
+tries to build it using ctx->untrusted and caches the result in ctx->chain.
+In any case all the certificates explicitly specified to be sent out (i.e.,
+I<ctx->extraCertsOut>) are added. Note that it will NOT add the root certificate
+of the chain, i.e, the trust anchor (unless it is part of extraCertsOut).
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+The I<ctx> parameter of ossl_cmp_msg_add_extraCerts()
+and thus also of ossl_cmp_msg_protect() cannot be made I<const>
+because I<ctx->chain> may get adapted to cache the chain of the CMP signer cert.
+
+=head1 RETURN VALUES
+
+ossl_cmp_calc_protection() returns the protection on success, else NULL.
+
+All other functions return 1 on success, 0 on error.
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2023 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
diff --git a/doc/internal/man3/ossl_cmp_pkisi_get_status.pod b/doc/internal/man3/ossl_cmp_pkisi_get_status.pod
new file mode 100644
index 000000000000..e44bfd3f0190
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_pkisi_get_status.pod
@@ -0,0 +1,99 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_certresponse_get1_cert,
+ossl_cmp_pkisi_get_status,
+ossl_cmp_PKIStatus_to_string,
+ossl_cmp_pkisi_get0_statusString,
+ossl_cmp_pkisi_get_pkifailureinfo,
+ossl_cmp_pkisi_check_pkifailureinfo
+- functions for managing PKI status information
+
+=head1 SYNOPSIS
+
+ #include "cmp.h"
+
+# define OSSL_CMP_PKIFAILUREINFO_badAlg 0
+# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1
+# define OSSL_CMP_PKIFAILUREINFO_badRequest 2
+# define OSSL_CMP_PKIFAILUREINFO_badTime 3
+# define OSSL_CMP_PKIFAILUREINFO_badCertId 4
+# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5
+# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6
+# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7
+# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8
+# define OSSL_CMP_PKIFAILUREINFO_badPOP 9
+# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10
+# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11
+# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12
+# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13
+# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14
+# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15
+# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16
+# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17
+# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18
+# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19
+# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20
+# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21
+# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22
+# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23
+# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24
+# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25
+# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
+# define OSSL_CMP_PKIFAILUREINFO_MAX 26
+
+ X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx,
+ const OSSL_CMP_CERTRESPONSE *crep);
+ int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
+ const char *ossl_cmp_PKIStatus_to_string(int status);
+ OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
+ int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
+ int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
+
+=head1 DESCRIPTION
+
+ossl_cmp_certresponse_get1_cert() returns a pointer to a copy of the newly
+enrolled certificate from the given certResponse I<crep>, or NULL on error.
+Uses data from I<ctx>, which in case of indirect POPO includes the private key.
+
+ossl_cmp_pkisi_get_status() returns the PKIStatus of I<si>, or -1 on error.
+
+ossl_cmp_PKIStatus_to_string() returns a human-readable string representing
+the PKIStatus values as specified in RFC 4210, Appendix F.
+
+ossl_cmp_pkisi_get0_statusString() returns a direct pointer to the statusString
+field contained in I<si>.
+
+ossl_cmp_pkisi_get_pkifailureinfo() returns the PKIFailureInfo bits
+of I<si>, encoded as integer, or -1 on error.
+
+ossl_cmp_pkisi_check_pkifailureinfo() returns the state of the bit (0 or 1)
+with index I<index> in the PKIFailureInfo of the I<si>, or -1 on error.
+
+=head1 NOTES
+
+CMP is defined in RFC 4210 (and CRMF in RFC 4211).
+
+=head1 RETURN VALUES
+
+See the individual functions above.
+
+=head1 SEE ALSO
+
+L<OSSL_CMP_CTX_new(3)>, L<ossl_cmp_certreq_new(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-2023 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
diff --git a/doc/internal/man3/ossl_cmp_print_log.pod b/doc/internal/man3/ossl_cmp_print_log.pod
new file mode 100644
index 000000000000..f4384402e584
--- /dev/null
+++ b/doc/internal/man3/ossl_cmp_print_log.pod
@@ -0,0 +1,108 @@
+=pod
+
+=head1 NAME
+
+ossl_cmp_print_log,
+ossl_cmp_alert,
+ossl_cmp_err,
+ossl_cmp_warn,
+ossl_cmp_info,
+ossl_cmp_debug,
+ossl_cmp_log,
+ossl_cmp_log1,
+ossl_cmp_log2,
+ossl_cmp_log3,
+ossl_cmp_log4,
+ossl_cmp_log_parse_metadata,
+ossl_cmp_add_error_data,
+ossl_cmp_add_error_line
+- logging and error reporting support for CMP
+
+=head1 SYNOPSIS
+
+ #include "cmp_local.h"
+
+ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
+ const char *func, const char *file, int line,
+ const char *level_str, const char *format, ...);
+ #define ossl_cmp_alert(ctx, msg)
+ #define ossl_cmp_err(ctx, msg)
+ #define ossl_cmp_warn(ctx, msg)
+ #define ossl_cmp_info(ctx, msg)
+ #define ossl_cmp_debug(ctx, (msg)
+ #define ossl_cmp_log(level, ctx, msg)
+ #define ossl_cmp_log1(level, ctx, fmt, arg1)
+ #define ossl_cmp_log2(level, ctx, fmt, arg1, arg2)
+ #define ossl_cmp_log3(level, ctx, fmt, arg1, arg2, arg3)
+ #define ossl_cmp_log4(level, ctx, fmt, arg1, arg2, arg3, arg4)
+ const char *ossl_cmp_log_parse_metadata(const char *buf,
+ OSSL_CMP_severity *level, char **func,
+ char **file, int *line);
+
+ #define ossl_cmp_add_error_data(txt)
+ #define ossl_cmp_add_error_line(txt)
+
+=head1 DESCRIPTION
+
+ossl_cmp_print_log() prints CMP log messages (i.e., diagnostic info) via the
+log callback of the B<ctx> if present and the severity level is sufficient.
+If the trace API if enabled the function uses it, prepending the function name,
+filename, line number, and severity information to the message being output.
+In any case the B<level>, B<func>, B<file>, and B<line> parameters
+and the message constructed using the given B<format> and variable further
+argument list are passed to the log callback function (unless it is NULL).
+The B<ctx>, B<func>, B<file>, and B<level_str> arguments may be NULL.
+
+ossl_cmp_alert(), ossl_cmp_err(), ossl_cmp_warn(), ossl_cmp_info(), and
+ossl_cmp_debug() output a simple alert/error/warning/info/debug message
+via ossl_cmp_print_log().
+
+ossl_cmp_log(), ossl_cmp_log1(), ossl_cmp_log2(), ossl_cmp_log3(), and
+ossl_cmp_log4() output a log message with the given severity,
+constructing the message text from the given format and arguments.
+
+ossl_cmp_log_parse_metadata() parses the given message buffer I<buf> populated
+by ossl_cmp_log() etc.
+according to the pattern OSSL_CMP_LOG_START#level ": %s\n", filling in
+the variable pointed to by I<level> with the severity level or -1,
+the variable pointed to by I<func> with the function name string or NULL,
+the variable pointed to by I<file> with the filename string or NULL, and
+the variable pointed to by I<line> with the line number or -1.
+Any string returned via I<*func> and I<*file> must be freed by the caller.
+
+ossl_cmp_add_error_data() is a macro calling
+L<ERR_add_error_txt(3)> with the separator being ":".
+
+ossl_cmp_add_error_line() is a macro calling
+L<ERR_add_error_txt(3)> with the separator being "\n".
+
+=head1 RETURN VALUES
+
+ossl_cmp_log_parse_metadata() returns the pointer to the actual message text
+after the OSSL_CMP_LOG_PREFIX and level and ':' if found in the buffer,
+else the beginning of the buffer.
+
+ossl_cmp_add_error_data() and
+ossl_cmp_add_error_line()
+do not return anything.
+
+All other functions return 1 on success, 0 on error.
+
+=head1 SEE ALSO
+
+L<ERR_add_error_txt(3)>
+
+=head1 HISTORY
+
+The OpenSSL CMP support was added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2007-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
diff --git a/doc/internal/man3/ossl_ends_with_dirsep.pod b/doc/internal/man3/ossl_ends_with_dirsep.pod
new file mode 100644
index 000000000000..d19ce7a3b97c
--- /dev/null
+++ b/doc/internal/man3/ossl_ends_with_dirsep.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+ossl_ends_with_dirsep, ossl_is_absolute_path
+- internal functions to work with paths
+
+=head1 SYNOPSIS
+
+ #include "internal/cryptlib.h"
+
+ int ossl_ends_with_dirsep(const char *path);
+
+ int ossl_is_absolute_path(const char *path);
+
+=head1 DESCRIPTION
+
+ossl_ends_with_dirsep() detects whether the I<path> ends with a directory
+separator in a platform agnostic way.
+
+ossl_is_absolute_path() detects whether the I<path> is absolute path in
+a platform agnostic way.
+
+=head1 RETURN VALUES
+
+ossl_ends_with_dirsep() returns 1 if the I<path> ends with a directory
+separator, 0 otherwise.
+
+ossl_is_absolute_path() returns 1 if the I<path> is absolute, 0 otherwise.
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-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
+
diff --git a/doc/internal/man3/ossl_global_properties_no_mirrored.pod b/doc/internal/man3/ossl_global_properties_no_mirrored.pod
new file mode 100644
index 000000000000..6c39ccbc0ffe
--- /dev/null
+++ b/doc/internal/man3/ossl_global_properties_no_mirrored.pod
@@ -0,0 +1,56 @@
+=pod
+
+=head1 NAME
+
+ossl_property_list_to_string, ossl_global_properties_no_mirrored
+- internal property routines
+
+=head1 SYNOPSIS
+
+ #include "internal/property.h"
+
+ size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx,
+ const OSSL_PROPERTY_LIST *list, char *buf,
+ size_t bufsize);
+
+ int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx);
+ void ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx);
+
+
+=head1 DESCRIPTION
+
+ossl_property_list_to_string() takes a given OSSL_PROPERTY_LIST in I<list> and
+converts it to a string. If I<buf> is non NULL then the string will be stored
+in I<buf>. The size of the buffer is provided in I<bufsize>. If I<bufsize> is
+too short then the string will be truncated. If I<buf> is NULL then the length
+of the string is still calculated and returned. If the property list has no
+properties in it then the empty string will be stored in I<buf>.
+
+ossl_global_properties_no_mirrored() checks whether mirroring of global
+properties from a parent library context is allowed for the current library
+context.
+
+ossl_global_properties_no_mirrored() prevents future mirroring of global
+properties from a parent library context for the current library context.
+
+=head1 RETURN VALUES
+
+ossl_property_list_to_string() returns the length of the string, or 0 on error.
+
+ossl_global_properties_no_mirrored() returns 1 if mirroring of global properties
+is not allowed, or 0 otherwise.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2021 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
diff --git a/doc/internal/man3/ossl_init_thread_deregister.pod b/doc/internal/man3/ossl_init_thread_deregister.pod
new file mode 100644
index 000000000000..6c9e0b5b8998
--- /dev/null
+++ b/doc/internal/man3/ossl_init_thread_deregister.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+OSSL_thread_stop_handler_fn,
+ossl_init_thread_start,
+ossl_init_thread_deregister
+- internal thread routines
+
+=head1 SYNOPSIS
+
+ #include "crypto/cryptlib.h"
+ #include <openssl/core.h>
+
+ typedef void (*OSSL_thread_stop_handler_fn)(void *arg);
+
+ int ossl_init_thread_start(const void *index, void *arg,
+ OSSL_thread_stop_handler_fn handfn);
+ int ossl_init_thread_deregister(void *index);
+
+=head1 DESCRIPTION
+
+Thread aware code may be informed about when a thread is stopping, typically to
+perform some cleanup operation.
+Thread stop events may be detected by OpenSSL either automatically (using the
+capabilities of the underlying threading library) where possible or explicitly
+by the application calling OPENSSL_thread_stop() or OPENSSL_thread_stop_ex().
+
+Thread aware code registers a "stop handler" for each new thread that it uses.
+Typically, when a new thread is being used, code will add a new value to some
+thread local variable and then register a stop handler. When the thread is
+stopping the stop handler is called (while on that thread) and the code can
+clean up the value stored in the thread local variable.
+
+A new stop handler is registered using the function ossl_init_thread_start().
+The I<index> parameter should be a unique value that can be used to identify a
+set of common stop handlers and is passed in a later call to
+ossl_init_thread_deregister. If no later call to ossl_init_thread_deregister is
+made then NULL can be passed for this parameter. The I<arg> parameter is passed
+back as an argument to the stop handler when it is later invoked. Finally the
+I<handfn> is a function pointer to the stop handler itself.
+
+In the event that previously registered stop handlers need to be deregistered
+then this can be done using the function ossl_init_thread_deregister().
+This will deregister all stop handlers (no matter which thread they were
+registered for) which the same I<index> value.
+
+=head1 RETURN VALUES
+
+ossl_init_thread_start() and ossl_init_thread_deregister() return 1 for success
+or 0 on error.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
diff --git a/doc/internal/man3/ossl_lib_ctx_get_data.pod b/doc/internal/man3/ossl_lib_ctx_get_data.pod
new file mode 100644
index 000000000000..faedf7275f08
--- /dev/null
+++ b/doc/internal/man3/ossl_lib_ctx_get_data.pod
@@ -0,0 +1,154 @@
+=pod
+
+=head1 NAME
+
+ossl_lib_ctx_get_data, ossl_lib_ctx_run_once, ossl_lib_ctx_onfree,
+ossl_lib_ctx_is_child
+- internal OSSL_LIB_CTX routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/types.h>
+ #include "internal/cryptlib.h"
+
+ typedef struct ossl_lib_ctx_method {
+ int priority;
+ void *(*new_func)(OSSL_LIB_CTX *ctx);
+ void (*free_func)(void *);
+ } OSSL_LIB_CTX_METHOD;
+
+ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index,
+ const OSSL_LIB_CTX_METHOD *meth);
+
+ int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx,
+ ossl_lib_ctx_run_once_fn run_once_fn);
+ int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn);
+
+ int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx);
+
+=head1 DESCRIPTION
+
+Internally, the OpenSSL library context B<OSSL_LIB_CTX> is implemented
+as a B<CRYPTO_EX_DATA>, which allows data from diverse parts of the
+library to be added and removed dynamically.
+Each such data item must have a corresponding CRYPTO_EX_DATA index
+associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes
+to identify data items. These are mapped transparently to CRYPTO_EX_DATA dynamic
+indexes internally to the implementation.
+See the example further down to see how that's done.
+
+ossl_lib_ctx_get_data() is used to retrieve a pointer to the data in
+the library context I<ctx> associated with the given I<index>. An
+OSSL_LIB_CTX_METHOD must be defined and given in the I<meth> parameter. The index
+for it should be defined in cryptlib.h. The functions through the method are
+used to create or free items that are stored at that index whenever a library
+context is created or freed, meaning that the code that use a data item of that
+index doesn't have to worry about that, just use the data available.
+
+Deallocation of an index happens automatically when the library
+context is freed.
+
+ossl_lib_ctx_run_once is used to run some initialisation routine I<run_once_fn>
+exactly once per library context I<ctx> object. Each initialisation routine
+should be allocate a unique run once index in cryptlib.h.
+
+Any resources allocated via a run once initialisation routine can be cleaned up
+using ossl_lib_ctx_onfree. This associates an "on free" routine I<onfreefn> with
+the library context I<ctx>. When I<ctx> is freed all associated "on free"
+routines are called.
+
+ossl_lib_ctx_is_child() returns 1 if this library context is a child and 0
+otherwise.
+
+=head1 RETURN VALUES
+
+ossl_lib_ctx_get_data() returns a pointer on success, or NULL on
+failure.
+
+=head1 EXAMPLES
+
+=head2 Initialization
+
+For a type C<FOO> that should end up in the OpenSSL library context, a
+small bit of initialization is needed, i.e. to associate a constructor
+and a destructor to an index.
+
+ typedef struct foo_st {
+ int i;
+ void *data;
+ } FOO;
+
+ static void *foo_new(OSSL_LIB_CTX *ctx)
+ {
+ FOO *ptr = OPENSSL_zalloc(sizeof(*foo));
+ if (ptr != NULL)
+ ptr->i = 42;
+ return ptr;
+ }
+ static void foo_free(void *ptr)
+ {
+ OPENSSL_free(ptr);
+ }
+
+ /*
+ * Include a reference to this in the methods table in context.c
+ * OSSL_LIB_CTX_FOO_INDEX should be added to internal/cryptlib.h
+ * Priorities can be OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
+ * OSSL_LIB_CTX_METHOD_PRIORITY_1, OSSL_LIB_CTX_METHOD_PRIORITY_2, etc.
+ * Default priority is low (0). The higher the priority the earlier the
+ * method's destructor will be called when the library context is cleaned up.
+ */
+ const OSSL_LIB_CTX_METHOD foo_method = {
+ OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
+ foo_new,
+ foo_free
+ };
+
+=head2 Usage
+
+To get and use the data stored in the library context, simply do this:
+
+ /*
+ * ctx is received from a caller,
+ */
+ FOO *data = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_FOO_INDEX, &foo_method);
+
+=head2 Run Once
+
+ void foo_cleanup(OSSL_LIB_CTX *ctx)
+ {
+ /* Free foo resources associated with ctx */
+ }
+
+ static ossl_lib_ctx_run_once_fn do_foo_init;
+ static int do_foo_init(OSSL_LIB_CTX *ctx)
+ {
+ /* Allocate and initialise some foo resources and associated with ctx */
+ return ossl_lib_ctx_onfree(ctx, &foo_cleanup)
+ }
+
+ int foo_some_function(OSSL_LIB_CTX *ctx)
+ {
+ if (!ossl_lib_ctx_run_once(ctx,
+ OSSL_LIB_CTX_FOO_RUN_ONCE_INDEX,
+ do_foo_init))
+ return 0;
+
+ /* Do some work using foo resources in ctx */
+ }
+
+
+=head1 SEE ALSO
+
+L<OSSL_LIB_CTX(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man3/ossl_method_construct.pod b/doc/internal/man3/ossl_method_construct.pod
new file mode 100644
index 000000000000..422d7a5b6850
--- /dev/null
+++ b/doc/internal/man3/ossl_method_construct.pod
@@ -0,0 +1,158 @@
+=pod
+
+=head1 NAME
+
+OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
+- generic method constructor
+
+=head1 SYNOPSIS
+
+ #include "internal/core.h"
+
+ struct ossl_method_construct_method_st {
+ /* Get a temporary store */
+ void *(*get_tmp_store)(void *data);
+ /* Get an already existing method from a store */
+ void *(*get)(void *store, const OSSL_PROVIDER *prov, void *data);
+ /* Store a method in a store */
+ int (*put)(void *store, void *method, const OSSL_PROVIDER *prov,
+ const char *name, const char *propdef, void *data);
+ /* Construct a new method */
+ void *(*construct)(const OSSL_ALGORITHM *algodef, OSSL_PROVIDER *prov,
+ void *data);
+ /* Destruct a method */
+ void (*destruct)(void *method, void *data);
+ };
+ typedef struct ossl_method_construct_method OSSL_METHOD_CONSTRUCT_METHOD;
+
+ void *ossl_method_construct(OSSL_LIB_CTX *ctx, int operation_id,
+ OSSL_PROVIDER *prov, int force_cache,
+ OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data);
+
+
+=head1 DESCRIPTION
+
+All libcrypto subsystems that want to create their own methods based
+on provider dispatch tables need to do so in exactly the same way.
+ossl_method_construct() does this while leaving it to the subsystems
+to define more precisely how the methods are created, stored, etc.
+
+It's important to keep in mind that a method is identified by three things:
+
+=over 4
+
+=item The operation identity
+
+=item The name of the algorithm
+
+=item The properties associated with the algorithm implementation
+
+=back
+
+=head2 Functions
+
+ossl_method_construct() creates a method by asking all available
+providers for a dispatch table given an I<operation_id>, and then
+calling the appropriate functions given by the subsystem specific
+method creator through I<mcm> and the data in I<mcm_data> (which is
+passed by ossl_method_construct()).
+If I<prov> is not NULL, only that provider is considered, which is
+useful in the case a method must be found in that particular
+provider.
+
+This function assumes that the subsystem method creator implements
+reference counting and acts accordingly (i.e. it will call the
+subsystem destruct() method to decrement the reference count when
+appropriate).
+
+=head2 Structures
+
+A central part of constructing a subsystem specific method is to give
+ossl_method_construct a set of functions, all in the
+B<OSSL_METHOD_CONSTRUCT_METHOD> structure, which holds the following
+function pointers:
+
+=over 4
+
+=item get_tmp_store()
+
+Create a temporary method store in the scope of the library context I<ctx>.
+This store is used to temporarily store methods for easier lookup, for
+when the provider doesn't want its dispatch table stored in a longer
+term cache.
+
+=item get()
+
+Look up an already existing method from a store by name.
+
+The store may be given with I<store>.
+NULL is a valid value and means that a subsystem default store
+must be used.
+This default store should be stored in the library context I<libctx>.
+
+The method to be looked up should be identified with data found in I<data>
+(which is the I<mcm_data> that was passed to ossl_construct_method()).
+In other words, the ossl_method_construct() caller is entirely responsible
+for ensuring the necessary data is made available.
+
+Optionally, I<prov> may be given as a search criterion, to narrow down the
+search of a method belonging to just one provider.
+
+This function is expected to increment the resulting method's reference count.
+
+=item put()
+
+Places the I<method> created by the construct() function (see below)
+in a store.
+
+The store may be given with I<store>.
+NULL is a valid value and means that a subsystem default store
+must be used.
+This default store should be stored in the library context I<libctx>.
+
+The method should be associated with the given provider I<prov>,
+I<name> and property definition I<propdef> as well as any
+identification data given through I<data> (which is the I<mcm_data>
+that was passed to ossl_construct_method()).
+
+This function is expected to increment the I<method>'s reference count.
+
+=item construct()
+
+Constructs a subsystem method for the given I<name> and the given
+dispatch table I<fns>.
+
+The associated provider object I<prov> is passed as well, to make
+it possible for the subsystem constructor to keep a reference, which
+is recommended.
+If such a reference is kept, the I<provider object> reference counter
+must be incremented, using ossl_provider_up_ref().
+
+This function is expected to set the method's reference count to 1.
+
+=item destruct()
+
+Decrement the I<method>'s reference count, and destruct it when
+the reference count reaches zero.
+
+=back
+
+=head1 RETURN VALUES
+
+ossl_method_construct() returns a constructed method on success, or
+NULL on error.
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2024 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
diff --git a/doc/internal/man3/ossl_namemap_new.pod b/doc/internal/man3/ossl_namemap_new.pod
new file mode 100644
index 000000000000..ff247e87b03c
--- /dev/null
+++ b/doc/internal/man3/ossl_namemap_new.pod
@@ -0,0 +1,129 @@
+=pod
+
+=head1 NAME
+
+ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty,
+ossl_namemap_add_name, ossl_namemap_add_name_n, ossl_namemap_add_names,
+ossl_namemap_name2num, ossl_namemap_name2num_n,
+ossl_namemap_doall_names
+- internal number E<lt>-E<gt> name map
+
+=head1 SYNOPSIS
+
+ #include "internal/cryptlib.h"
+
+ OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx);
+
+ OSSL_NAMEMAP *ossl_namemap_new(void);
+ void ossl_namemap_free(OSSL_NAMEMAP *namemap);
+ int ossl_namemap_empty(OSSL_NAMEMAP *namemap);
+
+ int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name);
+ int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
+ const char *name, size_t name_len);
+
+ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name);
+ int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
+ const char *name, size_t name_len);
+ int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number,
+ void (*fn)(const char *name, void *data),
+ void *data);
+
+ int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
+ const char *names, const char separator);
+
+=head1 DESCRIPTION
+
+A B<OSSL_NAMEMAP> is a one-to-many number E<lt>-E<gt> names map, which
+can be used to give any arbitrary set of names (any string) a unique
+dynamic identity that is valid throughout the lifetime of the associated
+library context.
+
+ossl_namemap_new() and ossl_namemap_free() construct and destruct a
+new B<OSSL_NAMEMAP>.
+This is suitable to use when the B<OSSL_NAMEMAP> is embedded in other
+structures, or should be independent for any reason.
+
+ossl_namemap_empty() checks if the given B<OSSL_NAMEMAP> is empty or
+not.
+
+ossl_namemap_stored() finds or auto-creates the default namemap in the
+given library context.
+The returned B<OSSL_NAMEMAP> can't be destructed using
+ossl_namemap_free().
+
+ossl_namemap_add_name() adds a new name to the namemap if it's not already
+present.
+If the given I<number> is zero, a new number will be allocated to
+identify this I<name>.
+If the given I<number> is nonzero, the I<name> is added to the set of
+names already associated with that number.
+
+ossl_namemap_name2num() finds the number corresponding to the given
+I<name>.
+
+ossl_namemap_add_name_n() and ossl_namemap_name2num_n() do the same thing
+as ossl_namemap_add_name() and ossl_namemap_name2num(), but take a string
+length I<name_len> as well, allowing the caller to use a fragment of
+a string as a name.
+
+ossl_namemap_doall_names() walks through all names associated with
+I<number> in the given I<namemap> and calls the function I<fn> for
+each of them.
+I<fn> is also passed the I<data> argument, which allows any caller to
+pass extra data for that function to use.
+
+ossl_namemap_add_names() divides up a set of names given in I<names>,
+separated by I<separator>, and adds each to the I<namemap>, all with
+the same number. If some of them already exist in the I<namemap>,
+they must all have the same associated number, which will be adopted
+for any name that doesn't exist yet.
+
+=head1 RETURN VALUES
+
+ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
+B<OSSL_NAMEMAP>, or NULL on error.
+
+ossl_namemap_empty() returns 1 if the B<OSSL_NAMEMAP> is NULL or
+empty, 0 if it's not empty, or -1 on internal error (such as inability
+to lock).
+
+ossl_namemap_add_name() and ossl_namemap_add_name_n() return the number
+associated with the added string, or zero on error.
+
+ossl_namemap_num2names() returns a pointer to a NULL-terminated list of
+pointers to the names corresponding to the given number, or NULL if
+it's undefined in the given B<OSSL_NAMEMAP>.
+
+ossl_namemap_name2num() and ossl_namemap_name2num_n() return the number
+corresponding to the given name, or 0 if it's undefined in the given
+B<OSSL_NAMEMAP>.
+
+ossl_namemap_doall_names() returns 1 if the callback was called for all names. A
+return value of 0 means that the callback was not called for any names.
+
+ossl_namemap_add_names() returns the number associated with the added
+names, or zero on error.
+
+=head1 NOTES
+
+The result from ossl_namemap_num2names() isn't thread safe, other threads
+dealing with the same namemap may cause the list of names to change
+location.
+It is therefore strongly recommended to only use the result in code
+guarded by a thread lock.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man3/ossl_provider_add_conf_module.pod b/doc/internal/man3/ossl_provider_add_conf_module.pod
new file mode 100644
index 000000000000..7e4d5097f634
--- /dev/null
+++ b/doc/internal/man3/ossl_provider_add_conf_module.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+ossl_provider_add_conf_module - internal standard configuration module
+
+=head1 SYNOPSIS
+
+ #include "internal/provider.h"
+
+ /* Configuration */
+ void ossl_provider_add_conf_module(void);
+
+=head1 DESCRIPTION
+
+ossl_provider_add_conf_module() adds the standard configuration module
+for providers.
+This allows providers to be configured with an OpenSSL L<config(5)> file.
+
+=head1 RETURN VALUES
+
+ossl_provider_add_conf_module() doesn't return any value.
+
+=head1 SEE ALSO
+
+L<OSSL_PROVIDER(3)>, L<ossl_provider_new(3)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod
new file mode 100644
index 000000000000..193472462b38
--- /dev/null
+++ b/doc/internal/man3/ossl_provider_new.pod
@@ -0,0 +1,400 @@
+=pod
+
+=head1 NAME
+
+ossl_provider_find, ossl_provider_new, ossl_provider_up_ref,
+ossl_provider_free,
+ossl_provider_set_fallback, ossl_provider_set_module_path,
+ossl_provider_add_parameter, ossl_provider_set_child, ossl_provider_get_parent,
+ossl_provider_up_ref_parent, ossl_provider_free_parent,
+ossl_provider_default_props_update, ossl_provider_get0_dispatch,
+ossl_provider_init_as_child, ossl_provider_deinit_child,
+ossl_provider_activate, ossl_provider_deactivate, ossl_provider_add_to_store,
+ossl_provider_ctx,
+ossl_provider_doall_activated,
+ossl_provider_name, ossl_provider_dso,
+ossl_provider_module_name, ossl_provider_module_path,
+ossl_provider_libctx,
+ossl_provider_teardown, ossl_provider_gettable_params,
+ossl_provider_get_params,
+ossl_provider_query_operation, ossl_provider_unquery_operation,
+ossl_provider_set_operation_bit, ossl_provider_test_operation_bit,
+ossl_provider_get_capabilities
+- internal provider routines
+
+=head1 SYNOPSIS
+
+ #include "internal/provider.h"
+
+ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name,
+ int noconfig);
+ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name,
+ ossl_provider_init_fn *init_function
+ int noconfig);
+ int ossl_provider_up_ref(OSSL_PROVIDER *prov);
+ void ossl_provider_free(OSSL_PROVIDER *prov);
+
+ /* Setters */
+ int ossl_provider_set_fallback(OSSL_PROVIDER *prov);
+ int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *path);
+ int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
+ const char *value);
+
+ /* Child Providers */
+ int ossl_provider_set_child(OSSL_PROVIDER *prov,
+ const OSSL_CORE_HANDLE *handle);
+ const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov);
+ int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate);
+ int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate);
+ int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx,
+ const char *props);
+
+ /*
+ * Activate the Provider
+ * If the Provider is a module, the module will be loaded
+ */
+ int ossl_provider_activate(OSSL_PROVIDER *prov, int upcalls, int aschild);
+ int ossl_provider_deactivate(OSSL_PROVIDER *prov, int removechildren);
+ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov,
+ int retain_fallbacks);
+
+ /* Return pointer to the provider's context */
+ void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
+
+ const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov);
+
+ /* Iterate over all loaded providers */
+ int ossl_provider_doall_activated(OSSL_LIB_CTX *,
+ int (*cb)(OSSL_PROVIDER *provider,
+ void *cbdata),
+ void *cbdata);
+
+ /* Getters for other library functions */
+ const char *ossl_provider_name(OSSL_PROVIDER *prov);
+ const DSO *ossl_provider_dso(OSSL_PROVIDER *prov);
+ const char *ossl_provider_module_name(OSSL_PROVIDER *prov);
+ const char *ossl_provider_module_path(OSSL_PROVIDER *prov);
+ OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov);
+
+ /* Thin wrappers around calls to the provider */
+ void ossl_provider_teardown(const OSSL_PROVIDER *prov);
+ const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov);
+ int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]);
+ int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov,
+ const char *capability,
+ OSSL_CALLBACK *cb,
+ void *arg);
+ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ int *no_cache);
+ void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs);
+
+ int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum);
+ int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum,
+ int *result);
+
+ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
+ const OSSL_CORE_HANDLE *handle,
+ const OSSL_DISPATCH *in);
+ void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx);
+
+=head1 DESCRIPTION
+
+I<OSSL_PROVIDER> is a type that holds all the necessary information
+to handle a provider, regardless of if it's built in to the
+application or the OpenSSL libraries, or if it's a loadable provider
+module.
+Instances of this type are commonly referred to as "provider objects".
+
+A provider object is always stored in a set of provider objects
+in the library context.
+
+Provider objects are reference counted.
+
+Provider objects are initially inactive, i.e. they are only recorded
+in the store, but are not used.
+They are activated with the first call to ossl_provider_activate(),
+and are deactivated with the last call to ossl_provider_deactivate().
+Activation affects a separate counter.
+
+=head2 Functions
+
+ossl_provider_find() finds an existing provider object in the provider
+object store by I<name>.
+The config file will be automatically loaded unless I<noconfig> is set.
+Typically I<noconfig> should be 0.
+We set I<noconfig> to 1 only when calling these functions while processing a
+config file in order to avoid recursively attempting to load the file.
+The provider object it finds has its reference count incremented.
+
+ossl_provider_new() creates a new provider object named I<name> and
+stores it in the provider object store, unless there already is one
+there with the same name.
+If there already is one with the same name, it's returned with its
+reference count incremented.
+The config file will be automatically loaded unless I<noconfig> is set.
+Typically I<noconfig> should be 0.
+We set I<noconfig> to 1 only when calling these functions while processing a
+config file in order to avoid recursively attempting to load the file.
+The reference count of a newly created provider object will always
+be 2; one for being added to the store, and one for the returned
+reference.
+If I<init_function> is NULL, the provider is assumed to be a
+dynamically loadable module, with the symbol B<OSSL_provider_init> as
+its initialisation function.
+If I<init_function> isn't NULL, the provider is assumed to be built
+in, with I<init_function> being the pointer to its initialisation
+function.
+For further description of the initialisation function, see the
+description of ossl_provider_activate() below.
+
+ossl_provider_up_ref() increments the provider object I<prov>'s
+reference count.
+
+ossl_provider_free() decrements the provider object I<prov>'s
+reference count; when it drops to zero, the provider object is assumed
+to have fallen out of use and will be deinitialized (its I<teardown>
+function is called), and the associated module will be unloaded if one
+was loaded, and I<prov> itself will be freed.
+
+ossl_provider_set_fallback() marks an available provider I<prov> as
+fallback.
+Note that after this call, the provider object pointer that was
+used can simply be dropped, but not freed.
+
+ossl_provider_set_module_path() sets the module path to load the
+provider module given the provider object I<prov>.
+This will be used in preference to automatically trying to figure out
+the path from the provider name and the default module directory (more
+on this in L</NOTES>).
+
+ossl_provider_libctx() returns the library context the given
+provider I<prov> is registered in.
+
+ossl_provider_add_parameter() adds a global parameter for the provider
+to retrieve as it sees fit.
+The parameters are a combination of I<name> and I<value>, and the
+provider will use the name to find the value it wants.
+Only text parameters can be given, and it's up to the provider to
+interpret them.
+
+ossl_provider_set_child() marks this provider as a child of a provider in the
+parent library context. I<handle> is the B<OSSL_CORE_HANDLE> object passed to
+the provider's B<OSSL_provider_init> function.
+
+ossl_provider_get_parent() obtains the handle on the parent provider.
+
+ossl_provider_up_ref_parent() increases the reference count on the parent
+provider. If I<activate> is nonzero then the parent provider is also activated.
+
+ossl_provider_free_parent() decreases the reference count on the parent
+provider. If I<deactivate> is nonzero then the parent provider is also
+deactivated.
+
+ossl_provider_default_props_update() is responsible for informing any child
+providers of an update to the default properties. The new properties are
+supplied in the I<props> string.
+
+ossl_provider_activate() "activates" the provider for the given
+provider object I<prov> by incrementing its activation count, flagging
+it as activated, and initializing it if it isn't already initialized.
+Initializing means one of the following:
+
+=over 4
+
+=item *
+
+If an initialization function was given with ossl_provider_new(), that
+function will get called.
+
+=item *
+
+If no initialization function was given with ossl_provider_new(), a
+loadable module with the I<name> that was given to ossl_provider_new()
+will be located and loaded, then the symbol B<OSSL_provider_init> will
+be located in that module, and called.
+
+=back
+
+If I<upcalls> is nonzero then, if this is a child provider, upcalls to the
+parent libctx will be made to inform it of an up-ref. If I<aschild> is nonzero
+then the provider will only be activated if it is a child provider. Otherwise
+no action is taken and ossl_provider_activate() returns success.
+
+ossl_provider_deactivate() "deactivates" the provider for the given
+provider object I<prov> by decrementing its activation count. When
+that count reaches zero, the activation flag is cleared. If the
+I<removechildren> parameter is 0 then no attempt is made to remove any
+associated child providers.
+
+ossl_provider_add_to_store() adds the provider I<prov> to the provider store and
+makes it available to other threads. This will prevent future automatic loading
+of fallback providers, unless I<retain_fallbacks> is true. If a provider of the
+same name already exists in the store then it is not added but this function
+still returns success. On success the I<actualprov> value is populated with a
+pointer to the provider of the given name that is now in the store. The
+reference passed in the I<prov> argument is consumed by this function. A
+reference to the provider that should be used is passed back in the
+I<actualprov> argument.
+
+ossl_provider_ctx() returns a context created by the provider.
+Outside of the provider, it's completely opaque, but it needs to be
+passed back to some of the provider functions.
+
+ossl_provider_get0_dispatch() returns the dispatch table that the provider
+initially returned in the I<out> parameter of its B<OSSL_provider_init>
+function.
+
+ossl_provider_doall_activated() iterates over all the currently
+"activated" providers, and calls I<cb> for each of them.
+If no providers have been "activated" yet, it tries to activate all
+available fallback providers before iterating over them.
+
+ossl_provider_name() returns the name that was given with
+ossl_provider_new().
+
+ossl_provider_dso() returns a reference to the module, for providers
+that come in the form of loadable modules.
+
+ossl_provider_module_name() returns the filename of the module, for
+providers that come in the form of loadable modules.
+
+ossl_provider_module_path() returns the full path of the module file,
+for providers that come in the form of loadable modules.
+
+ossl_provider_teardown() calls the provider's I<teardown> function, if
+the provider has one.
+
+ossl_provider_gettable_params() calls the provider's I<gettable_params>
+function, if the provider has one.
+It should return an array of I<OSSL_PARAM> to describe all the
+parameters that the provider has for the provider object.
+
+ossl_provider_get_params() calls the provider's parameter request
+responder.
+It should treat the given I<OSSL_PARAM> array as described in
+L<OSSL_PARAM(3)>.
+
+ossl_provider_get_capabilities() calls the provider's I<get_capabilities> function,
+if the provider has one. It provides the name of the I<capability> and a
+callback I<cb> parameter to call for each capability that has a matching name in
+the provider. The callback gets passed OSSL_PARAM details about the capability as
+well as the caller supplied argument I<arg>.
+
+ossl_provider_query_operation() calls the provider's
+I<query_operation> function, if the provider has one.
+It should return an array of I<OSSL_ALGORITHM> for the given
+I<operation_id>.
+
+ossl_provider_unquery_operation() informs the provider that the result of
+ossl_provider_query_operation() is no longer going to be directly accessed and
+that all relevant information has been copied.
+
+ossl_provider_set_operation_bit() registers a 1 for operation I<bitnum>
+in a bitstring that's internal to I<provider>.
+
+ossl_provider_test_operation_bit() checks if the bit operation I<bitnum>
+is set (1) or not (0) in the internal I<provider> bitstring, and sets
+I<*result> to 1 or 0 accordingly.
+
+ossl_provider_init_as_child() stores in the library context I<ctx> references to
+the necessary upcalls for managing child providers. The I<handle> and I<in>
+parameters are the B<OSSL_CORE_HANDLE> and L<OSSL_DISPATCH(3)> pointers that were
+passed to the provider's B<OSSL_provider_init> function.
+
+ossl_provider_deinit_child() deregisters callbacks from the parent library
+context about provider creation or removal events for the child library context
+I<ctx>. Must only be called if I<ctx> is a child library context.
+
+=head1 NOTES
+
+Locating a provider module happens as follows:
+
+=over 4
+
+=item 1.
+
+If a path was given with ossl_provider_set_module_path(), use that as
+module path.
+Otherwise, use the provider object's name as module path, with
+platform specific standard extensions added.
+
+=item 2.
+
+If the environment variable B<OPENSSL_MODULES> is defined, assume its
+value is a directory specification and merge it with the module path.
+Otherwise, merge the value of the OpenSSL built in macro B<MODULESDIR>
+with the module path.
+
+=back
+
+When this process is done, the result is used when trying to load the
+provider module.
+
+The command C<openssl version -m> can be used to find out the value
+of the built in macro B<MODULESDIR>.
+
+=head1 RETURN VALUES
+
+ossl_provider_find() and ossl_provider_new() return a pointer to a
+provider object (I<OSSL_PROVIDER>) on success, or NULL on error.
+
+ossl_provider_up_ref() returns the value of the reference count after
+it has been incremented.
+
+ossl_provider_free() doesn't return any value.
+
+ossl_provider_doall_activated() returns 1 if the callback was called for all
+activated providers. A return value of 0 means that the callback was not
+called for any activated providers.
+
+ossl_provider_set_module_path(), ossl_provider_set_fallback(),
+ossl_provider_activate(), ossl_provider_activate_leave_fallbacks() and
+ossl_provider_deactivate(), ossl_provider_add_to_store(),
+ossl_provider_default_props_update() return 1 on success, or 0 on error.
+
+ossl_provider_name(), ossl_provider_dso(),
+ossl_provider_module_name(), and ossl_provider_module_path() return a
+pointer to their respective data if it's available, otherwise NULL
+is returned.
+
+ossl_provider_libctx() return a pointer to the library context.
+This may be NULL, and is perfectly valid, as it denotes the default
+global library context.
+
+ossl_provider_teardown() doesn't return any value.
+
+ossl_provider_gettable_params() returns a pointer to a constant
+I<OSSL_PARAM> array if this function is available in the provider,
+otherwise NULL.
+
+ossl_provider_get_params() returns 1 on success, or 0 on error.
+If this function isn't available in the provider, 0 is returned.
+
+ossl_provider_set_operation_bit() and ossl_provider_test_operation_bit()
+return 1 on success, or 0 on error.
+
+ossl_provider_get_capabilities() returns 1 on success, or 0 on error.
+If this function isn't available in the provider or the provider does not
+support the requested capability then 0 is returned.
+
+=head1 SEE ALSO
+
+L<OSSL_PROVIDER(3)>, L<provider(7)>, L<openssl(1)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2024 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
diff --git a/doc/internal/man3/ossl_punycode_decode.pod b/doc/internal/man3/ossl_punycode_decode.pod
new file mode 100644
index 000000000000..652626159e3a
--- /dev/null
+++ b/doc/internal/man3/ossl_punycode_decode.pod
@@ -0,0 +1,60 @@
+=pod
+
+=head1 NAME
+
+ossl_punycode_decode, ossl_a2ulabel, ossl_a2ucompare
+- internal punycode-related functions
+
+=head1 SYNOPSIS
+
+ #include "crypto/punycode.h"
+
+ int ossl_punycode_decode(const char *pEncoded, const size_t enc_len,
+ unsigned int *pDecoded, unsigned int *pout_length);
+
+ int ossl_a2ulabel(const char *in, char *out, size_t *outlen);
+
+ int ossl_a2ucompare(const char *a, const char *u);
+
+=head1 DESCRIPTION
+
+PUNYCODE encoding introduced in RFCs 3490-3492 is widely used for
+representation of host names in ASCII-only format. Some specifications,
+such as RFC 8398, require comparison of host names encoded in UTF-8 charset.
+
+ossl_a2ulabel() decodes NUL-terminated hostname from PUNYCODE to UTF-8,
+using a provided buffer for output.
+
+ossl_a2ucompare() accepts two NUL-terminated hostnames, decodes the 1st
+from PUNYCODE to UTF-8 and compares it with the 2nd one as is.
+
+ossl_punycode_decode() decodes one label (one dot-separated part) from
+a hostname, with stripped PUNYCODE marker I<xn-->.
+
+=head1 RETURN VALUES
+
+ossl_a2ulabel() returns 1 on success, 0 on not enough buf passed,
+-1 on invalid PUNYCODE string passed. When valid string is provided, it sets the
+I<*outlen> to the length of required buffer to perform correct decoding.
+
+ossl_a2ucompare() returns 1 on non-equal strings, 0 on equal strings,
+-1 when invalid PUNYCODE string passed.
+
+ossl_punycode_decode() returns 1 on success, 0 on error. On success,
+*pout_length contains the number of codepoints decoded.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
+
diff --git a/doc/internal/man3/ossl_rand_get_entropy.pod b/doc/internal/man3/ossl_rand_get_entropy.pod
new file mode 100644
index 000000000000..4da3f1f4d9db
--- /dev/null
+++ b/doc/internal/man3/ossl_rand_get_entropy.pod
@@ -0,0 +1,66 @@
+=pod
+
+=head1 NAME
+
+ossl_rand_get_entropy, ossl_rand_cleanup_entropy,
+ossl_rand_get_nonce, ossl_rand_cleanup_nonce
+- get seed material from the operating system
+
+=head1 SYNOPSIS
+
+ #include "crypto/rand.h"
+
+ size_t ossl_rand_get_entropy(OSSL_CORE_HANDLE *handle,
+ unsigned char **pout, int entropy,
+ size_t min_len, size_t max_len);
+ void ossl_rand_cleanup_entropy(OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len);
+ size_t ossl_rand_get_nonce(OSSL_CORE_HANDLE *handle,
+ unsigned char **pout, size_t min_len,
+ size_t max_len, const void *salt, size_t salt_len);
+ void ossl_rand_cleanup_nonce(OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len);
+
+=head1 DESCRIPTION
+
+ossl_rand_get_entropy() retrieves seeding material from the operating system.
+The seeding material will have at least I<entropy> bytes of randomness and is
+stored in a buffer which contains at least I<min_len> and at most I<max_len>
+bytes. The buffer address is stored in I<*pout> and the buffer length is
+returned to the caller.
+
+ossl_rand_cleanup_entropy() cleanses and frees any storage allocated by
+ossl_rand_get_entropy(). The seeding buffer is pointed to by I<buf> and is
+of length I<len> bytes.
+
+ossl_rand_get_nonce() retrieves a nonce using the passed I<salt> parameter
+of length I<salt_len> and operating system specific information.
+The I<salt> should contain uniquely identifying information and this is
+included, in an unspecified manner, as part of the output.
+The output is stored in a buffer which contains at least I<min_len> and at
+most I<max_len> bytes. The buffer address is stored in I<*pout> and the
+buffer length returned to the caller.
+
+ossl_rand_cleanup_nonce() cleanses and frees any storage allocated by
+ossl_rand_get_nonce(). The nonce buffer is pointed to by I<buf> and is
+of length I<len> bytes.
+
+=head1 RETURN VALUES
+
+ossl_rand_get_entropy() and ossl_rand_get_nonce() return the number of bytes
+in I<*pout> or 0 on error.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 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
diff --git a/doc/internal/man3/ossl_random_add_conf_module.pod b/doc/internal/man3/ossl_random_add_conf_module.pod
new file mode 100644
index 000000000000..a3c1285fe01b
--- /dev/null
+++ b/doc/internal/man3/ossl_random_add_conf_module.pod
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+ossl_random_add_conf_module - internal random configuration module
+
+=head1 SYNOPSIS
+
+ #include "crypto/rand.h"
+
+ /* Configuration */
+ void ossl_random_add_conf_module(void);
+
+=head1 DESCRIPTION
+
+ossl_random_add_conf_module() adds the random configuration module
+for providers.
+This allows the type and parameters of the standard setup of random number
+generators to be configured with an OpenSSL L<config(5)> file.
+
+=head1 RETURN VALUES
+
+ossl_random_add_conf_module() doesn't return any value.
+
+=head1 SEE ALSO
+
+L<OSSL_PROVIDER(3)>, L<ossl_provider_new(3)>, L<provider-rand(7)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020-2024 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
diff --git a/doc/internal/man3/ossl_rsa_get0_all_params.pod b/doc/internal/man3/ossl_rsa_get0_all_params.pod
new file mode 100644
index 000000000000..a7ebb613bb02
--- /dev/null
+++ b/doc/internal/man3/ossl_rsa_get0_all_params.pod
@@ -0,0 +1,75 @@
+=pod
+
+=head1 NAME
+
+ossl_rsa_set0_all_params, ossl_rsa_get0_all_params
+- Internal routines for getting and setting data in an RSA object
+
+=head1 SYNOPSIS
+
+ #include "crypto/rsa.h"
+
+ int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
+ STACK_OF(BIGNUM_const) *exps,
+ STACK_OF(BIGNUM_const) *coeffs);
+ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
+ const STACK_OF(BIGNUM) *exps,
+ const STACK_OF(BIGNUM) *coeffs);
+
+=head1 DESCRIPTION
+
+ossl_rsa_set0_all_params() sets all primes, CRT exponents and CRT coefficients
+in the B<RSA> object I<r> to the contents of the stacks of BIGNUMs I<primes>,
+I<exps> and I<coeffs>. The B<RSA> object takes ownership of the BIGNUMs,
+but not of the stacks.
+
+ossl_rsa_get0_all_params() gets all primes, CRT exponents and CRT coefficients
+in the B<RSA> object I<r> and pushes them on the stacks of constant BIGNUMs
+I<primes>, I<exps> and I<coeffs>. The B<RSA> object retains ownership of the
+BIGNUMs, but not of the stacks.
+
+=head1 NOTES
+
+For RSA_set0_all_params() and RSA_get0_all_params():
+
+=over 4
+
+=item *
+
+the I<primes> stack contains I<p>, I<q>, and then the rest of the primes
+if the B<RSA> object is a multi-prime RSA key.
+
+=item *
+
+the I<exps> stack contains I<dP>, I<dQ>, and then the rest of the exponents
+if the B<RSA> object is a multi-prime RSA key.
+
+=item *
+
+the I<coeffs> stack contains I<qInv>, and then the rest of the coefficients
+if the B<RSA> object is a multi-prime RSA key.
+
+=back
+
+The number of primes must always be equal to the number of exponents, and
+the number of coefficients must be one less than the number of primes.
+
+=head1 RETURN VALUES
+
+ossl_rsa_get0_all_params() and ossl_rsa_set0_all_params() return 1 on success,
+or 0 on failure.
+
+=head1 SEE ALSO
+
+L<RSA_set0_multi_prime_params(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019-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
diff --git a/doc/internal/man3/x509v3_cache_extensions.pod b/doc/internal/man3/x509v3_cache_extensions.pod
new file mode 100644
index 000000000000..cc0aeb6079a8
--- /dev/null
+++ b/doc/internal/man3/x509v3_cache_extensions.pod
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+x509v3_cache_extensions
+- cache info on various X.509v3 extensions and further derived certificate data
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509v3.h>
+
+ int x509v3_cache_extensions(X509 *x, OSSL_LIB_CTX *libctx, const char *propq);
+
+=head1 DESCRIPTION
+
+This function processes any X509v3 extensions present in an X509 object I<x>
+and caches the result of that processing as well as further derived info,
+for instance whether the certificate is self-issued or has version X.509v1.
+It computes the SHA1 digest of the certificate using the default library context
+and property query string and stores the result in x->sha1_hash,
+or on failure sets B<EXFLAG_NO_FINGERPRINT> in x->flags.
+It sets B<X509_SIG_INFO_VALID> in x->flags if x->siginf was filled successfully,
+which may not be possible if a referenced algorithm is unknown or not available.
+Many OpenSSL functions that use an X509 object call this function implicitly.
+
+=head1 RETURN VALUES
+
+This function returns 0 if the extensions or other portions of the certificate
+are invalid or an error occurred.
+Otherwise it returns 1.
+
+=head1 COPYRIGHT
+
+Copyright 2020-2021 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
diff --git a/doc/internal/man7/DERlib.pod b/doc/internal/man7/DERlib.pod
new file mode 100644
index 000000000000..24280b976b34
--- /dev/null
+++ b/doc/internal/man7/DERlib.pod
@@ -0,0 +1,149 @@
+=pod
+
+=head1 NAME
+
+DERlib - internal OpenSSL DER library
+
+=head1 DESCRIPTION
+
+OpenSSL contains an internal small DER reading and writing library,
+as an alternative to the publicly known i2d and d2i functions. It's
+solely constituted of functions that work as building blocks to create
+more similar functions to encode and decode larger structures.
+
+All these functions have similar function signatures (C<something>
+will vary depending on what the function will encode):
+
+ int DER_w_something(WPACKET *pkt, int tag, ...);
+
+=begin comment
+
+When readers are added, add this:
+
+ int DER_r_something(PACKET *pkt, int tag, ...);
+
+=end comment
+
+I<pkt> is the packet context used, and I<tag> should be the
+context-specific tag value of the element being handled, or -1 if there
+is no tag number for that element (you may use the convenience macro
+B<DER_NO_CONTEXT> instead of -1). Any argument following is the C
+variable that's being encoded or decoded.
+
+=head2 DER writers / encoders
+
+DER writers are based in L<WPACKET(3)>, a generic packet writing
+library, so before using any of them, I<pkt> must be initialized
+using L<WPACKET_init_der(3)> or L<WPACKET_init_null_der(3)>
+
+DER writers must be used in reverse order, except for the wrapping
+functions that implement a constructed element. The latter are easily
+recognised by their function name including the words C<begin> and
+C<end>. As an example, we can look at the DSA signature structure,
+which is defined like this in ASN.1 terms:
+
+ -- Copied from RFC 3279, section 2.2.2
+ Dss-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER }
+
+With the DER library, this is the corresponding code, given two OpenSSL
+B<BIGNUM>s I<r> and I<s>:
+
+ int ok = ossl_DER_w_begin_sequence(pkt, -1)
+ && ossl_DER_w_bn(pkg, -1, s)
+ && ossl_DER_w_bn(pkg, -1, r)
+ && ossl_DER_w_end_sequence(pkt, -1);
+
+As an example of the use of I<tag>, an ASN.1 element like this:
+
+ v [1] INTEGER OPTIONAL
+
+Would be encoded like this:
+
+ ossl_DER_w_bn(pkt, 1, v)
+
+=begin comment
+
+=head2 DER readers / decoders
+
+TBA
+
+=end comment
+
+=head1 EXAMPLES
+
+A more complex example, encoding the AlgorithmIdentifier with
+RSASSA-PSS values.
+
+As a reminder, the AlgorithmIdentifier is specified like this:
+
+ -- From RFC 3280, section 4.1.1.2
+ AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL }
+
+And the RSASSA-PSS OID and parameters are specified like this:
+
+ -- From RFC 3279, section 3.1
+ id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
+
+ RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT
+ sha1Identifier,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT
+ mgf1SHA1Identifier,
+ saltLength [2] INTEGER DEFAULT 20,
+ trailerField [3] INTEGER DEFAULT 1 }
+
+The value we want to encode, written in ASN.1 syntax:
+
+ {
+ algorithm id-RSASSA-PSS,
+ parameters {
+ hashAlgorithm sha256Identifier,
+ maskGenAlgorithm mgf1SHA256Identifier,
+ saltLength 20 -- unnecessarily explicit
+ }
+ }
+
+Assuming that we have precompiled constants for C<id-RSASSA-PSS>,
+C<sha256Identifier> and C<mgf1SHA256Identifier>, the DER writing code
+looks as follows. This is a complete function to write that specific
+value:
+
+ int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt,
+ int tag,
+ RSA *rsa)
+ {
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ && (ossl_DER_w_begin_sequence(pkt, DER_NO_CONTEXT)
+ && ossl_DER_w_uint32(pkt, 2, 20)
+ && ossl_DER_w_precompiled(pkt, 1,
+ der_mgf1SHA256Identifier,
+ sizeof(der_mgf1SHA256Identifier))
+ && ossl_DER_w_precompiled(pkt, 0,
+ der_sha256Identifier,
+ sizeof(der_sha256Identifier))
+ && ossl_DER_w_end_sequence(pkt, DER_NO_CONTEXT))
+ && ossl_DER_w_precompiled(pkt, DER_NO_CONTEXT,
+ der_id_RSASSA_PSS,
+ sizeof(der_id_RSASSA_PSS))
+ && ossl_DER_w_end_sequence(pkt, tag);
+ }
+
+=head1 SEE ALSO
+
+L<ossl_DER_w_bn(3)>, L<ossl_DER_w_begin_sequence(3)>,
+L<ossl_DER_w_precompiled(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2020-2022 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
diff --git a/doc/internal/man7/EVP_PKEY.pod b/doc/internal/man7/EVP_PKEY.pod
new file mode 100644
index 000000000000..3dc10fa4104c
--- /dev/null
+++ b/doc/internal/man7/EVP_PKEY.pod
@@ -0,0 +1,212 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY - an internal description
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ typedef struct evp_pkey_st EVP_PKEY;
+
+=head1 DESCRIPTION
+
+I<This is not a complete description yet>
+
+B<EVP_PKEY> is a complex type that's essentially a container for
+private/public key pairs, but has had other uses as well.
+
+=for comment "uses" could as well be "abuses"...
+
+The private/public key pair that an B<EVP_PKEY> contains is referred to
+as its "internal key" or "origin" (the reason for "origin" is
+explained further down, in L</Export cache for provider operations>),
+and it can take one of the following forms:
+
+=over 4
+
+=item legacy origin
+
+This is the form that an B<EVP_PKEY> in OpenSSL prior to 3.0 had. The
+internal key in the B<EVP_PKEY> is a pointer to the low-level key
+types, such as B<RSA>, B<DSA> and B<EC>, or an engine driven
+structure, and is governed by an associated L<EVP_PKEY_METHOD(3)> and
+an L<EVP_PKEY_ASN1_METHOD(3)>.
+
+The functions available through those two method structures get full
+access to the B<EVP_PKEY> and therefore have a lot of freedom to
+modify whatever they want. This also means that an B<EVP_PKEY> is a
+shared structure between libcrypto and any ENGINE that serves such
+methods.
+
+=item provider-native origin
+
+This is a new form in OpenSSL 3.0, which permits providers to hold the
+key data (see L<provider-keymgmt(7)>). The internal key in the
+B<EVP_PKEY> is a pointer to that key data held by the provider, and
+is governed by an associated L<EVP_KEYMGMT(3)> method structure.
+
+The functions available through the L<EVP_KEYMGMT(3)> have no access
+to the B<EVP_PKEY>, and can therefore not make any direct changes.
+Similarly, the key data that the B<EVP_PKEY> points at is only known
+to the functions pointed at in the L<EVP_KEYMGMT(3)>.
+
+=back
+
+These two forms can never co-exist in the same B<EVP_PKEY>, the main
+reason being that having both at the same time will create problems
+with synchronising between the two forms, and potentially make it
+confusing which one of the two is the origin.
+
+=head2 Key mutability
+
+The B<EVP_PKEY> internal keys are mutable.
+
+This is especially visible with internal legacy keys, since they can
+be extracted with functions like L<EVP_PKEY_get0_RSA(3)> and then
+modified at will with functions like L<RSA_set0_key(3)>. Note that if the
+internal key is a provider key then the return value from functions such as
+L<EVP_PKEY_get0_RSA(3)> is a cached copy of the key. Changes to the cached
+copy are not reflected back in the provider key.
+
+Internal provider native keys are also possible to be modified, if the
+associated L<EVP_KEYMGMT(3)> implementation allows it. This is done
+with L<EVP_PKEY_set_params(3)> and its specialised derivatives. The
+OpenSSL providers allow it for the following:
+
+=over 4
+
+=item DH, EC, X25519, X448:
+
+It's possible to set the encoded public key. This is supported in
+particular through L<EVP_PKEY_set1_encoded_public_key(3)>.
+
+=item EC:
+
+It's possible to flip the ECDH cofactor mode.
+
+=back
+
+Every time the B<EVP_PKEY> internal key mutates, an internal dirty
+count is incremented. The need for a dirty count is explained further
+in L</Export cache for provider operations>.
+
+For provider native origin keys, this doesn't require any help from
+the L<EVP_KEYMGMT(3)>, the dirty count is maintained in the B<EVP_PKEY>
+itself, and is incremented every time L<EVP_PKEY_set_params(3)> or its
+specialised derivatives are called.
+For legacy origin keys, this requires the associated
+L<EVP_PKEY_ASN1_METHOD(3)> to implement the dirty_cnt() function. All
+of OpenSSL's built-in L<EVP_PKEY_ASN1_METHOD(3)> implement this
+function.
+
+=head2 Export cache for provider operations
+
+OpenSSL 3.0 can handle operations such as signing, encrypting, etc in
+diverse providers, potentially others than the provider of the
+L<EVP_KEYMGMT(3)>. Two providers, possibly from different vendors,
+can't be expected to share internal key structures. There are
+therefore instances where key data will need to be exported to the
+provider that is going to perform the operation (this also implies
+that every provider that implements a key pair based operation must
+also implement an L<EVP_KEYMGMT(3)>).
+
+For performance reasons, libcrypto tries to minimize the need to
+perform such an export, so it maintains a cache of such exports in the
+B<EVP_PKEY>. Each cache entry has two items, a pointer to the
+provider side key data and the associated L<EVP_KEYMGMT(3)>.
+
+I<This cache is often referred to as the "operation key cache", and
+the key data that the cached keys came from is the "origin", and since
+there are two forms of the latter, we have the "legacy origin" and the
+"provider native origin".>
+
+The export to the operation key cache can be performed independent of
+what form the origin has.
+For a legacy origin, this requires that the associated
+L<EVP_PKEY_ASN1_METHOD(3)> implements the functions export_to() and
+dirty_cnt().
+For a provider native origin, this requires that the associated
+L<EVP_KEYMGMT(3)> implements the OSSL_FUNC_keymgmt_export() function
+(see L<provider-keymgmt(7)>).
+In all cases, the receiving L<EVP_KEYMGMT(3)> (the one associated with
+the exported key data) must implement OSSL_FUNC_keymgmt_import().
+
+If such caching isn't supported, the operations that can be performed
+with that key are limited to the same backend as the origin key
+(ENGINE for legacy origin keys, provider for provider side origin
+keys).
+
+=head3 Exporting implementation details
+
+
+Exporting a key to the operation cache involves the following:
+
+=over 4
+
+=item 1.
+
+Check if the dirty count for the internal origin key has changed since
+the previous time. This is done by comparing it with a copy of the
+dirty count, which is maintained by the export function.
+
+If the dirty count has changed, the export cache is cleared.
+
+=item 2.
+
+Check if there's an entry in the export cache with the same
+L<EVP_KEYMGMT(3)> that's the same provider that an export is to be
+made to (which is the provider that's going to perform an operation
+for which the current B<EVP_PKEY> is going to be used).
+
+If such an entry is found, nothing more is done, the key data and
+L<EVP_KEYMGMT(3)> found in that export cache entry will be used for
+the operation to be performed.
+
+=item 3.
+
+Export the internal origin key to the provider, using the appropriate
+method.
+
+For legacy origin keys, that's done with the help of the
+L<EVP_PKEY_ASN1_METHOD(3)> export_to() function.
+
+For provider native origin keys, that's done by retrieving the key
+data in L<OSSL_PARAM(3)> form from the origin keys, using the
+OSSL_FUNC_keymgmt_export() functions of the associated
+L<EVP_KEYMGMT(3)>, and sending that data to the L<EVP_KEYMGMT(3)> of
+the provider that's to perform the operation, using its
+OSSL_FUNC_keymgmt_import() function.
+
+=back
+
+=head2 Changing a key origin
+
+It is never possible to change the origin of a key. An B<EVP_PKEY> with a legacy
+origin will I<never> be upgraded to become an B<EVP_PKEY> with a provider
+native origin. Instead, we have the operation cache as described above, that
+takes care of the needs of the diverse operation the application may want to
+perform.
+
+Similarly an B<EVP_PKEY> with a provider native origin, will I<never> be
+I<transformed> into an B<EVP_PKEY> with a legacy origin. Instead we may have a
+cached copy of the provider key in legacy form. Once the cached copy is created
+it is never updated. Changes made to the provider key are not reflected back in
+the cached legacy copy. Similarly changes made to the cached legacy copy are not
+reflected back in the provider key.
+
+=head1 SEE ALSO
+
+L<provider-keymgmt(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2020-2024 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
diff --git a/doc/internal/man7/VERSION.pod b/doc/internal/man7/VERSION.pod
new file mode 100644
index 000000000000..4bc8ba6b9327
--- /dev/null
+++ b/doc/internal/man7/VERSION.pod
@@ -0,0 +1,149 @@
+=pod
+
+=head1 NAME
+
+VERSION - OpenSSL version information
+
+=head1 SYNOPSIS
+
+ MAJOR=3
+ MINOR=0
+ PATCH=0
+ PRE_RELEASE_TAG=dev
+ BUILD_METADATA=
+ RELEASE_DATE=
+ SHLIB_VERSION=3
+
+=head1 DESCRIPTION
+
+This file is a set of keyed information looking like simple variable
+assignments. When given an empty value, they are seen as unassigned.
+The keys that are recognised are:
+
+=over 4
+
+=item B<MAJOR>, B<MINOR>, B<PATCH>
+
+The three parts of OpenSSL's 3 numbered version number, MAJOR.MINOR.PATCH.
+These are used to compose the values for the C macros B<OPENSSL_VERSION_MAJOR>,
+B<OPENSSL_VERSION_MINOR>, B<OPENSSL_VERSION_PACTH>.
+
+=item B<PRE_RELEASE_TAG>
+
+This is the added pre-release tag, which is added to the version separated by
+a dash. For a value C<foo>, the C macro B<OPENSSL_VERSION_PRE_RELEASE> gets
+the string C<-foo> (dash added).
+
+=item B<BUILD_METADATA>
+
+Extra metadata to be used by anyone for their own purposes. This is added to
+the version and possible pre-release tag, separated by a plus sign. For a
+value C<bar>, the C macro B<OPENSSL_VERSION_BUILD_METADATA> gets the string
+C<+bar>.
+
+=item B<RELEASE_DATE>
+
+Defined in releases. When not set, it gets the value C<xx XXX xxxx>.
+
+=item B<SHLIB_VERSION>
+
+The shared library version, which is something other than the project version.
+
+=back
+
+It is a configuration error if B<MAJOR>, B<MINOR>, B<PATCH> and B<SHLIB_VERSION>
+don't have values. Configuration will stop in that case.
+
+=head2 Affected configuration data
+
+The following items in %config from F<configdata.pm> are affected:
+
+=over 4
+
+=item $config{major}, $config{minor}, $config{patch}, $config{shlib_version}
+
+These items get their values from B<MAJOR>, B<MINOR>, B<PATCH>, and
+B<SHLIB_VERSION>, respectively.
+
+=item $config{prerelease}
+
+If B<PRERELEASE> is assigned a value, $config{prerelease} gets that same value,
+prefixed by a dash, otherwise the empty string.
+
+=item $config{build_metadata}
+
+If B<BUILD_METADATA> is assigned a value, $config{build_metadata} gets that same
+value, prefixed by a plus sign, otherwise the empty string.
+
+=item $config{release_date}
+
+If B<RELEASE_DATE> is assigned a value, $config{release_date} gets that same
+value, otherwise the string C<xx XXX yyyy>.
+
+=item $config{version}
+
+The minimal version number, a string composed from B<MAJOR>, B<MINOR> and
+B<PATCH>, separated by periods. For C<MAJOR=3>, C<MINOR=0> and C<PATCH=0>,
+the string will be C<3.0.0>.
+
+=item $config{full_version}
+
+The fully loaded version number, a string composed from $config{version},
+$config{prerelease} and $config{build_metadata}. See See L</EXAMPLES> for
+a few examples.
+
+=back
+
+=head1 EXAMPLES
+
+=over 4
+
+=item 1.
+
+ MAJOR=3
+ MINOR=0
+ PATCH=0
+ PRE_RELEASE_TAG=dev
+ BUILD_METADATA=
+
+The fully loaded version number ($config{full_version}) will be
+C<3.0.0-dev>.
+
+=item 2.
+
+ MAJOR=3
+ MINOR=0
+ PATCH=0
+ PRE_RELEASE_TAG=
+ BUILD_METADATA=something
+
+The fully loaded version number ($config{full_version}) will be
+C<3.0.0+something>.
+
+=item 3.
+
+ MAJOR=3
+ MINOR=0
+ PATCH=0
+ PRE_RELEASE_TAG=alpha3
+ BUILD_METADATA=something
+
+The fully loaded version number ($config{full_version}) will be
+C<3.0.0-alpha3+something>.
+
+=back
+
+=head1 SEE ALSO
+
+L<OpenSSL_version(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
diff --git a/doc/internal/man7/build.info.pod b/doc/internal/man7/build.info.pod
new file mode 100644
index 000000000000..080c9e444eea
--- /dev/null
+++ b/doc/internal/man7/build.info.pod
@@ -0,0 +1,644 @@
+=pod
+
+=head1 NAME
+
+build.info - Building information files
+
+=head1 SYNOPSIS
+
+B<IF[>0|1B<]>
+
+B<ELSIF[>0|1B<]>
+
+B<ELSE>
+
+B<ENDIF>
+
+B<SUBDIRS=> I<dir> ...
+
+B<PROGRAMS=> I<name> ...
+
+B<LIBS=> I<name> ...
+
+B<MODULES=> I<name> ...
+
+B<SCRIPTS=> I<name> ...
+
+B<DEPEND[>I<items>B<]=> I<otheritem> ...
+
+B<GENERATE[>I<item>B<]=> I<generator> I<generator-args> ...
+
+B<SOURCE[>I<item>B<]=> I<file> ...
+
+B<SHARED_SOURCE[>I<item>B<]=> I<file> ...
+
+B<DEFINE[>I<items>B<]=> I<name>[B<=>I<value>] ...
+
+B<INCLUDE[>I<items>B<]=> I<dir> ...
+
+B<$>I<VARIABLE>B<=>I<value>
+
+=head1 DESCRIPTION
+
+OpenSSL's build system revolves around three questions:
+
+=over 4
+
+=item What to build for?
+
+This is about choice of platform (combination of hardware, operating
+system, and toolchain).
+
+=item What to build?
+
+This is about having all the information on what needs to be built and
+from what.
+
+=item How to build it?
+
+This is about build file generation.
+
+=back
+
+This document is all about the second item, "What to build?", and most
+of all, how to specify that information.
+
+For some terms used in this document, please see the L</GLOSSARY> at
+the end.
+
+=head2 F<build.info> files
+
+F<build.info> files are meta data files for OpenSSL's built file
+generators, and are used to specify exactly what end product files
+(programs, libraries, modules or scripts) are to be produced, and from
+what sources.
+
+Intermediate files, such as object files, are seldom referred to at
+all. They sometimes can be, if there's a need, but this should happen
+very rarely, and support for that sort of thing is added on as-needed
+basis.
+
+Any time a directory or file is expected in a statement value, Unix
+syntax must be used, which means that the slash C</> must be used as
+the directory separator.
+
+=head2 General syntax
+
+=head3 Comments
+
+Comments are any line that start with a hash sign (C<#>). The hash
+sign may be preceded by any number of horizontal spaces.
+
+=head3 Filenames
+
+F<build.info> files are platform agnostic. This means that there is
+some information in them that is representative rather than specific.
+
+This is particularly visible with end product names, they work more
+like a tag than as the actual filename that's going to be produced.
+This is because different platforms have different decorations on
+different types of files.
+
+For example, if we say that we want to produce a program C<foo>, it
+would look like this:
+
+ PROGRAM=foo
+
+However, the program filename may end up being just C<foo> (typical
+for Unix), or C<foo.exe> (typical for Windows), or even C<BLAH$FOO.EXE>
+(possible on VMS, depending on policy).
+
+These platform specific decorations are not the concern of
+F<build.info> files. The build file generators are responsible for
+transforming these platform agnostic names to their platform specific
+counterparts.
+
+=head3 Statements
+
+With the exception of variables and conditions, the general statement
+syntax is one of:
+
+=over 4
+
+=item B<I<KEYWORD>> B<=> I<value> ...
+
+=item B<I<KEYWORD>[>I<items>B<]> B<=> I<value> ...
+
+=back
+
+Every B<I<KEYWORD>> represents some particular type of information.
+
+The first form (sometimes called "plain statement") is used to specify
+information on what end products need to be built, for example:
+
+ PROGRAMS=foo bar
+ LIBS=libpoly libcookie
+ MODULES=awesome-plugin
+ SCRIPTS=tool1 tool2
+ SUBDIRS=dir1 dir2
+
+This says that we want to build programs C<foo> and C<bar>, the
+libraries C<libpoly> and C<libcookie>, an awesome plugin module
+C<awesome-plugin>, a couple of scripts C<tool1> and C<tool2>, and
+finally that there are more F<build.info> files in subdirectories
+C<dir1> and C<dir2>.
+
+The second form (sometimes called "indexed statement") is used to
+specify further details for existing items, for example:
+
+ SOURCE[foo]=foo.c details.c
+ DEPEND[foo]=libcookie
+
+This says that the program C<foo> is built from the source files
+F<foo.c> and F<details.c>, and that it depends on the library
+C<libcookie> (in other words, the library will be included when
+linking that program together).
+
+Multiple space separated items are allowed too:
+
+ SOURCE[foo]=foo.c
+ SOURCE[details]=details.c
+ DEPEND[foo details]=libcookie
+
+For any indexed statement for which the items haven't been specified
+through any plain statement, or where the items exists but the indexed
+statement does not apply, the value is simply ignored by the build
+file generators.
+
+=head3 Statement attributes
+
+Some statements can have attributes added to them, to allow for
+variations on how they are treated.
+
+=over 4
+
+=item B<I<KEYWORD>{> I<attrib> | I<attrib>B<=>I<attrib-value> [,...]B<}>
+B<=> I<value> ...
+
+=item B<I<KEYWORD>[>I<items>B<]{> I<attrib> | I<attrib>B<=>I<attrib-value>
+[,...]B<}> B<=> I<value> ...
+
+=back
+
+Attributes are passed as they are to the build file generators, and
+the exact interpretation of those attributes is entirely up to them
+(see L</Known attributes> below for details).
+
+A current example:
+
+ LIBS{noinst,has_main}=libtestutil.a
+
+This says that the static library C<libtestutil.a> should not be
+installed (C<noinst>), and that it includes an object file that has
+the C<main> symbol (C<has_main>). Most platforms don't need to know
+the latter, but there are some where the program linker will not look
+for C<main> in libraries unless it's explicitly told so, so this is
+way to tell the build file generator to emit the necessary command
+options to make that happen.
+
+Attributes are accumulated globally. This means that a library could
+be given like this in different places:
+
+ # Location 1
+ LIBS=libwhatever
+
+ # Location 2
+ LIBS{noinst}=libwhatever
+
+ # Location 3
+ LIBS{has_main}=libwhatever
+
+The end result is that the library C<libwhatever> will have the
+attributes C<noinst> and C<has_main> attached to it.
+
+=head3 Quoting and tokens
+
+Statement values are normally split into a list of tokens, separated
+by spaces.
+
+To avoid having a value split up into several tokens, they may be
+quoted with double (C<">) or single (C<'>) quotes.
+
+For example:
+
+ PROGRAMS=foo "space cadet" bar
+
+This says that we sant to build three programs, C<foo>, C<space cadet>
+and C<bar>.
+
+=head3 Conditionals
+
+F<build.info> files include a very simple condition system, involving
+the following keywords:
+
+=over 4
+
+=item B<IF[>0|1B<]>
+
+=item B<ELSIF[>0|1B<]>
+
+=item B<ELSE>
+
+=item B<ENDIF>
+
+=back
+
+This works like any condition system with similar syntax, and the
+condition value in B<IF> and B<ELSIF> can really be any literal value
+that perl can interpret as true or false.
+
+Conditional statements are nesting.
+
+In itself, this is not very powerful, but together with L</Perl nuggets>,
+it can be.
+
+=head3 Variables
+
+F<build.info> handles simple variables. They are defined by
+assignment:
+
+=over 4
+
+=item B<$>I<NAME> B<=> I<value>
+
+=back
+
+These variables can then be used as part of any statement value or
+indexed statement item. This should be used with some care, as
+I<variables are expanded into their values before the value they are
+part of is tokenized>.
+
+I<Variable assignment values are not tokenized.>
+
+Variable references can be one of:
+
+=over 4
+
+=item B<$>I<NAME> or B<${>I<NAME>B<}>
+
+Simple reference; the variable reference is replaced with its value,
+verbatim.
+
+=item B<${>I<NAME>B</>I<str>B</>I<subst>B<}>
+
+Substitution reference; the variable reference is replaced with its
+value, modified by replacing all occurrences of I<str> with I<subst>.
+
+=back
+
+=head2 Scope
+
+Most of the statement values are accumulated globally from all the
+F<build.info> files that are digested. There are two exceptions,
+F<build.info> variables and B<SUBDIRS> statement, for which the scope
+is the F<build.info> file they are in.
+
+=head2 Perl nuggets
+
+Whenever a F<build.info> file is read, it is passed through the Perl
+template processor L<OpenSSL::Template>, which is a small extension of
+L<Text::Template>.
+
+Perl nuggets are anything between C<{-> and C<-}>, and whatever the
+result from such a nugget is, that value will replace the nugget in
+text form. This is useful to get dynamically generated F<build.info>
+statements, and is most often seen used together with the B<IF> and
+B<ELSIF> conditional statements.
+
+For example:
+
+ IF[{- $disabled{something} -}]
+ # do whatever's needed when "something" is disabled
+ ELSIF[{- $somethingelse eq 'blah' -}]
+ # do whatever's needed to satisfy this condition
+ ELSE
+ # fallback
+ ENDIF
+
+Normal Perl scope applies, so it's possible to have an initial perl
+nugget that sets diverse global variables that are used in later
+nuggets. Each nugget is a Perl block of its own, so B<my> definitions
+are only in scope within the same nugget, while B<our> definitions are
+in scope within the whole F<build.info> file.
+
+=head1 REFERENCE
+
+=head2 Conditionals
+
+=over 4
+
+=item B<IF[>0|1B<]>
+
+If the condition is true (represented as C<1> here), everything
+between this B<IF> and the next corresponding B<ELSIF> or B<ELSE>
+applies, and the rest until the corresponding B<ENDIF> is skipped
+over.
+
+If the condition is false (represented as C<0> here), everything
+from this B<IF> is skipped over until the next corresponding B<ELSIF>
+or B<ELSE>, at which point processing continues.
+
+=item B<ELSE>
+
+If F<build.info> statements have been skipped over to this point since
+the corresponding B<IF> or B<ELSIF>, F<build.info> processing starts
+again following this line.
+
+=item B<ELSIF[>0|1B<]>
+
+This is B<ELSE> and B<IF> combined.
+
+=item B<ENDIF>
+
+Marks the end of a conditional.
+
+=back
+
+=head2 Plain statements
+
+=over 4
+
+=item B<SUBDIRS=> I<dir> ...
+
+This instructs the F<build.info> reader to also read the F<build.info>
+file in every specified directory. All directories should be given
+relative to the location of the current F<build.info> file.
+
+=item B<PROGRAMS=> I<name> ...
+
+Collects names of programs that should be built.
+
+B<PROGRAMS> statements may have attributes, which apply to all the
+programs given in such a statement. For example:
+
+ PROGRAMS=foo
+ PROGRAMS{noinst}=bar
+
+With those two lines, the program C<foo> will not have the attribute
+C<noinst>, while the program C<bar> will.
+
+=item B<LIBS=> I<name> ...
+
+Collects names of libraries that should be built.
+
+The normal case is that libraries are built in both static and shared
+form. However, if a name ends with C<.a>, only the static form will
+be produced.
+
+Similarly, libraries may be referred in indexed statements as just the
+plain name, or the name including the ending C<.a>. If given without
+the ending C<.a>, any form available will be used, but if given with
+the ending C<.a>, the static library form is used unconditionally.
+
+B<LIBS> statements may have attributes, which apply to all the
+libraries given in such a statement. For example:
+
+ LIBS=libfoo
+ LIBS{noinst}=libbar
+
+With those two lines, the library C<libfoo> will not have the
+attribute C<noinst>, while the library C<libbar> will.
+
+=item B<MODULES=> I<name>
+
+Collects names of dynamically loadable modules that should be built.
+
+B<MODULES> statements may have attributes, which apply to all the
+modules given in such a statement. For example:
+
+ MODULES=foo
+ MODULES{noinst}=bar
+
+With those two lines, the module C<foo> will not have the attribute
+C<noinst>, while the module C<bar> will.
+
+=item B<SCRIPTS=> I<name>
+
+Collects names of scripts that should be built, or that just exist.
+That is how they differ from programs, as programs are always expected
+to be compiled from multiple sources.
+
+B<SCRIPTS> statements may have attributes, which apply to all the
+scripts given in such a statement. For example:
+
+ SCRIPTS=foo
+ SCRIPTS{noinst}=bar
+
+With those two lines, the script C<foo> will not have the attribute
+C<noinst>, while the script C<bar> will.
+
+=back
+
+=head2 Indexed statements
+
+=over 4
+
+=item B<DEPEND[>I<items>B<]> B<=> I<file> ...
+
+Collects dependencies, where I<items> depend on the given I<file>s.
+
+As a special case, the I<items> may be empty, for which the build file
+generators should make the whole build depend on the given I<file>s,
+rather than the specific I<items>.
+
+The I<items> may be any program, library, module, script, or any
+filename used as a value anywhere.
+
+The I<items> may also be literal build file targets. Those are
+recognised by being surrounded be vertical bars (also known as the
+"pipe" character), C<|>. For example:
+
+ DEPEND[|tests|]=fipsmodule.cnf
+
+B<DEPEND> statements may have attributes, which apply to each
+individual dependency in such a statement. For example:
+
+ DEPEND[libfoo.a]=libmandatory.a
+ DEPEND[libfoo.a]{weak}=libbar.a libcookie.a
+
+With those statements, the dependency between C<libfoo.a> and
+C<libmandatory.a> is strong, while the dependency between C<libfoo.a>
+and C<libbar.a> and C<libcookie.a> is weak. See the description of
+B<weak> in L</Known attributes> for more information.
+
+=item B<GENERATE[>I<item>B<]> B<=> I<generator> I<generator-arg> ...
+
+This specifies that the I<item> is generated using the I<generator>
+with the I<generator-arg>s as arguments, plus the name of the output
+file as last argument.
+
+For I<generator>s where this is applicable, any B<INCLUDE> statement
+for the same I<item> will be given to the I<generator> as its
+inclusion directories. Likewise, any B<DEPEND> statement for the same
+I<item> will be given to the I<generator> as an extra file or module
+to load, where this is applicable.
+
+The build file generators must be able to recognise the I<generator>.
+Currently, they at least recognise files ending in C<.pl>, and will
+execute them to generate the I<item>, and files ending in C<.in>,
+which will be used as input for L<OpenSSL::Template> to generate
+I<item> (in other words, we use the exact same style of
+L</Perl nuggets> mechanism that is used to read F<build.info> files).
+
+=item B<SOURCE[>I<item>B<]> B<=> I<file> ...
+
+Collects filenames that will be used as source files for I<item>.
+
+The I<item> must be a singular item, and may be any program, library,
+module or script given with B<PROGRAMS>, B<LIBS>, B<MODULES> and
+B<SCRIPTS>.
+
+Static libraries may be sources. In that case, its object files are
+used directly when building I<item> instead of relying on library
+dependency and symbol resolution (through B<DEPEND> statements).
+
+B<SOURCE> statements may have attributes, which apply to each
+individual dependency in such a statement. For example:
+
+ SOURCE[prog]=prog_a.c
+ SOURCE[prog]{check}=prog_b.c prog_c.c
+
+With those statements, the association between C<prog> and C<prog_a.c>
+comes with no extra attributes, while the association between C<prog>
+and C<prog_b.c> as well as C<prog_c.c> comes with the extra attribute
+C<check>.
+
+=item B<SHARED_SOURCE[>I<item>B<]> B<=> I<file> ...
+
+Collects filenames that will be used as source files for I<item>.
+
+The I<item> must be a singular item, and may be any library or module
+given with B<LIBS> or B<MODULES>. For libraries, the given filenames
+are only used for their shared form, so if the item is a library name
+ending with C<.a>, the filenames will be ignored.
+
+B<SHARED_SOURCE> statements may have attributes, just as B<SOURCE>
+statements.
+
+=item B<DEFINE[>I<items>B<]> B<=> I<name>[B<=>I<value>] ...
+
+Collects I<name> / I<value> pairs (or just I<name> with no defined
+value if no I<value> is given) associated with I<items>.
+
+The build file generators will decide what to do with them. For
+example, these pairs should become C macro definitions whenever a
+C<.c> file is built into an object file.
+
+=item B<INCLUDE[>I<items>B<]> B<=> I<dir> ...
+
+Collects inclusion directories that will be used when building the
+I<items> components (object files and whatever else). This is used at
+the discretion of the build file generators.
+
+=back
+
+=head2 Known attributes
+
+Note: this will never be a complete list of attributes.
+
+=over 4
+
+=item B<noinst>
+
+This is used to specify that the end products this is set for should
+not be installed, that they are only internal. This is applicable on
+internal static libraries, or on test programs.
+
+=item B<misc>
+
+This is used with B<SCRIPTS>, to specify that some scripts should be
+installed in the "misc" directory rather than the normal program
+directory.
+
+=item B<engine>
+
+This is used with B<MODULES>, to specify what modules are engines and
+should be installed in the engines directory instead of the modules
+directory.
+
+=item B<weak>
+
+This is used with B<DEPEND> where libraries are involved, to specify
+that the dependency between two libraries is weak and is only there to
+infer order.
+
+Without this attribute, a dependency between two libraries, expressed
+like this, means that if C<libfoo.a> appears in a linking command
+line, so will C<libmandatory.a>:
+
+ DEPEND[libfoo.a]=libmandatory.a
+
+With this attribute, a dependency between two libraries, expressed
+like this, means that if I<both> C<libfoo.a> and C<libmandatory.a>
+appear in a linking command line (because of recursive dependencies
+through other libraries), they will be ordered in such a way that this
+dependency is maintained:
+
+ DEPEND[libfoo.a]{weak}=libfoo.a libcookie.a
+
+This is useful in complex dependency trees where two libraries can be
+used as alternatives for each other. In this example, C<lib1.a> and
+C<lib2.a> have alternative implementations of the same thing, and
+C<libmandatory.a> has unresolved references to that same thing, and is
+therefore depending on either of them, but not both at the same time:
+
+ DEPEND[program1]=libmandatory.a lib1.a
+ DEPEND[program2]=libmandatory.a lib2.a
+ DEPEND[libmandatory]{weak}=lib1.a lib2.a
+
+=back
+
+=head1 GLOSSARY
+
+=over 4
+
+=item "build file"
+
+This is any platform specific file that describes the complete build,
+with platform specific commands. On Unix, this is typically
+F<Makefile>; on VMS, this is typically F<descrip.mms>.
+
+=item "build file generator"
+
+Perl code that generates build files, given configuration data and
+data collected from F<build.info> files.
+
+=item "plain statement"
+
+Any F<build.info> statement of the form B<I<KEYWORD>>=I<values>, with
+the exception of conditional statements and variable assignments.
+
+=item "indexed statement"
+
+Any F<build.info> statement of the form B<I<KEYWORD>[>I<items>B<]=>I<values>,
+with the exception of conditional statements.
+
+=item "intermediate file"
+
+Any file that's an intermediate between a source file and an end
+product.
+
+=item "end product"
+
+Any file that is mentioned in the B<PROGRAMS>, B<LIBS>, B<MODULES> or
+B<SCRIPTS>.
+
+=back
+
+=head1 SEE ALSO
+
+For OpenSSL::Template documentation,
+C<perldoc -o man util/perl/OpenSSL/Template.pm>
+
+L<Text::Template|https://metacpan.org/pod/Text::Template>
+
+=head1 COPYRIGHT
+
+Copyright 2019-2021 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
diff --git a/doc/internal/man7/deprecation.pod b/doc/internal/man7/deprecation.pod
new file mode 100644
index 000000000000..13a4b059a04c
--- /dev/null
+++ b/doc/internal/man7/deprecation.pod
@@ -0,0 +1,140 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_NO_DEPRECATED_3_0, OSSL_DEPRECATEDIN_3_0,
+OPENSSL_NO_DEPRECATED_1_1_1, OSSL_DEPRECATEDIN_1_1_1,
+OPENSSL_NO_DEPRECATED_1_1_0, OSSL_DEPRECATEDIN_1_1_0,
+OPENSSL_NO_DEPRECATED_1_0_2, OSSL_DEPRECATEDIN_1_0_2,
+OPENSSL_NO_DEPRECATED_1_0_1, OSSL_DEPRECATEDIN_1_0_1,
+OPENSSL_NO_DEPRECATED_1_0_0, OSSL_DEPRECATEDIN_1_0_0,
+OPENSSL_NO_DEPRECATED_0_9_8, OSSL_DEPRECATEDIN_0_9_8,
+deprecation - How to do deprecation
+
+=head1 DESCRIPTION
+
+Deprecation of a symbol is adding an attribute to the declaration of that
+symbol (function, type, variable, but we currently only do that for
+functions in our public header files, F<< <openssl/*.h> >>).
+
+Removal of a symbol is not the same thing as deprecation, as it actually
+explicitly removes the symbol from public view.
+
+OpenSSL configuration supports deprecation as well as simulating removal of
+symbols from public view (with the configuration option C<no-deprecated>, or
+if the user chooses to do so, with L<OPENSSL_NO_DEPRECATED(7)>), and also
+supports doing this in terms of a specified OpenSSL version (with the
+configuration option C<--api>, or if the user chooses to do so, with
+L<OPENSSL_API_COMPAT(7)>).
+
+Deprecation is done using attribute macros named
+B<OSSL_DEPRECATEDIN_I<version>>, used with any declaration it applies to.
+
+Simulating removal is done with C<#ifndef> preprocessor guards using macros
+named B<OPENSSL_NO_DEPRECATED_I<version>>.
+
+B<OSSL_DEPRECATEDIN_I<version>> and B<OPENSSL_NO_DEPRECATED_I<version>> are
+defined in F<< <openssl/macros.h> >>.
+
+In those macro names, B<I<version>> corresponds to the OpenSSL release since
+which the deprecation applies, with underscores instead of periods. Because
+of the change in version scheme with OpenSSL 3.0, the B<I<version>> for
+versions before that are three numbers (such as C<1_1_0>), while they are
+two numbers (such as C<3_0>) from 3.0 and on.
+
+The implementation of a deprecated symbol is kept for one of two reasons:
+
+=over 4
+
+=item Planned to be removed
+
+The symbol and its implementation are planned to be removed some time in the
+future, but needs to remain available until that time.
+Such an implementation needs to be guarded appropriately, as shown in
+L</Implementations to be removed> below.
+
+=item Planned to remain internally
+
+The symbol is planned to be removed from public view, but will otherwise
+remain for internal purposes. In this case, the implementation doesn't need
+to change or be guarded.
+
+However, it's necessary to ensure that the declaration remains available for
+the translation unit where the symbol is used or implemented, even when the
+symbol is publicly unavailable through simulated removal. That's done by
+including an internal header file very early in the affected translation
+units. See L</Implementations to remain internally> below.
+
+In the future, when the deprecated declaration is to actually be removed
+from public view, it should be moved to an internal header file, with the
+deprecation attribute removed, and the translation units that implement or
+use that symbol should adjust their header inclusions accordingly.
+
+=back
+
+=head1 EXAMPLES
+
+=head2 Header files
+
+In public header files (F<< <openssl/*.h> >>), this is what a deprecation is
+expected to look like, including the preprocessor wrapping for simulated
+removal:
+
+ # ifndef OPENSSL_NO_DEPRECATED_3_0
+ /* ... */
+
+ OSSL_DEPRECATEDIN_3_0 RSA *RSA_new_method(ENGINE *engine);
+
+ /* ... */
+ # endif
+
+=head2 Implementations to be removed
+
+For a deprecated function that we plan to remove in the future, for example
+RSA_new_method(), the following should be found very early (before including
+any OpenSSL header file) in the translation unit that implements it and in
+any translation unit that uses it:
+
+ /*
+ * Suppress deprecation warnings for RSA low level implementations that are
+ * kept until removal.
+ */
+ #define OPENSSL_SUPPRESS_DEPRECATED
+
+The RSA_new_method() implementation itself must be guarded the same way as
+its declaration in the public header file is:
+
+ #ifndef OPENSSL_NO_DEPRECATED_3_0
+ RSA *RSA_new_method(ENGINE *engine)
+ {
+ /* ... */
+ }
+ #endif
+
+=head2 Implementations to remain internally
+
+For a deprecated function that we plan to keep internally, for example
+RSA_size(), the following should be found very early (before including any
+other OpenSSL header file) in the translation unit that implements it and in
+any translation unit that uses it:
+
+ /*
+ * RSA low level APIs are deprecated for public use, but are kept for
+ * internal use.
+ */
+ #include "internal/deprecated.h"
+
+=head1 SEE ALSO
+
+L<openssl_user_macros(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2020-2021 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