[openssl-commits] [web] master update
Richard Levitte
levitte at openssl.org
Mon Feb 11 21:19:32 UTC 2019
The branch master has been updated
via e56baa71b5cc8028e08e8a3027ea9ecf3f27dbd0 (commit)
via 6065450b21d016b775b31e091d32c20be5bfecc7 (commit)
via 2a9b4633145732c5e50fa9848d5e87380d2dc5ea (commit)
via 653652e64822e3c199efb861e9c15bca8d174e19 (commit)
via 37e9a53cb53ca592f669ab7d08e816177220d949 (commit)
from 86790fc138e335918125ccd51941958785e840d5 (commit)
- Log -----------------------------------------------------------------
commit e56baa71b5cc8028e08e8a3027ea9ecf3f27dbd0
Author: Richard Levitte <levitte at openssl.org>
Date: Fri Feb 1 16:42:51 2019 +0100
OpenSSL 3.0.0 Design: make the state uppercase
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/web/pull/113)
commit 6065450b21d016b775b31e091d32c20be5bfecc7
Author: Richard Levitte <levitte at openssl.org>
Date: Fri Feb 1 16:41:43 2019 +0100
Allow extra header stuff, and use it to correct the list style type
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/web/pull/113)
commit 2a9b4633145732c5e50fa9848d5e87380d2dc5ea
Author: Richard Levitte <levitte at openssl.org>
Date: Wed Jan 30 13:31:16 2019 +0100
Add the OpenSSL 3.0.0 Design document (draft)
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/web/pull/113)
commit 653652e64822e3c199efb861e9c15bca8d174e19
Author: Richard Levitte <levitte at openssl.org>
Date: Fri Feb 1 16:42:26 2019 +0100
MD to HTML: add a mechanism to show a document state
If the YAML metadata of a document contains a 'state:' attribute, it
will be rendered with large sans-serif in a 45 degree angle.
Requires CSS3
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/web/pull/113)
commit 37e9a53cb53ca592f669ab7d08e816177220d949
Author: Richard Levitte <levitte at openssl.org>
Date: Fri Feb 1 16:41:43 2019 +0100
MD to HTML: allow extra header stuff
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/web/pull/113)
-----------------------------------------------------------------------
Summary of changes:
Makefile | 4 +
bin/md-to-html5.tmpl.html5 | 20 +-
docs/OpenSSL300Design.md | 3193 +++++++++++++++++++++++
docs/images/300Component.png | Bin 0 -> 67941 bytes
docs/images/300FIPSStateMachine.png | Bin 0 -> 63762 bytes
docs/images/300Packaging.png | Bin 0 -> 67311 bytes
docs/images/300PropDefinition.png | Bin 0 -> 9390 bytes
docs/images/300PropNumberLiteral.png | Bin 0 -> 25821 bytes
docs/images/300PropPropertyName.png | Bin 0 -> 13569 bytes
docs/images/300PropQuery.png | Bin 0 -> 16653 bytes
docs/images/300PropQuotedString.png | Bin 0 -> 14064 bytes
docs/images/300PropStringLiteral.png | Bin 0 -> 7343 bytes
docs/images/300PropUnquotedString.png | Bin 0 -> 5440 bytes
docs/images/300PropValue.png | Bin 0 -> 6558 bytes
docs/images/300ProviderCollab.png | Bin 0 -> 45613 bytes
docs/images/DigestExplicit.png | Bin 0 -> 61671 bytes
docs/images/DigestSignFIPSExplicit.png | Bin 0 -> 125685 bytes
docs/images/DigestSignFIPSModulePerspective.png | Bin 0 -> 82601 bytes
docs/images/ToBeComponent.png | Bin 73449 -> 67941 bytes
docs/images/ToBePackaging.png | Bin 65063 -> 67311 bytes
20 files changed, 3216 insertions(+), 1 deletion(-)
create mode 100644 docs/OpenSSL300Design.md
create mode 100644 docs/images/300Component.png
create mode 100644 docs/images/300FIPSStateMachine.png
create mode 100644 docs/images/300Packaging.png
create mode 100644 docs/images/300PropDefinition.png
create mode 100644 docs/images/300PropNumberLiteral.png
create mode 100644 docs/images/300PropPropertyName.png
create mode 100644 docs/images/300PropQuery.png
create mode 100644 docs/images/300PropQuotedString.png
create mode 100644 docs/images/300PropStringLiteral.png
create mode 100644 docs/images/300PropUnquotedString.png
create mode 100644 docs/images/300PropValue.png
create mode 100644 docs/images/300ProviderCollab.png
create mode 100644 docs/images/DigestExplicit.png
create mode 100644 docs/images/DigestSignFIPSExplicit.png
create mode 100644 docs/images/DigestSignFIPSModulePerspective.png
diff --git a/Makefile b/Makefile
index f799e85..a8dbae6 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ SIMPLE = newsflash.inc sitemap.txt \
community/omc.inc community/omc-alumni.inc \
docs/faq.inc docs/fips.inc \
docs/OpenSSLStrategicArchitecture.html \
+ docs/OpenSSL300Design.html \
news/changelog.inc news/changelog.txt \
news/cl102.txt news/cl110.txt news/cl111.txt \
news/openssl-1.0.2-notes.inc \
@@ -110,6 +111,9 @@ docs/fips.inc: $(wildcard docs/fips/*) bin/mk-filelist
docs/OpenSSLStrategicArchitecture.html: docs/OpenSSLStrategicArchitecture.md
@rm -f $@
./bin/md-to-html5 $<
+docs/OpenSSL300Design.html: docs/OpenSSL300Design.md
+ @rm -f $@
+ ./bin/md-to-html5 $<
news/changelog.inc: news/changelog.txt bin/mk-changelog
@rm -f $@
diff --git a/bin/md-to-html5.tmpl.html5 b/bin/md-to-html5.tmpl.html5
index b1fbe38..d784305 100644
--- a/bin/md-to-html5.tmpl.html5
+++ b/bin/md-to-html5.tmpl.html5
@@ -1,14 +1,32 @@
<!DOCTYPE html>
<html lang="en">
+<head>
<!--#include virtual="/inc/head.shtml" -->
+$for(header-includes)$
+ $header-includes$
+$endfor$
+<style type="text/css">
+ .state {
+ position: fixed;
+ color: rgba(0,0,0,0.1);
+ font-family: sans-serif;
+ font-size: 25vh;
+ transform-origin: right top;
+ transform: rotate(-45deg);
+ z-index: 100;
+ }
+</style>
+</head>
<body>
<!--#include virtual="/inc/banner.shtml" -->
-
<div id="main">
<div id="content">
<div class="blog-index">
<article>
+$if(state)$
+<span class="state">$state$</span>
+$endif$
$if(title)$
<header>
<h1 class="title">$title$</h1>
diff --git a/docs/OpenSSL300Design.md b/docs/OpenSSL300Design.md
new file mode 100644
index 0000000..30a02eb
--- /dev/null
+++ b/docs/OpenSSL300Design.md
@@ -0,0 +1,3193 @@
+---
+title: OpenSSL 3.0.0 Design
+author: OpenSSL Management Committee (OMC)
+date: January, 2019
+state: DRAFT
+header-includes:
+- |
+ <style type="text/css">
+ ol, ol ol, ol ol ol { list-style-type: decimal; }
+ </style>
+---
+## Introduction
+
+
+This document outlines the design of OpenSSL 3.0, the next version of
+OpenSSL after 1.1.1. It assumes familiarity with the document entitled
+_OpenSSL Strategic Architecture_ and a working knowledge of OpenSSL
+1.1.x.
+
+The OpenSSL 3.0 release will have minimal impact to the vast majority
+of existing applications; almost all well-behaved applications will
+just need to be recompiled.
+
+The majority of the changes in OpenSSL 3.0 are internal architectural
+restructuring to facilitate a long-term supportable cryptographic
+framework that enables better separation of algorithm implementations
+from algorithm APIs. These structural changes also support a more
+maintainable OpenSSL FIPS Cryptographic Module 3.0.
+
+No currently marked deprecated APIs will be removed in OpenSSL 3.0.
+
+Many additional low-level functions will be marked as deprecated APIs
+in OpenSSL 3.0.
+
+OpenSSL 3.0 will support an application having TLS connections that
+are in FIPS mode (using the OpenSSL FIPS Cryptographic Module 3.0) and
+TLS connections that are in non-FIPS mode simultaneously.
+
+## Terms Used in This Document {#terms-used-in-this-document}
+
+The following terms, in alphabetical order, are used in this
+document. A brief (summary) definition is provided.
+
+
+
+* **Algorithm**, or sometimes **cryptographic algorithm**, is a
+ method to perform a set of operations (such as encryption or
+ decryption). Our use of the term is abstract, and usually
+ represents an algorithm by its name, such as "aes-128-cbc".
+* **Algorithm implementation**, or sometimes just
+ **implementation**, is a concrete implementation of an algorithm.
+ This is mainly represented in code in the form of a set of
+ functions.
+* **CAVS** is the Cryptographic Algorithm Validation System. A tool
+ used to test that a cryptographic implementation conforms to FIPS
+ standards.
+* **CMVP** is the Cryptographic Module Validation Program. A process
+ that validates that cryptographic implementations conform to FIPS
+ standards.
+* **EVP** is a family of APIs implemented by libcrypto that enables
+ applications to perform cryptographic operations. The
+ implementation of the EVP API uses the Core and Provider
+ components.
+* The **Core** is a component in libcrypto that enables applications
+ to access the algorithm implementations offered by providers.
+* **CSP** is Critical Security Parameters. This includes any information (e.g.
+ private keys, passwords, pin numbers etc) that might compromise the security
+ of a module in the event of their unauthorised disclosure or modification.
+* **Explicit Fetch** is a method for finding an algorithm
+ implementation where the application makes an explicit call to
+ locate the implementation and supplies search criteria.
+* **FIPS** is the Federal Information Processing Standards. This is
+ a set of standards defined by the US government. In particular,
+ FIPS standard 140-2 is applicable to cryptographic software.
+* A **FIPS module** is an implementation of cryptographic algorithms
+ that has been validated by the CMVP as conforming to FIPS
+ standards. In OpenSSL the FIPS module is implemented as a provider
+ and is available in dynamically loadable module form.
+* **Implicit Fetch** is a method for finding an algorithm
+ implementation where the application does not explicitly make a
+ call to locate the implementation and therefore default search
+ criteria are used.
+* The **Integrity Check** is a test that is automatically run when
+ the FIPS module is loaded. The module checksums itself and
+ verifies that it hasn't been inadvertently altered.
+* **KAS** is Key Agreement Scheme. A method by which two communicating parties
+ can agree a shared key between them.
+* **KAT**s are Known Answer Tests. A set of tests used to perform a
+ health-check of a FIPS module.
+* **libcrypto** is a shared library implemented by OpenSSL that
+ provides applications with access to various cryptography related
+ capabilities.
+* **libssl** is a shared library implemented by OpenSSL that
+ provides applications with the ability to create SSL/TLS
+ connections either as a client or as a server.
+* A **Library Context** is an opaque structure that holds library
+ "global" data.
+* **Operation** is a class of functions to be performed on data,
+ such as calculating a digest, encrypting, decrypting, etc. An
+ algorithm may offer one or more operations. For example RSA
+ provides asymmetric encryption, asymmetric decryption, signing,
+ verifying, etc
+* **Parameters** are an implementation agnostic set of key-value
+ pairs that are used to communicate object data between the Core
+ and providers. For example they could be used to transfer private
+ key data.
+* **POST** refers to the FIPS module Power-Up Self-Tests
+ (a.k.a. Power-On Self-Tests) that are run at installation time, at
+ power up (i.e. each time the FIPS module is loaded for an
+ application) or on demand. These tests include the Integrity Check
+ and the KATs. If the KATs were run successfully at installation
+ time then they don't need to be run again at power up, however the
+ Integrity Check is always performed.
+* **Properties** are used by providers to describe the features of
+ their algorithm implementations. They are also used in application
+ queries to find specific implementations.
+* **Provider** is a unit that provides one or more algorithm
+ implementations.
+* **Provider module** is a provider in dynamically loadable module
+ form.
+
+## Architecture {#architecture}
+
+The architecture shall have the following features:
+
+* Common Services form the building blocks usable by applications
+ and providers. (e.g. BIO, X509, SECMEM, ASN.1, etc).
+* Providers implement cryptographic algorithms and supporting
+ services. An algorithm may consist of multiple operations (for
+ example RSA may have "encrypt", "decrypt", "sign", "verify"
+ etc). Similarly an operation (for example "sign") can be
+ implemented by multiple algorithms such as RSA and ECDSA. A
+ provider has implementations of the cryptographic primitives for
+ an algorithm. This release will include the following providers:
+ a. Default, which contains the current non-legacy OpenSSL
+ cryptographic algorithms; this will be built-in (i.e., part of
+ libcrypto)
+ b. Legacy, with implementations of older algorithms (e.g, DES,
+ MDC2, MD2, Blowfish, CAST)
+ c. Engines, which include a compatibility layer between engines
+ designed for older versions of OpenSSL, and the new Provider
+ based approach.
+ d. FIPS, which implements the OpenSSL FIPS Cryptographic Module
+ 3.0; this can be loaded dynamically at runtime.
+* The Core enables access to the operations offered by providers to
+ applications (and other providers). The Core is the mechanism via
+ which concrete implementations of operations are located.
+* Protocol implementations. E.g. TLS, DTLS.
+
+This document has many references to the "EVP API." This refers to
+"application-level" operations, such as public-key signing, generating
+a digest and so on. These functions include `EVP_DigestSign`,
+`EVP_Digest`, `EVP_MAC_init` and the like. The EVP API also
+encapsulates the cryptographic objects used to perform those services,
+such as `EVP_PKEY`, `EVP_CIPHER`, `EVP_MD`, `EVP_MAC` and so
+forth. Providers implement the backend functionality for the latter
+set. Instances of these objects can be bound to providers implicitly
+or explicitly, depending on the application's needs. This is discussed
+in more detail in the [Provider Design](#core-and-provider-design),
+below.
+
+The architecture has the following characteristics:
+
+* The EVP layer is a thin wrapper for operations implemented in the
+ providers. Most calls are passed straight through with little/no
+ pre- or post-processing.
+* New EVP APIs will be provided to affect how the Core selects (or
+ finds) the implementation of an operation to be used for any given
+ EVP call.
+* Information will be passed between libcrypto and the providers in
+ an implementation agnostic manner.
+* Legacy APIs (e.g. low level cryptographic APIs that do not go via
+ the EVP layer) will be deprecated. Note that there are legacy APIs
+ to non legacy algorithms (e.g. AES is not a legacy algorithm but
+ `AES_encrypt` is a legacy API).
+* The OpenSSL FIPS Cryptographic Module will be implemented as a
+ dynamically loaded provider. It will be self-contained (i.e. can
+ only depend on system runtime libraries and services provided by
+ the Core).
+
+### Conceptual Component View {#conceptual-component-view}
+
+An overview of the conceptual components in the OpenSSL architecture
+is as shown in the diagram below. Note that the existence of a
+component in the diagram does not indicate that the component is a
+public API or intended for end-user direct access or usage.
+
+![](images/ToBeComponent.png)
+
+The new components (not present in the previous architecture) shown
+here are as follows:
+
+* Core: This is a fundamental component that connects requests for
+ an operation (such as encryption) to a provider of that
+ operation. It provides the ability to locate an implementation of
+ an algorithm offering specified operations given a set of
+ properties that the implementation must fulfil. For example,
+ properties of an encryption algorithm may include at a minimum
+ "fips".
+* Default Provider: Implements a set of default algorithms.
+* FIPS Provider: Implements a set of algorithms that are FIPS
+ validated and are made available via the Core. This includes the
+ following supporting services:
+ * POST: Power On Self Test
+ * KAT: Known Answer Tests
+ * Integrity Check
+ * Low Level Implementations: This is the set of components that
+ actually implement the cryptographic primitives (to meet the
+ FIPS-mandated self-contained requirement).
+* Engines Provider: A shim that allows existing engines to work
+ when called via the Core.
+* Legacy Provider: Provides implementations of older algorithms that
+ will be exposed via EVP-level APIs.
+* 3rd Party Providers: Eventually, third-parties may provide their
+ own providers. A third-party provider, like any other provider,
+ implements a set of algorithms that will be accessible to
+ applications and other providers via the Core.
+
+### Packaging View {#package-view}
+
+The various components described in the conceptual component view
+above are physically packaged into:
+
+* Executable application(s) for use by users
+* Libraries for use by application(s)
+* Dynamically loadable module(s) for use by the Core.
+
+There will be multiple different packaging options provided with
+OpenSSL 3.0 (for example a single library libcrypto containing
+everything except the FIPS Provider, and all providers as separate
+dynamically loadable modules).
+
+Which dynamically loadable modules are registered, used, or available
+will be able to be configured at runtime.
+
+The following figure describes the architecture in terms of physical
+packages.
+
+![](images/ToBePackaging.png)
+
+The physical packages new to this release are:
+
+* FIPS module. This contains the FIPS Provider that implements a set
+ of algorithms that are FIPS validated and are available via the
+ Core. The FIPS Provider is the OpenSSL FIPS Cryptographic Module
+ 3.0.
+
+ We will not attempt to preclude users from making errors, however
+ we will keep in mind the typical user usage and "safety". By
+ default the FIPS provider will be built and installed.
+
+ We will be able to perform a safety check that detects if the user
+ has modified the source in a FIPS-impactful manner from the
+ release distribution and block building the FIPS provider (on best
+ effort basis) unless an override option is provided.
+
+ We need to ensure there is a mechanism that enables the end user
+ to determine whether or not their usage of the FIPS module is
+ within the allowed uses under a formal validation.
+
+ Versioning of the FIPS module will be aligned with the base
+ OpenSSL version number at the point in time of the
+ validation. Not all OpenSSL releases will need an update to the
+ FIPS module. Therefore when a new FIPS module version is released
+ there may be gaps/jumps in its version number since the previous
+ release.
+
+* Legacy module. This contains implementations of legacy
+ algorithms.
+
+Engines will be built with a provider shim, to allow them to work as
+usual for cases when an ENGINE pointer is passed to some functions,
+and as providers when acting as default implementations. Engines
+compiled for pre-3.0.0 OpenSSL will need to be recompiled to work with
+OpenSSL 3.0.0. Details in
+[The ENGINE API](#the-engine-api) further down.
+
+## Core and Provider Design {#core-and-provider-design}
+
+The interactions relevant for the Core and provider design are shown
+in the diagram below. There are four major components: User
+Application, EVP component, the Core, and a cryptographic
+Provider. (There may be multiple providers, but that is not relevant
+here).
+
+![](images/300ProviderCollab.png)
+
+The Core has the following characteristics:
+
+* It enables Provider discovery, loading, initialisation and
+ unloading
+* It enables property-based algorithm queries
+* It implements caching of algorithm queries and implementation
+ details
+* It operates within a library context that contains data such as
+ global properties, search cache and dispatch tables.
+
+Providers have the following characteristics:
+
+* They provide for access to specific algorithm implementations
+* They associate algorithm implementations with a set of well
+ defined properties
+* They support parameter passing in an implementation agnostic
+ manner
+* They can be loaded at any point in time
+* They have a well-known module entry point
+
+The subsections that follow describe the flow an application uses to
+load a provider, fetch an algorithm implementation, and use it. In
+addition, this section describes in detail how algorithms, properties,
+and parameters are named; how algorithm queries are handled; how
+algorithms are registered and initialized; and how providers are
+loaded.
+
+In order for an application to be able to use an algorithm it must
+first "fetch" an implementation of it through an algorithm query. Our
+design objective is to be able to support both explicit (up front)
+fetching of algorithms and fetching of algorithms on use. By default
+we expect to do fetching on use (e.g. using `EVP_sha256()`) so that
+algorithms are typically fetched during an "init" function and bound
+to a context object (often named `ctx`). The explicit fetching option
+will be implemented via new API calls (e.g. `EVP_MD_fetch()`).
+
+The diagram above shows the explicit fetch approach. The steps are as
+follows:
+
+
+
+1. Every provider needs to be loaded. This will happen implicitly
+ (default provider or specified via configuration) and may also be
+ explicitly requested by the application. Load encompases both
+ dynamic shared object loading (as needed) and initialisation.
+ 1. The Core physically loads the module into memory (not required
+ if default provider is already in memory).
+ 2. The Core calls the provider's entry point for the provider to
+ initialise itself.
+ 1. Within the entry point function, the provider initialises
+ some provider variables using values passed in from the
+ Core. A provider algorithm implementation query callback
+ is returned to the Core if initialization succeeds.
+2. User application requests algorithm by calling a fetch routine.
+ 1. The search by EVP will combine global properties with
+ call-specific ones and an algorithm identity to find the
+ corresponding algorithm implementation, and then create and
+ return a library handle (e.g. `EVP_MD`, `EVP_CIPHER`) to the
+ application.
+ 1. The first search of the implementation dispatch table is
+ made in an internal cache.
+ 2. Should the first search fail, a second search is made by
+ asking the providers if they have an implementation of
+ said algorithm with the queried properties. When this
+ search is done, the resulting data is cached unless the
+ provider opts out of caching, to be used in the first
+ search (2.1.1). For example a PKCS#11 provider may opt out
+ of caching because its algorithms may become available and
+ unavailable over time.
+3. The user application then uses the algorithm via EVP APIs (e.g.,
+ `EVP_DigestInit()`, `EVP_DigestUpdate()`, `EVP_DigestFinal()`,
+ etc).
+ 1. The function pointer is invoked and ends up in the provider
+ for the implementation to perform the requested cryptographic
+ algorithm.
+
+For the existing `EVP_{algorithm}()` functions (e.g. `EVP_sha256()`,
+etc) things remain mostly unchanged. In particular, the fetch call is
+not performed when the `EVP_{algorithm}()` call returns, but rather it
+happens implicitly when the context object (e.g. `EVP_MD_CTX`) is
+bound within the respective EVP init function. Specifically, step 2.1
+happens just before step 3.1. This is known as "implicit
+fetch". Implicit fetch always operates within a default library
+context (see [Library Context](#library-context) below).
+
+The method dispatch table is a list of `<function-id,
+function-pointer>` pairs — where the `function-id`s are publically
+defined and known by OpenSSL — put together with a set of properties
+that can be used to identify each particular implementation. The Core
+can take a property query and find the corresponding dispatch table,
+to be used for applicable operations. This approach allows providers
+to flexibly pass references to functions that the OpenSSL code can use
+to create its method structures dynamically.
+
+Providers can be loaded at any point in time. Unload at any point in
+time can be requested. It is up to the application to ensure that a
+provider is not currently being used or referenced when it is
+unloaded. If an attempt is made to use an implementation that is no
+longer available then an error will be returned.
+
+The assumptions an application can currently make about the return
+from `EVP_{algorithm}()` and not the new fetch approach are:
+
+* const pointer
+* does not need to be freed by the application
+* can safely be compared for checking algorithms are the same
+ (i.e. specifically comparing pointers to `EVP_CIPHER`, `EVP_MD`,
+ etc)
+
+For a direct use of explicit fetch by the application (rather than
+using the existing `EVP_{algorithm}()` functions) the semantics will
+be different:
+
+* non-const pointer
+* needs to be freed by the application
+* pointers can't be safely compared with each other (more on that in
+ the next paragraph)
+
+There will be new APIs to test the equality of objects that can be
+used for both explicitly fetched objects and static variant ones
+These APIs will enable comparison of just the algorithm identity,
+or of specific algorithm implementations.
+
+### Library Context {#library-context}
+
+A library context is an opaque structure that holds library "global"
+data. OpenSSL will provide such a structure, limited to the global
+data that the Core has to keep. Future expansion may come to include
+other existing global data. An application will be able to create and
+destroy one or more library context(s) within which all subsequent
+interactions with the Core operate within. If the application does not
+create and provide its own library context, an internal default one
+will be used.
+
+
+```
+OPENSSL_CTX *OPENSSL_CTX_new();
+void OPENSSL_CTX_free(OPENSSL_CTX *ctx);
+```
+
+A library context can be passed to the explicit fetch functions. If
+`NULL` is passed to them, the internal default context will be used.
+
+More than one library context may be allocated, which implies that any
+provider module may be initialized more than once. This permits an
+application to both be directly linked with libcrypto and loading
+providers it's interested in, as well as being linked with other
+libraries that use their own provider modules, independently.
+
+### Naming {#naming}
+
+Names are required for algorithms, parameters, and properties. In
+order to ensure consistency and to enable external Provider
+implementers to define new names in a consistent way there will be a
+registry of recommended or used names. It will be maintained
+separately from the sources.
+
+The ability to define aliases for names is required because there are
+contexts where there are more than one name for the same thing
+(e.g. EC curves with general names and NIST names for the same
+thing).
+
+### Properties for Algorithm Implementation Selection {#properties-for-algorithm-implementation-selection}
+
+Algorithm implementations (cryptographic and non-cryptographic) will
+have some properties which will be used to select an implementation
+from amongst those available. For 3.0, two properties are defined:
+
+* _is this implementation the default implementation?_
+* _is this implementation FIPS validated_?
+
+The valid input and their meaning are:
+
++---------------------+-----------------------------+------------------------+
+| **Property String** | **Meaning in a definition** | **Meaning in a query** |
++=====================+=============================+========================+
+| `default` | This is the default | Request the default |
+| | implementation | implementation |
++---------------------+-----------------------------+------------------------+
+| `default=yes` | This is the default | Request the default |
+| | implementation | implementation |
++---------------------+-----------------------------+------------------------+
+| `default=no` | This is not the default | Request a non-default |
+| | implementation | implementation |
++---------------------+-----------------------------+------------------------+
+| `fips` | This implementation is FIPS | Request an |
+| | validated. | implementation that is |
+| | | FIPS validated |
++---------------------+-----------------------------+------------------------+
+| `fips=yes` | This implementation is FIPS | Request an |
+| | validated. | implementation that is |
+| | | FIPS validated |
++---------------------+-----------------------------+------------------------+
+| `fips=no` | This implementation is not | Request an |
+| | FIPS validated. | implementation that is |
+| | | not FIPS validated |
+| | | |
++---------------------+-----------------------------+------------------------+
+
+In all cases property names will be defined as printable ASCII
+characters and are case insensitive. Property values may be quoted or
+unquoted. Unquoted values will also always be printable ASCII
+characters and are case insensitive. Quoted values are tested for
+equality on a raw byte comparison basis only.
+
+Providers will be able to provide their own names or values. The full
+syntax of property definitions and queries appear in
+[Appendix 1 - Property Syntax](#appendix-1---property-syntax).
+
+OpenSSL reserves all property names that do not have a period;
+vendor-provided property names must have a period in the name. It is
+expected (but not enforced) that the part of the property name before
+the first period is or relates to the provider's name, to provide some
+level of conflict avoidance via namespacing.
+
+It is likely that additional properties will be defined during the
+development of this release. A likely candidate is `provider` being
+the name of the provider that is supplying the implementation.
+Another possibility is `engine`, meaning that this algorithm is
+implemented by an OpenSSL 1.1.1 dynamically loaded engine masquerading
+as a provider.
+
+There will be a built in global property query string, which will be
+"default".
+
+#### Property-based Algorithm Selection {#property-based-algorithmselection}
+
+Algorithm implementation selection is based on properties.
+
+The provider sets properties on the algorithms it offers. The
+application sets which properties that it wants to see used as a
+filter during algorithm selection - the query.
+
+The desired properties for fetching algorithm implementations can be
+specified in the following places:
+
+1. globally, based on configuration files.
+2. globally, based on API calls.
+3. on a per-object basis for specific objects. E.g. SSL_CTX, SSL.
+
+Properties will be used during algorithm lookup (parameter
+specification of property values).
+
+The sets of properties will be evaluated in a manner that resolves to
+a single value of a property for each specified property
+(keyword). The precedence order for keyword evaluation is:
+
+
+
+1. The per-object or directly specified API parameter to fetch
+1. The global (default) properties set by API calls
+1. The global (default) properties set in configuration files
+
+It is possible that additional property setting methods and evaluation
+approaches will be defined during the development of this release.
+
+By default, OpenSSL 3.0 will load a configuration file (which contains
+global properties and other settings) automatically without explicit
+application API calls. This will occur in libcrypto. Note that in
+OpenSSL 1.1.1 the configuration file is automatically loaded only by
+the default (automatic) initialisation of libssl.
+
+### Parameter Definition {#parameter-definition}
+
+The OpenSSL Core and providers have to exchange data while keeping
+OpenSSL and provider structures opaque. All composite values will be
+passed as an array of items, using the public data structure defined
+in
+[Appendix 2 - OpenSSL parameter passing](#openssl-parameter-passing).
+Parameters will be identified using their name (as a string) and each
+contains its own type and size information.
+
+The Core will define an API to pass an array of parameter values or
+requests for values to a provider or a specific algorithm
+implementation, and for the latter, an associated object handled by
+that implementation. In the cases of the basic machine types, macros
+could be developed to assist in the construction and extraction of
+values.
+
+### Operation and Operation Function Definitions {#operation-and-operation-function-definitions}
+
+While algorithm and parameter names are essentially controlled and
+allocated by the providers, the operations and associated functions
+that are going to be called by libcrypto are essentially controlled
+and allocated by the Core.
+
+For things that are only controlled by the Core, we will use macros to
+name them, with numbers as values to be used as indexes. Allocation
+will be incremental, i.e. for any new operation or function, the next
+number available will be picked.
+
+### Algorithm Query {#algorithm-query}
+
+Each algorithm type (e.g. `EVP_MD`, `EVP_CIPHER` etc) with have a
+"fetch" function available (e.g. `EVP_MD_fetch()`,
+`EVP_CIPHER_fetch()`). Algorithm implementations are identified using
+their name and properties
+
+Each fetch function will use services provided by the Core to find an
+appropriate implementation as described in the introduction of
+[Core and Provider Design](#core-and-provider-design). If an appropriate
+implementation has been found then it is constructed into a suitable
+algorithm structure (e.g. `EVP_MD`, `EVP_CIPHER`) and returned to the
+calling application.
+
+If multiple implementations are equally good matches for the passed
+name and properties, one of these will be returned on retrieval but
+exactly which one is not defined. Furthermore, there is no guarantee
+that the same match would be returned every time.
+
+### Algorithm Query Caching {#algorithm-query-caching}
+
+
+Algorithm queries will be cached together with their result.
+
+The algorithm query cache can be flushed to remove:
+
+* All queries returning a specific algorithm implementation
+* All algorithm implementations from a specific provider
+* All algorithm implementations
+
+### Multilevel Queries {#multilevel-queries}
+
+In order to handle both global properties and properties passed to
+specific calls (such as fetch calls), the global property query
+settings will be merged with the passed property settings except where
+there is a conflict, specifically:
+
+
++--------------------+---------------------+---------------------+
+| **Global Setting** | **Passed Settings** | **Resulting Query** |
++====================+=====================+=====================+
+| `fips=yes` | `fips=yes` | `fips=yes` |
++--------------------+---------------------+---------------------+
+| `fips=yes` | `fips=no` | `fips=no` |
++--------------------+---------------------+---------------------+
+| `fips=yes` | `-fips` | *fips is not |
+| | | specified* |
++--------------------+---------------------+---------------------+
+| `fips=yes` | *fips is not | `fips=yes` |
+| | specified* | |
++--------------------+---------------------+---------------------+
+| `fips=no` | `fips=yes` | `fips=yes` |
++--------------------+---------------------+---------------------+
+| `fips=no` | `fips=no` | `fips=no` |
++--------------------+---------------------+---------------------+
+| `fips=no` | `-fips` | *fips is not |
+| | | specified* |
++--------------------+---------------------+---------------------+
+| `fips=no` | *fips is not | `fips=no` |
+| | specified* | |
++--------------------+---------------------+---------------------+
+| *fips is not | `fips=yes` | `fips=yes` |
+| specified* | | |
++--------------------+---------------------+---------------------+
+| *fips is not | `fips=no` | `fips=no` |
+| specified* | | |
++--------------------+---------------------+---------------------+
+| *fips is not | `-fips` | *fips stays not |
+| specified* | | specified* |
++--------------------+---------------------+---------------------+
+| *fips is not | *fips is not | *fips stays not |
+| specified* | specified* | specified* |
++--------------------+---------------------+---------------------+
+
+
+### Provider Module Loading {#provider-module-loading}
+
+
+Providers can either be built-in or dynamically loadable modules.
+
+All algorithms are implemented by providers. The OpenSSL Core will
+initially have no providers loaded, and therefore will have no
+algorithms available. Providers will need to be discovered and
+loaded. The algorithm implementations contained within them can then
+be queried by the Core at a later time, with those queries possibly
+becoming cached.
+
+If no provider has been loaded at the time of the first fetch
+(implicit as well as explicit), the built in default provider will be
+automatically loaded.
+
+Note that a provider may be written against an older version of the
+Core API than the current version in libcrypto. For example, it will
+have to be possible for users to run a different FIPS provider module
+version than the main OpenSSL version. This means the Core API will
+have to remain stable and backwards compatible (just like any other
+public API).
+
+All of the command line applications supplied as part of the OpenSSL
+build will gain a `-provider xxx` option which loads a provider. This
+option can be specified multiple times on the command line (as
+multiple providers can always be loaded) and it isn't an error if the
+provider remains unused for any specific operation (e.g. loading a
+provider that only supplies AES when doing a SHA256 digest).
+
+#### Finding and loading dynamic provider modules {#finding-and-loading-dynamic-provider-modules}
+
+Dynamic provider modules are `.so` files on UNIX type operating
+systems, or a `.dll` file on Windows type operating systems, or
+whatever corresponds on other operating systems. By default, they
+will be installed in a well known directory.
+
+Provider module loading can occur several ways:
+
+* **On demand**, the application will have to specify exactly what
+ provider modules should be loaded.
+* **By configuration**, the set of provider modules to load would be
+ specified in a configuration file.
+
+Some of these methods may be combined.
+
+A provider module can be specified by full path, and can therefore be
+loaded even if it isn't located in the well known directory.
+
+After the Core loads a provider module, it calls the provider module
+entry point.
+
+#### Provider Module Entry Point {#provider-module-entry-point}
+
+A provider module _must_ have the following well known entry point:
+
+```
+int OSSL_provider_init(const OSSL_PROVIDER *provider,
+ const OSSL_DISPATCH *in,
+ const OSSL_DISPATCH **out);
+```
+
+If the entry point does not exist in the dynamically loaded object,
+then it is not a valid module and loading it will fail.
+
+`in` is an array of functions that the Core passes to the provider.
+
+`out` is an array of provider functions that the provider passes back
+to the Core.
+
+`provider` is a handle to a provider object belonging to the Core.
+This can serve as a unique provider identity which may be required in
+some API calls. This object will also be populated with diverse data,
+such as module path, NCONF configuration structure for the provider
+(see [CONF / NCONF values as parameters](#conf-nconf-values-as-parameters)
+below for an idea on how that would be implemented), and these diverse
+values can then be retrieved by the provider using a params getter
+callback that the Core provides. The type `OSSL_PROVIDER` is opaque.
+
+`OSSL_DISPATCH` is an open structure that implements the `< function-id,
+function-pointer >` tuple mentioned in the introduction of
+[Core and Provider Design](#core-and-provider-design):
+
+
+```
+typedef struct ossl_dispatch_st {
+ int function_id;
+ void *(*function)();
+} OSSL_DISPATCH;
+```
+
+
+The `funcion_id` identifies a specific function, and `function` is the
+pointer to that function. An array of these is terminated with
+`function_id` set to zero.
+
+The provider module may or may not be linked against libcrypto. If it
+is not then it will have no direct access to any libcrypto
+functions. All essential communication back to libcrypto will be via
+callback functions provided by the Core. It is important that memory
+allocated by specific providers is freed by the same
+providers. Similarly memory allocated in libcrypto should be freed by
+libcrypto.
+
+The API will specify a well known set of callback function
+numbers. More function numbers can be added in later releases as
+required without breaking backwards compatibility.
+
+
+```
+/* Functions provided by the Core to the provider */
+#define OSSL_FUNC_ERR_PUT_ERROR 1
+#define OSSL_FUNC_GET_PARAMS 2
+/* Functions provided by the provider to the Core */
+#define OSSL_FUNC_PROVIDER_QUERY_OPERATION 3
+#define OSSL_FUNC_PROVIDER_TEARDOWN 4
+```
+
+
+The Core will set up an array of the well known callback functions:
+
+
+```
+static OSSL_DISPATCH core_callbacks[] = {
+ { OSSL_FUNC_ERR_PUT_ERROR, ERR_put_error },
+ /* int ossl_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]); */
+ { OSSL_FUNC_GET_PARAMS, ossl_get_params, }
+ /* ... and more */
+};
+```
+
+This is only a few of the functions that the Core may see fit to pass
+to a provider. We may also pass functions to help with logging,
+testing, instrumentation etc as the need comes up.
+
+Once the module is loaded and the well known entry point located, the
+init entry point can be invoked by the Core:
+
+```
+/*
+ * NOTE: this code is meant as a simple demonstration of what could happen
+ * in the core. This is an area where the OSSL_PROVIDER type is not opaque.
+ */
+OSSL_PROVIDER *provider = OSSL_PROVIDER_new();
+const OSSL_DISPATCH *provider_callbacks;
+/*
+ * The following are diverse parameters that the provider can get the values
+ * of with ossl_get_params.
+ */
+/* reference to the loaded module, or NULL if built in */
+provider->module = dso;
+/* reference to the path of the loaded module */
+provider->module_path = dso_path;
+/* reference to the NCONF structure used for this provider */
+provider->conf_module = conf_module;
+
+if (!OSSL_provider_init(provider, core_callbacks, &provider_callbacks))
+ goto err;
+
+/* populate |provider| with functions passed by the provider */
+while (provider_callbacks->func_num > 0) {
+ switch (provider_callbacks->func_num) {
+ case OSSL_FUNC_PROVIDER_QUERY_OPERATION:
+ provider->query_operation = provider_callbacks->func;
+ break;
+ case OSSL_FUNC_PROVIDER_TEARDOWN:
+ provider->teardown = provider_callbacks->func;
+ break;
+ }
+ provider_callbacks++;
+}
+```
+
+
+The `OSSL_provider_init` entry point does not register any algorithms
+that will be needed, but it will return at least these two callbacks
+to enable this process:
+
+
+
+1. `OSSL_FUNC_QUERY_OPERATION`, which is used to find out what
+ implementations of an operation are available. This must return
+ an array of `OSSL_ALGORITHM` (see further down), which maps
+ algorithm names and property definition strings to implementation
+ dispatch tables. This function must also be able to indicate if
+ the resulting array may be cached by the Core or not. This is
+ explained in further detail below.
+1. `OSSL_FUNC_TEARDOWN`, which is used when the provider is unloaded.
+
+The provider register callback can only be run after the
+`OSSL_provider_init()` call succeeds.
+
+#### Provider Initialisation and Algorithm Registration {#provider-initialisation-and-algorithm-registration}
+
+
+An algorithm offers a set of operations (capabilities, features,
+etc). The operations are invoked via functions. For example, the RSA
+algorithm offers signing and encryption (two operations) which are
+invoked via the _init_, _update_, _final_ functions for signing and
+_init_, _update_, _final _ functions for encryption. The set of
+functions is determined by the implementation of the upper-level EVP
+code.
+
+Operations are identified by a unique number. For example:
+
+
+```
+#define OSSL_OP_DIGEST 1
+#define OSSL_OP_SYM_ENCRYPT 2
+#define OSSL_OP_SEAL 3
+#define OSSL_OP_DIGEST_SIGN 4
+#define OSSL_OP_SIGN 5
+#define OSSL_OP_ASYM_KEYGEN 6
+#define OSSL_OP_ASYM_PARAMGEN 7
+#define OSSL_OP_ASYM_ENCRYPT 8
+#define OSSL_OP_ASYM_SIGN 9
+#define OSSL_OP_ASYM_DERIVE 10
+```
+
+For a provider to make an algorithm usable by libcrypto, it must
+register an operation querying callback, which returns an array of
+implementation descriptors, given an operation identity:
+
+
+ < algorithm name, property definition string, implementation `OSSL_DISPATCH*` >
+
+So for example, this query callback will return the list of all its
+digests if the given operation is `OSSL_OP_DIGEST`.
+
+Algorithms are identified by a string.
+
+The Core provides a set of services for the provider to use in the
+form of a function table.
+
+A provider will also offer a service for returning information (in the
+form of parameters as specified in
+[Appendix 2 - Parameter Passing](#appendix-2---parameter-passing)) via a callback provided by the
+provider, such as:
+
+
+* version number
+* Build strings - as per the current OpenSSL related build
+ information (only at the provider level)
+* Provider name
+
+
+An individual operation may require multiple function callbacks to be
+defined in order to implement the operation. Each function will be
+identified by a numeric function identity. Each of the identities are
+unique for the combination of operation and function, i.e. the number
+assigned to the init function of the digest operation cannot be reused
+for init functions for other operations, those will have their own
+unique numbers. For example, for the digest operation, these functions
+are required:
+
+```
+#define OSSL_OP_DIGEST_NEWCTX_FUNC 1
+#define OSSL_OP_DIGEST_INIT_FUNC 2
+#define OSSL_OP_DIGEST_UPDATE_FUNC 3
+#define OSSL_OP_DIGEST_FINAL_FUNC 4
+#define OSSL_OP_DIGEST_FREECTX_FUNC 5
+typedef void *(*OSSL_OP_digest_newctx_fn)(const OSSL_PROVIDER *prov);
+typedef int (*OSSL_OP_digest_init_fn)(void *ctx);
+typedef int (*OSSL_OP_digest_update_fn)(void *ctx, void *data, size_t len);
+typedef int (*OSSL_OP_digest_final_fn)(void *ctx, void *md, size_t mdsize,
+ size_t *outlen);
+typedef void (*OSSL_OP_digest_freectx_fn)(void *ctx);
+```
+
+An all in one version is also advisable for devices that cannot handle
+multi-part operations:
+
+```
+#define OSSL_OP_DIGEST_FUNC 6
+typedef int (*OSSL_OP_digest)(const OSSL_PROVIDER *prov,
+ const void *data, size_t len,
+ unsigned char *md, size_t mdsize,
+ size_t *outlen);
+```
+
+
+A provider then defines arrays containing the set of functions for
+each algorithm implementation and one array of algorithm descriptors
+for each operation. The algorithm descriptor was mentioned higher up,
+and would be publically defined like this:
+
+
+```
+typedef struct ossl_algorithm_st {
+ const char *name;
+ const char *properties;
+ OSSL_DISPATCH *impl;
+} OSSL_ALGORITHM;
+```
+
+For example (and it is only an example, providers may arrange these
+things any way they want, the important thing is what the algorithm
+querying function such as `fips_query_operation` below returns) the
+FIPS module may define arrays like this for the SHA1 algorithm:
+
+
+```
+static OSSL_DISPATCH fips_sha1_callbacks[] = {
+ { OSSL_OP_DIGEST_NEWCTX_FUNC, fips_sha1_newctx },
+ { OSSL_OP_DIGEST_INIT_FUNC, fips_sha1_init },
+ { OSSL_OP_DIGEST_UPDATE_FUNC, fips_sha1_update },
+ { OSSL_OP_DIGEST_FINAL_FUNC, fips_sha1_final },
+ { OSSL_OP_DIGEST_FUNC, fips_sha1_digest },
+ { OSSL_OP_DIGEST_FREECTX_FUNC, fips_sha1_freectx },
+ { 0, NULL }
+};
+static const char prop_fips[] = "fips";
+static const OSSL_ALGORITHM fips_digests[] = {
+ { "sha1", prop_fips, fips_sha1_callbacks },
+ { "SHA-1", prop_fips, fips_sha1_callbacks }, /* alias for "sha1" */
+ { NULL, NULL, NULL }
+};
+```
+
+The FIPS provider init module entry point function might look like
+this:
+
+``` C
+static int fips_query_operation(const OSSL_PROVIDER *provider,
+ int op_id, const OSSL_ALGORITHM **map)
+{
+ *map = NULL;
+ switch (op_id) {
+ case OSSL_OP_DIGEST:
+ *map = fips_digests;
+ break;
+ }
+ return *map != NULL;
+}
+
+#define param_set_string(o,s) do { \
+ (o)->buffer = (s); \
+ (o)->data_type = OSSL_PARAM_UTF8_STRING_PTR; \
+ if ((o)->result_size != NULL) *(o)->result_size = sizeof(s); \
+} while(0)
+static int fips_get_parms(const OSSL_PROVIDER *provider,
+ OSSL_PARAM *outparams)
+{
+ while (outparams->key != NULL) {
+ if (strcmp(outparams->key, "provider.name") == 0) {
+ param_set_string(outparams, "OPENSSL_FIPS");
+ } else if if (strcmp(outparams->key, "provider.build") == 0) {
+ param_set_string(outparams, OSSL_FIPS_PROV_BUILD_STRING);
+ }
+ }
+ return 1;
+}
+
+OSSL_DISPATCH provider_dispatch[] = {
+ { OSSL_FUNC_PROVIDER_QUERY_OPERATION, fips_query_operation },
+ { OSSL_FUNC_PROVIDER_GET_PARAMS, fips_get_params },
+ { OSSL_FUNC_PROVIDER_STATUS, fips_get_status },
+ { OSSL_FUNC_PROVIDER_TEARDOWN, fips_teardown },
+ { 0, NULL }
+};
+static core_put_error_fn *core_put_error = NULL;
+static core_get_params_fn *core_get_params = NULL;
+
+int OSSL_provider_init(const OSSL_PROVIDER *provider,
+ const OSSL_DISPATCH *in,
+ const OSSL_DISPATCH **out)
+{
+ int ret = 0;
+
+ /*
+ * Start with collecting the functions provided by the core
+ * (we could write it more elegantly, but ...)
+ */
+ while (in->func_num > 0) {
+ switch (in->func_num) {
+ case OSSL_FUNC_ERR_PUT_ERROR:
+ core_put_error = in->func;
+ break;
+ case OSSL_FUNC_GET_PARAMS:
+ core_get_params = in->func;
+ Break;
+ }
+ in++;
+ }
+
+ /* Get all parameters required for self tests */
+ {
+ /*
+ * All these parameters come from a configuration saying this:
+ *
+ * [provider]
+ * selftest_i = 4
+ * selftest_path = "foo"
+ * selftest_bool = true
+ * selftest_name = "bar"
+ */
+ OSSL_PARAM selftest_params[] = {
+ { "provider.selftest_i", OSSL_PARAM_NUMBER,
+ &selftest_i, sizeof(selftest_i), NULL },
+ { "provider.selftest_path", OSSL_PARAM_STRING,
+ &selftest_path, sizeof(selftest_path), &selftest_path_ln },
+ { "provider.selftest_bool", OSSL_PARAM_BOOLEAN,
+ &selftest_bool, sizeof(selftest_bool), NULL },
+ { "provider.selftest_name", OSSL_PARAM_STRING,
+ &selftest_name, sizeof(selftest_name), &selftest_name_ln },
+ { NULL, 0, NULL, 0, NULL }
+ }
+ core_get_params(provider, selftest_params);
+ }
+
+ /* Perform the FIPS self test - only return params if it succeeds. */
+ if (OSSL_FIPS_self_test()) {
+ *out = provider_dispatch;
+ return 1;
+ }
+ return 0;
+}
+```
+
+### Algorithm Selection {#algorithm-selection}
+
+
+Multiple providers may be available at any one time. Existing
+application code re-compiled for this version should continue to
+work. At the same time it should be possible with minor code
+adjustments to be able to find and use algorithms using the new
+property based algorithm lookup capability.
+
+To illustrate how this might work, the code below is an example of how
+a simple AES-CBC-128 encryption might be done using OpenSSL 1.1.1. All
+error handling has been stripped out for simplicity.
+
+``` C
+EVP_CIPHER_CTX *ctx;
+EVP_CIPHER *ciph;
+
+ctx = EVP_CIPHER_CTX_new();
+ciph = EVP_aes_128_cbc();
+EVP_EncryptInit_ex(ctx, ciph, NULL, key, iv);
+EVP_EncryptUpdate(ctx, ciphertext, &clen, plaintext, plen);
+EVP_EncryptFinal_ex(ctx, ciphertext + clen, &clentmp);
+clen += clentmp;
+
+EVP_CIPHER_CTX_free(ctx);
+```
+
+In OpenSSL 3.0, such code would continue to work and would use
+algorithms from a provider (assuming nothing else has been configured,
+it will be the default provider). It could also be rewritten using
+explicit fetching as follows. Explicit fetching also enables the
+application to specify a non-default library context if required
+(`osslctx` in this example):
+
+
+```
+
+EVP_CIPHER_CTX *ctx;
+EVP_CIPHER *ciph;
+
+ctx = EVP_CIPHER_CTX_new();
+ciph = EVP_CIPHER_fetch(osslctx, "aes-128-cbc", NULL); /* <=== */
+EVP_EncryptInit_ex(ctx, ciph, NULL, key, iv);
+EVP_EncryptUpdate(ctx, ciphertext, &clen, plaintext, plen);
+EVP_EncryptFinal_ex(ctx, ciphertext + clen, &clentmp);
+clen += clentmp;
+
+EVP_CIPHER_CTX_free(ctx);
+EVP_CIPHER_free(ciph); /* <=== */
+```
+
+
+An application may wish to use algorithms from a different provider.
+
+For example, consider the scenario where an application wishes to use
+some algorithms from the FIPS provider, but still use the default
+algorithms in certain cases. This could be implemented in different
+ways, e.g.
+
+
+
+1. Only use FIPS algorithms.
+2. Default to using FIPS algorithms. Be able to override it on an "as
+ needed" basis to get access to a non FIPS algorithm.
+3. Default to not caring about FIPS algorithms. Be able to override
+ it on an "as needed" basis to get a FIPS algorithm.
+
+#### Only FIPS {#only-fips}
+
+Compared to code written for pre-3.0.0 OpenSSL, all you need to do to
+only get FIPS implementations is something like this:
+
+``` C
+int main(void)
+{
+ EVP_set_default_alg_properties(NULL, "fips=yes"); /* <=== */
+ ...
+}
+```
+
+Then the above encryption code that uses `EVP_aes_128_cbc() `would
+continue to work as before. The `EVP_EncryptInit_ex()` call would use
+those default algorithm properties, and then look it up via the Core
+in order to get a handle to the FIPS implementation. This
+implementation would then be associated with the `EVP_CIPHER_CTX`
+object. If there isn't a suitable algorithm implementation available
+then the the `EVP_Encrypt_init_ex()` call will fail.
+
+The first parameter to `EVP_set_default_alg_properties` is the library
+context, NULL being the default internal one.
+
+#### Default to FIPS but allow an override {#default-to-fips-but-allow-an-override}
+
+To default to using FIPS algorithms but override it on an _as needed_
+basis to non-FIPS algorithms, the application might instead do this,
+compared to code written for pre-3.0.0 OpenSSL:
+
+``` C
+int main(void)
+{
+ EVP_set_default_alg_properties(osslctx, "fips=yes"); /* <=== */
+ ...
+}
+
+EVP_CIPHER_CTX *ctx;
+EVP_CIPHER *ciph;
+
+ctx = EVP_CIPHER_CTX_new();
+ciph = EVP_CIPHER_fetch(osslctx, "aes-128-cbc", "fips!=yes"); /* <=== */
+EVP_EncryptInit_ex(ctx, ciph, NULL, key, iv);
+EVP_EncryptUpdate(ctx, ciphertext, &clen, plaintext, plen);
+EVP_EncryptFinal_ex(ctx, ciphertext + clen, &clentmp);
+clen += clentmp;
+
+EVP_CIPHER_CTX_free(ctx);
+EVP_CIPHER_free(ciph); /* <=== */
+```
+
+Here the `EVP_CIPHER_fetch()` call would combine properties from:
+
+1. The default algorithm properties
+2. The properties passed in as a parameter (with the passed in
+ properties taking precedence).
+
+Because the `EVP_CIPHER_fetch()` call overrides the default "fips"
+property it will look for an implementation of AES-CBC-128 that is not
+"fips".
+
+In this example, we see a non-default library context being used.
+This is only possible with explicitly fetched implementations.
+
+(note for the attentive: `"fips!=yes"` could as well be `"fips=no"`,
+but is provided here as an example of the "not equal to" operator)
+
+#### Default to not caring and allow override for FIPS {#default-to-not-caring-and-allow-override-for-fips}
+
+To default to not using FIPS algorithms but override it on an _as
+needed_ basis to use FIPS, the application code might look like this,
+compared to code written for pre-3.0.0 OpenSSL:
+
+``` C
+EVP_CIPHER_CTX *ctx;
+EVP_CIPHER *ciph;
+
+ctx = EVP_CIPHER_CTX_new();
+ciph = EVP_CIPHER_fetch(osslctx, "aes-128-cbc", "fips=yes"); /* <=== */
+EVP_EncryptInit_ex(ctx, ciph, NULL, key, iv);
+EVP_EncryptUpdate(ctx, ciphertext, &clen, plaintext, plen);
+EVP_EncryptFinal_ex(ctx, ciphertext + clen, &clentmp);
+clen += clentmp;
+
+EVP_CIPHER_CTX_free(ctx);
+EVP_CIPHER_free(ciph); /* <=== */
+```
+
+In this version we have not overridden the default algorithm
+properties in "main", and therefore you get the standard
+out-of-the-box defaults which are to not mandate the use of
+FIPS. However we've explicitly set the "fips" property at the
+`EVP_CIPHER_fetch()` level, and so that overrides the default. When
+`EVP_CIPHER_fetch()` looks up the algorithm using the Core it will get
+a reference to the FIPS one (or fail if no such algorithm is
+available).
+
+#### Asymmetric algorithm selection {#asymmetric-algorithm-selection}
+
+Note that for symmetric encryption/decryption and for message digests
+there are existing OpenSSL objects that can be used to represent an
+algorithm, i.e. `EVP_CIPHER` and `EVP_MD`. For asymmetric algorithms
+there is no equivalent object. The algorithm in use is inferred
+implicitly from the type of the `EVP_PKEY`.
+
+In order to solve this problem a new asymmetric algorithm object will
+be introduced. In the example below an ECDH key derivation is
+performed. We lookup a FIPS ECDH implementation (assuming we _know_
+that the given private key is an ECC one, of course) using a new
+algorithm object, `EVP_ASYM`:
+
+``` C
+EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(privkey, NULL);
+EVP_ASYM *asym = EVP_ASYM_fetch(osslctx, EVP_PKEY_EC, "fips=yes");
+EVP_PKEY_CTX_set_alg(pctx, asym));
+EVP_PKEY_derive_init(pctx);
+EVP_PKEY_derive_set_peer(pctx, pubkey);
+EVP_PKEY_derive(pctx, out, &outlen);
+EVP_PKEY_CTX_free(pctx);
+```
+
+### Example dynamic views of algorithm selection {#example-dynamic-views-of-algorithm-selection}
+
+The sequence diagram below shows an example of how the SHA256
+algorithm might be selected and invoked from the default provider.
+
+![](images/DigestExplicit.png)
+
+Note that each EVP layer call is implemented by thin wrappers in the
+EVP layer, which invoke similarly named functions within the provider
+on an algorithm by algorithm basis. The specific provider functions to
+be used will be looked up in the Core Dispatcher tables via an
+explicit `EVP_MD_fetch()` call that specifies the message digest name as a
+string and any other relevant properties. The returned "md" object contains
+function pointers to the implementation of the algorithm in the selected
+provider.
+
+The `EVP_MD_CTX` object is not passed through to the provider since we
+do not know whether any specific provider module is linked against
+libcrypto. Instead we simply pass through a black box handle (`void *`
+pointer), which the provider will associate with whatever structure it
+requires. This is allocated during an explicit `digestNewCtx()` call
+to the provider at the beginning of the operation, and freed at the
+end with a `digestFreeCtx()` call.
+
+The next diagram shows a slightly more complex scenario, i.e. an
+`EVP_DigestSign*` operation using RSA and SHA256. This diagram is
+drawn from the perspective of libcrypto with algorithms being provided
+by the FIPS module. A later section will examine this scenario from
+the perspective of the FIPS module.
+
+![](images/DigestSignFIPSExplicit.png)
+
+An `EVP_DigestSign*` operation is more complicated because it involves
+two algorithms: a signing algorithm, and a digest algorithm. In
+general those two algorithms may come from different providers or the
+same one. In the case of the FIPS module the algorithms must both come
+from the same FIPS module provider. The operation will fail if an
+attempt is made to do otherwise.
+
+In spite of the added complexity of having two algorithms the same
+concepts apply as for the simpler `EVP_Digest*` operation shown in the
+earlier diagram. There are two contexts produced: an `EVP_MD_CTX` and
+an `EVP_PKEY_CTX`. Neither of these are passed through to the
+provider. Instead black box (`void *`) handles are created via
+explicit "newCtx" provider calls, and then those handles are passed
+through during subsequent "init", "update" and "final" operations.
+
+The algorithms are looked up in the Core dispatch tables using
+explicit `EVP_MD_fetch()` and `EVP_ASYM_fetch()` calls in advance.
+
+## FIPS Module {#fips-module}
+
+This is a
+[FIPS 140-2](https://csrc.nist.gov/publications/detail/fips/140/2/final)
+validated cryptographic module. It is a
+[provider](#core-and-provider-design) that contains FIPS
+validated/approved cryptographic algorithms only. Non FIPS algorithms
+will be supplied by the default provider (not the FIPS module).
+
+The module is dynamically loadable - static linking is not supported.
+
+The FIPS Module will itself not have a "FIPS mode". The OpenSSL that
+can use the FIPS provider will have a "mode" concept that is
+compatible with the FIPS Module 2.0.0.
+
+### FIPS Module Version Numbering {#fips-module-version-numbering}
+
+
+The version will be FIPS module 3.0
+
+Any subsequent revisions will be labelled in a similar manner to
+previous releases i.e 3.0.x.
+
+For change letters or revalidations the version number of the FIPS
+Module will be updated to match the current version of the OpenSSL
+library.
+
+### Detection of Changes inside the FIPS Boundary {#detection-of-changes-inside-the-fips-boundary}
+
+For the sake of validation, we need to detect if any relevant source
+has changed.
+
+This can be done with a script that tokenizes the C sources the same
+way a C preprocessor does, but that is also taught to ignore certain
+parts of the source:
+
+
+
+* System `#include` directives.
+* Code that is conditioned away in FIPS mode (as described in
+ [Conditional Code](#conditional-code) below).
+
+(reminder: a C preprocessor can, but doesn't not have to, collapse all
+non-newline whitespace and leave a standard single space between every
+token, and comments are considered to be whitespace for this purpose)
+
+The result of the tokenization process can then go through a checksum,
+which is stored in a file parallel to the source file and ultimately
+version controlled.
+
+The process will be something like this (not exactly, this is a code
+example to show the overall process):
+
+``` shell
+ for f in $(FIPS_SOURCES); do
+ perl ./util/fips-tokenize $f | openssl sha256 -r
+ done | openssl sha256 -hex -out fips.checksum
+```
+
+There will also be some mechanism that alerts us of changes so we can take appropriate action. For example:
+
+
+``` shell
+ git diff --quiet fips.checksum || \
+ (git rev-parse HEAD > fips.commit; scream)
+```
+
+
+What `scream` should actually do is still to be determined.
+
+Updating `fips.checksum` should happen as part of a normal `make
+update`, which is the usual method to change and check changes on
+files that are version controlled. OpenSSL's CIs already run this to
+see that nothing was forgotten, and breaks the build if something was
+changed by this command. Running `make update` is also part of the
+normal OpenSSL release process.
+
+#### How to react to a change of the signed checksum {#how-to-react-to-a-change-of-the-signed-checksum}
+
+
+In spite of `scream`, a changed checksum in our repo isn't very
+dramatic per se, it simply notifies us that we need to pay some extra
+attention to the FIPS source.
+
+Two possibilities:
+
+1. _When it's soon time for a release_ and `fips.checksum` no longer
+ contains the checksum from the last validated source, send the
+ FIPS source to the lab and get the update validation process
+ started.
+2. _At the same time as a release is made_ `fips.checksum` no longer
+ contains the checksum from the last validated source, send the
+ FIPS source to the lab (including diff files and a change list)
+ and get the appropriate update validation process started.
+
+The list of validated checksums will be listed _somewhere else_ (to be
+specified later)
+
+#### Compiling {#compiling}
+
+For each FIPS provider source file, we calculate that file's checksum
+and check it against the collected checksum in `fips.checksum`, and
+refuse to compile if there's a mismatch.
+
+### FIPS Mode {#fips-mode}
+
+The FIPS module only contains FIPS validated cryptographic
+algorithms. Any FIPS mode 'switching logic' will be outside the FIPS
+module boundary - this will be handled by the "fips" property.
+
+[Conditional code](#conditional-code) related to FIPS mode is
+discussed in a separate section.
+
+The following FIPS API's will continue to be available for application
+use (for consistency the same names present in 1.1.1 are used):
+
+* `int FIPS_mode_set(int on)`
+
+ Ensures that "fips=yes" is set (for `on != 0`) or "fips" is unset
+ (for `on == 0`) in the current global property setting. This will
+ also attempt to fetch the `HMAC-SHA256` algorithm with the
+ property "fips=yes" and ensure that it successfully returns.
+
+* `int FIPS_mode(void)`
+
+ Returns 1 if the current global property string contains the
+ property "fips=yes" (or "fips"), 0 otherwise.
+
+ We could check if there is any provider available that offers a
+ FIPS algorithm currently and handle this a little differently.
+
+* `int FIPS_self_test(void)`
+
+ If the `FIPS_mode()` returns true then this runs the KATs.
+
+ The integrity test will not be covered. That will be a separate
+ function if we decide to provide it.
+
+ Returns 1 on success; 0 on failure or there being no OpenSSL FIPS
+ provider.
+
+Note: these functions will only operate in the context of the OpenSSL
+FIPS provider - not in the context of any other FIPS provider. These
+are legacy, deprecated interfaces. The
+`EVP_set_default_alg_properties()` function(s) should be used for
+non-legacy configuration.
+
+### Roles and Authentication {#roles-and-authentication}
+
+There are two implied roles - Cryptographic Officer (CO) and
+User. Both roles support all the same services. The only difference is
+that the CO installs the software. The module should not support user
+authentication (it is not required for level 1). This can all be
+explained in the security policy without any specific code.
+
+### Finite State Model (FIPS 140-2 section 4.4) {#finite-state-model}
+
+A state machine needs to be defined.
+
+We will require the following:
+
+* Self test states - initialisation, running, self test, error,
+ shutdown, (and potentially post_triggered)
+* Error States - If a self test fails the module should return an
+ error for that operation. It is permissible to try to clear the
+ error and repeat the operation. If failure persists, the module
+ should enter an error state. This can either be a hard error
+ state where all cryptographic operations fail or a reduced
+ functionality state where the failing components only return error
+ when used.
+
+ Failing a self test can be triggered by:
+
+ 1. Continuous tests (key pair gen pairwise test (sign/verify) and
+ random number compare test from entropy source to verify
+ random number inputs into the DRBG are not the same).
+ 2. DRBG health tests - this can be made to cause an error always
+ just in the RNG (rather than setting a global error
+ state)[^1].
+ 3. POST Integrity test failure either at install, startup, or on
+ demand.
+ 4. POST KAT failure at startup, or on demand.
+
+ An internal API will be supplied to set the failure state for the above cases.
+
+#### State Machine {#state-machine}
+
+States which are not present in the state machine are shown dotted.
+The edges into and out of the error state are dashed to indicate that
+they are not expected to be traversed.
+
+![](images/300FIPSStateMachine.png){style="float: right"}
+
+The state model consists of these states:
+
+1. **Power Off**: the FIPS module is not loaded into an application
+ and the shared library is not in memory.
+2. **Power On**: the FIPS module has been loaded by an application
+ and the shared library is in memory. Default Entry Point
+ Constructors will be initiated.
+3. **Initialisation**: `OSSL_provider_init` is called.
+4. **Integrity Check (POST Integrity)**: the module checksums itself
+ and verifies that it hasn't been inadvertently altered.
+
+ (This is run during the FIPS providers `OSSL_provider_init()`).
+
+5. **Self Test (POST KAT)**: the FIPS module is performing its POST
+ during installation or the POST on demand from an API call.
+6. **Running**: the FIPS module is in its normal operating state.
+ All APIs can be used and continuous testing is in force.
+7. **Error**: the FIPS module has entered an error state. All
+ cryptographic APIs will return an error when called.
+8. **Shutdown**: the FIPS module is being terminated and unloaded
+ from the using application.
+
+The edges between states are:
+
+1. **Power Off** to **Power On**: this transition is performed by the
+ operating system when loading the shared library into an
+ application.
+2. **Power On** to **Initialisation**: this transition occurs when
+ the shared library constructor is called.
+3. **Power On** to **Shutdown**: this transition is triggered if the
+ constructor cannot be called or if it fails.
+4. **Initialisation **to **Integrity Check**: this transition occurs
+ when the initialisation code has completed. The module integrity
+ checksum is computed and compared to the expected value.
+5. **Initialisation **to **Error**: this transition is triggered if
+ the initialisation code encounters an error before the self tests
+ are initiated.
+6. **Integrity Check** to **Running**: this transition occurs for all
+ startup where the integrity checks succeed after initial
+ installation.
+7. **Integrity Check** to **Self Test**: this transition occurs
+ during installation when the integrity checks succeed.
+8. **Integrity Check** to **Error**: this transition is triggered if
+ the integrity check fails.
+9. **Running **to **Shutdown**: this transition occurs when the FIPS
+ module is being finalised.
+10. **Running **to **Error**: this transition is triggered if one of
+ the continuous tests fail.
+11. **Running **to **Self Test**: this transition is triggered by the
+ application when it initiates the self tests manually. The
+ integrity checks are not rerun.
+12. **Self Test** to **Running**: this transition occurs when the
+ self tests pass.
+13. **Self Test** to **Error**: this transition is triggered if the
+ self tests fail.
+14. **Shutdown **to **Power Off**: this transition occurs when the
+ FIPS module is unloaded from the memory of the application.
+15. **Error **to **Shutdown**: this transition occurs when the FIPS
+ module is being finalised.
+
+If possible, we should aim to have algorithms registered only in the
+running state. Any transition into the running state should allow
+registration / caching of cryptographic algorithms and any transition
+into the error or shutdown states should flush all cached algorithms
+from libcrypto. By taking this approach, we obviate the need to check
+the state in all the cryptographic factory functions. This avoids
+special case access for the self tests (when started manually) while
+denying access to external callers.
+
+### Services {#services}
+
+The FIPS module provides the following services.
+
+* Show status. This returns 1 if the 'Running' state is active
+ otherwise it returns 0.
+* Cryptographic services such as HMAC, SHS, Encryption. See
+ [Algorithms](#appendix-3---algorithms).
+* Self Test (POST On Demand) - A public API FIPS_self_test() in
+ libcrypto will be used to access this method. The method used must
+ be the same one that is triggered during initialization. The
+ Security Policy will state that this may only be accessed while no
+ other cryptographic services are running.
+* Key Zeroization. See [CSP/Key Zeroization](#csp-key-zeroization).
+
+Services are only operational in the running state. Any attempts to
+access services in any other state will result in an error being
+returned. If the POST fails then any attempt to access any service
+should result in an error being returned.
+
+### Self Testing {#self-testing}
+
+Self-testing consists of power-on self-tests (POST) and run-time tests
+(such as ensuring entropy isn't repeated as input to the RNG).
+
+The POST consists of a module integrity check (which runs each time a
+FIPS-using application runs) as well as algorithm KATs (which can be
+run once at installation time).
+
+The POST tests run during the call to the FIPS modules
+`OSSL_provider_init()` entry point.
+
+In order to implement the Integrity Test and KAT in the proper order,
+the module needs access to the following data items:
+
+1. Path to the library;
+2. HMAC-SHA256 of the library contents (or path to the file with
+ that);
+3. An indication that the library has been installed and the KAT has
+ passed; and
+4. HMAC-SHA256 of that indicator.
+
+These values will be part of the parameters that can be retrieved
+through the `OSSL_PROVIDER` object and associated `OSSL_PARAM`
+getter. A "safer" get-value function that doesn't expand environment
+variables, etc. will be used to fetch the values. In addition,
+functions to access and return the library contents (probably
+BIO-based by having the Core pass a select number of BIO functions in
+its dispatch table) will also have to be passed into the module so
+that it can generate its own digest of the library.
+
+A new OpenSSL "fips" application will provide install (run the KAT and
+output data for the config file) and check (see if the values in the
+config file are valid) capabilities.
+
+The module's Default Entry Point (DEP), the ".init" function in Linux
+libraries, will set a module variable (probably the state
+variable). This variable will be checked in the OSSL_provider_init()
+and, if set (which it always will be), will verify the values in the
+file. This two-step process meets the FIPS requirement of having the
+DEP ensure the tests are run, but allows us to implement the tests
+when the rest of the module is being initialized during normal
+operation.
+
+As part of the build process the integrity checksum of the FIPS module
+must be saved to a file. This could be done as a script. It is just a
+HMAC_SHA256 of the entire FIPS module file with a known fixed key. If
+the library is signed then the checksum would have to be calculated
+after the signature is applied.
+
+A fixed key of at least 112 bits will be embedded in the FIPS module
+for all HMAC integrity operation(s), this key will also be made
+available to the external build script.
+
+For testing purposes all active POST tests run even if one or more of
+them fail.
+
+#### Integrity Checksum Location {#integrity-checksum-location}
+
+The integrity checksum will be saved into a seperate file during
+installation. This file will be in the same location as the FIPS module
+itself by default, but may be configured to be in a different
+location.
+
+#### Known Answer Tests {#known-answer-tests}
+
+The purpose of a KAT is to perform a health-check of the cryptographic
+module to identify catastrophic failures or alterations of the module
+between power cycles and not that the implementation is correct.
+
+There are
+[FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)'s
+rules that specify that each supported algorithm (not each mode) need
+to be tested, and that if an algorithm is tested as a component of
+another test then it does not need separate tests. Here is the list of
+algorithms that 'need' to be tested.
+
+* Cipher encrypt/decrypt
+ * AES_128_GCM[^2]
+ * TDES_CBC
+* Digests
+ * SHA1
+ * _SHA256 is required but tested elsewhere_
+ * SHA512
+ * SHA3-256
+* Sign/Verify tests
+ * DSA_2048
+ * RSA_SHA256 (with PKCS #1 v1.5 padding)
+ * ECDSA P256
+* DRBG Health Tests for any supported DRBG mechanisms
+ * CTR (AES_128_CTR)
+ * HASH - SHA256[^3]
+ * HMAC - SHA256
+* Derived Tests (Compute Z)
+ * ECDSA P256
+ * ECDH
+* KDF's
+ * KBKDF (HKDF for TLS)
+
+Note: HMAC-SHA-256 is used by the integrity test, so there is no need
+for a seperate HMAC test.
+
+##### API access {#api-access}
+
+In order to easily modify and change the self tests that are run - the
+self tests should be data driven. The POST tests are run before any
+methods are registered but the method tables can still be used
+indirectly. Lower level API's will still be required to set up keys
+(params, public/private) - the key loading code should be isolated in
+a separate function.
+
+An init method that sets up any required dependencies for the high
+level functions will be required i.e. `set_cpuid` may need to be
+called before doing primitive calls.
+
+API's for different types of self tests should be provided for
+digests, ciphers, signatures, DRBGs, KDFs, HMACs.
+
+The parameter passed into each of these tests is KAT data.
+
+### Security Strength {#security-strength}
+
+[SP 800-131A rev2](https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/draft)
+disallows certain algorithms and key lengths after certain dates.
+Security strengths are associated with these items.
+
+Algorithms with at least 112 bits of security strength are allowed.
+
+For signature verification, security strengths of at least 80 and
+below 112 are allowed for legacy purposes.
+
+These two values could be defined and enforced in the FIPS module for
+keys, or it can be handled more simply in the Security Policy
+Document.
+
+They could be defined by public API's that allow setting of these
+minimum values.
+
+A concept of target security strength should also be added, this value
+would be used during key generation algorithms, which have an input
+target security strength parameter specified by their standards.
+
+### SP800-56A & 56B {#sp800-56a-and-56b}
+
+These standards contain Key Agreement protocols. In order to test the
+protocols the following low level primitives would need to be in the
+cryptographic module.
+
+* Compute key methods - These already exist. (e.g `DH_compute_key()`).
+* Key Generation - (RSA
+ [FIPS 186-4](https://csrc.nist.gov/publications/detail/fips/186/4/final)
+ Keygen is currently missing).
+* Key Validation - (Mostly implemented).
+
+#### FIPS 186-4 RSA Key Generation {#fips-186-4-rsa-key-generation}
+
+* Initial Code for RSA key generation has been written
+ ([https://github.com/openssl/openssl/pull/6652](https://github.com/openssl/openssl/pull/6652))
+
+ Outstanding work is to plumb this into the FIPS module. The
+ OpenSSL FIPs provider will have the logic that enforces the key size
+ limits.
+* A pairwise consistency test (Conditional Self Test) is required
+ for RSA, DSA & ECDSA key pair generation. As the purpose of keys
+ is not known during key generation,
+ [FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)
+ states that the same pairwise tests can be used for both modes
+ i.e Signatures and Encryption.
+* 1024 bit keys are not allowed for RSA key generation.
+* The Key generation algorithms have the concept of a
+ target_security_strength. i.e- the code in key generation needs
+ the following check for RSA for example
+
+ ``` C
+ if (target_strength < 112
+ || target_strength > 256
+ || BN_security_bits(nbits) < target_strength)
+ return 0;
+
+ ```
+
+#### DH Key Generation {#dh-key-generation}
+
+* DH Key generation - This could possibly be broken up so that it
+ matches the standard steps. It is currently a fairly complex
+ monolithic function that is also used for validation.
+
+#### Key Validation {#key-validation}
+
+
+* RSA
+ [SP 800-56B](https://csrc.nist.gov/publications/detail/sp/800-56b/rev-1/final)
+ Key validation - public key, private key and key-pair checks that
+ conform to the standard have been added to
+ [PR #6652](https://github.com/openssl/openssl/pull/6652).
+* DH key validation checks need to be checked that they match the
+ standard.
+* EC key validation matches the standards checks.
+* AES-XTS mode requires a tweak key check.
+
+For KAS DH Params - two types are supported:
+
+1. Approved Safe Prime groups given by the following:
+
+ (where g=2, q=(p-1)/2, priv=[1, q-1], pub=[2, p-2])
+
+ TLS: (ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192)
+
+ IKE: (modp-2048, modp-3072, modp-4096, modp-6144, modp-8192)
+
+ Only the above safe primes can be validated - any others should fail.
+
+ Safe primes can be used for security strengths of at least 112
+ bits. FIPS specific checks to validate the group may be required.
+
+2. [FIPS 186-4](https://csrc.nist.gov/publications/detail/fips/186/4/final)
+ param sets can be used for backwards compatibility with security
+ strength of 112 bits only. The groups are
+
+ FB (2048, 224) &
+
+ FC (2048, 256).
+
+ This requires the seed and counter to be saved for validation purposes.
+
+If both types need to be supported then different key validation code
+will be required.
+
+The existing `DH_Check()` will require FIPS specific checks for the
+approved types.
+
+Keygen is the same for both (the security strength and max bitlen of
+private key are inputs).
+
+DSA = 'FFC' in
+[FIPS 186-4](https://csrc.nist.gov/publications/detail/fips/186/4/final).
+The DSA key generation/key validation could be reworked so that it
+matches the standard steps better. The key validation would benefit
+from this and can possibly be reused for the DH case if required.
+
+### GCM IV Generation {#gcm-iv-generation}
+
+For the FIPS module AES GCM has requirements related to unique key/IV
+pairs i.e.
+
+
+
+* Key/IV pair's must be unique for encryption.
+* The IV's must be generated inside the FIPS boundary.
+* For TLS the counter portion of the IV must be set by the
+ module. The module must ensure that when the counter is exhausted
+ an error is returned.
+* For a given key (for any IV length) the total number of
+ invocations of the authenticated encryption function must be less
+ than 2^32^.
+* A loss of power to the module should not cause the repetition of IVs.
+
+The Random Construction method for IV generation
+(from [SP 800-38D](https://csrc.nist.gov/publications/detail/sp/800-38d/final))
+will be used (except for TLS which will behave the same way it
+currently does). The Random Construction consists of a free field
+(which will be NULL) and a random field which will use a DRBG that can
+return at least 96 bits of entropy strength. This DRBG needs to be
+seeded by the module.
+
+The existing code needs to be modified so that an IV is generated if
+it is not set during the init() phase. The do_cipher() method can then
+be used to generate an iv if required..
+
+
+``` C
+int aes_gcm_cipher()
+{
+ ....
+ /* old code just returned -1 if iv_set was zero */
+ if (!gctx->iv_set) {
+ if (ctx->encrypt) {
+ if (!aes_gcm_iv_generate(gctx, 0))
+ return -1;
+ } else {
+ return -1;
+ }
+ }
+ }
+}
+```
+
+The generate code would look like the following:
+
+``` C
+#define AES_GCM_IV_GENERATE(gctx, offset) \
+ if (!gctx->iv_set) { \
+ int sz = gctx->ivlen - offset; \
+ if (sz <= 0) \
+ return -1; \
+ /* Must be at least 96 bits */ \
+ if (gctx->ivlen < 12) \
+ return -1; \
+ /* Use DRBG to generate random iv */ \
+ if (RAND_bytes(gctx->iv + offset, sz) <= 0) \
+ return -1; \
+ gctx->iv_set = 1; \
+ }
+```
+
+The generated IV can be retrieved via `EVP_CIPHER_CTX_iv()` so a ctrl
+id should not be needed.
+
+Ideally in FIPS mode trying to set the GCM IV parameter would result
+in an error. In practice there may be some applications that still
+require setting of the IV, so it is recommended that this is
+specified as a security policy item.
+
+The security policy would also need to state the following: (See
+[FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)
+A.5)
+
+
+
+* When the power is lost and then restored, a new key for use with
+ AES GCM encryption shall be established.
+* The total number of invocations using the same key must be less
+ than 2^32^.
+* Scenario 1: IV gen is in compliance with the TLS protocol.
+* Scenario 2: IV gen using
+ [NIST SP 800-38D](https://csrc.nist.gov/publications/detail/sp/800-38d/final)
+ (Section 8.2.2).
+
+### CSP/Key Zeroization {#csp-key-zeroization}
+
+We must set all Critical Security Parameters (CSPs) to zero when they
+are no longer needed. This might happen at different times dependent
+on the context:
+
+* Temporary copies of CSPs may be stack or heap allocated, and will
+ be zeroized within the relevant function for the scope within
+ which they are used.
+* Some CSPs will have a lifetime associated with an OpenSSL object
+ such as an `EVP_PKEY`, or an `EVP_CIPHER_CTX`. In this case the
+ CSPs will be zeroized at the point that these objects are
+ freed. In some cases objects may be reused (e.g. an
+ `EVP_CIPHER_CTX` can be reused for multiple encryption
+ operations), in which case any CSPs still present in the object
+ will be zeroized at the point that it is reinitialized for the new
+ operation.
+* Some CSPs (e.g. internal DRBG state) may live for the entire time
+ that the OpenSSL FIPS Module is loaded. In this case the state
+ will be encapsulated within OpenSSL objects. All OpenSSL Providers
+ (including the FIPS Module Provider) will have the ability to
+ register an "unload" function which is to be called when OpenSSL
+ is closed down (or the module is unloaded for any other
+ reason). The objects containing CSPs will be freed (and hence
+ zeroized) by this unload function.
+* According to
+ [FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)
+ 4.7: Cryptographic keys used by a cryptographic module ONLY to perform
+ [FIPS 140-2](https://csrc.nist.gov/publications/detail/fips/140/2/final)
+ Section 4.9.1 Power-Up Tests are not considered CSPs and therefore
+ do not need to meet the
+ [FIPS 140-2](https://csrc.nist.gov/publications/detail/fips/140/2/final)
+ Section 4.7.6 zeroization requirements.
+
+The OpenSSL FIPS Module will contain its own copy of the standard
+`OPENSSL_cleanse()` function to perform the zeroization. This is
+implemented using platform specific assembler.
+
+### DRBG {#drbg}
+
+
+The following API's existed in the old FIPS module and may need to be
+re-added:
+
+* **FIPS_drbg_health_check**: runs the DRBG KAT tests on demand. We
+ will need this available.
+* **FIPS_drbg_set_check_interval**: sets the interval (number of
+ generate calls) between running the DRBG KATs. This doesn't seem
+ like it is necessary, these tests are run at power up but are not
+ required to be run later, however this call is useful for failure
+ testing.
+
+#### Derivation Function {#derivation-function}
+
+As per #2 in
+[FIPS 140-2 IG 14.5](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf),
+CTR DRBG will need to support the derivation function unconditionally.
+With the derivation function disabled, the current code has issues
+reseeding. Moreover, without a derivation function, additional
+justification is required from the lab.
+
+#### Test Requirements {#test-requirements}
+
+* The `uninstantiate()` needs to demonstrate that the internal state
+ has been zeroized.
+* Failure testing requires a function for DRBG's to always produce the same
+ output.
+
+#### Other Items to Consider {#other-items-to-consider}
+
+In addition to entropy, described below, the following items need to be
+considered:
+
+* The entropy expansion in
+ [NIST SP 800-90C](https://csrc.nist.gov/publications/detail/sp/800-90c/draft)
+ 10.1.2 should be considered for implementation.
+* A better DRBG selection mechanism to choose between the available
+ DRBGs.
+* Support for prediction resistance. I.e. attempt to collect more
+ entropy from our sources when requested.
+* We need to figure out what the DRBG layer is going to look like. A
+ fair portion of the code will need to sit inside the FIPS
+ module. This code currently accesses EVP functionality which might
+ not be exposed inside the module. e.g. `drbg_ctr_init()` resolves
+ the `EVP_CIPHER` from a NID, and then sets up an `EVP_CIPHER_CTX`.
+
+### Entropy {#entropy}
+
+For all platforms, the operating system will provide entropy. For
+some platforms, built in hardware random number generators can also be
+used, although this introduces additional justification needs.
+
+For UNIX-like systems, one of the system calls `getrandom` or
+`getentropy` or the random device, `/dev/random`, will be used as
+entropy sources. Preference to be given to the system calls. Other
+strong random devices that can be used instead of `/dev/random`
+include: `/dev/srandom` and `/dev/hwrng`. Note, `/dev/urandom`,
+`/dev/prandom`, `/dev/wrandom` and `/dev/arandom` are not useable for
+FIPS operations without additional justification.
+
+On Windows, `BCryptGenRandom` or `CryptGenRandom` will be used as
+entropy sources.
+
+On VMS, various pieces of system status information will be used as
+entropy sources. Note, this will require justification and analysis
+to attest to the quality of the sources.
+
+For iOS,
+[SecRandomCopyBytes](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes)
+which produces
+[cryptographically secure random bytes](https://developer.apple.com/documentation/security/secrandomref).
+
+FIPS only allows one entropy source to be credited so the FIPS module
+will rely solely on the aforementioned operating system sources.
+Other sources, e.g. egd, hardware devices and the like, will not be
+used.
+
+#### Work to do to Complete the Entropy Solution {#work-to-do-to-complete-the-entropy-solution}
+
+The DRBG health tests need to be added to the random framework so that
+the seed material being fed into the DRBGs is checked. The check is
+for no two sequential blocks of seed material being identical. The
+check is made after all entropy sources are coalesced together and if
+it fails, reseeding the DRBGs fails forever more. We get to define
+the block size used: 64 bits. This is a balance between the
+probability of accidentally receiving a duplicate block
+(2^-64^) and grabbing too much entropy from the operating
+system (since the first block is discarded). Other obvious block
+sizes that could be used are 128 and 256 bits.
+
+The initial block of data must be zeroed and discarded after it is
+used.
+
+##### GCM IV {#gcm-iv}
+
+
+A recent update to
+[FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)
+A.5 states that justification is required if the module claims to
+generate a random IV for GCM. We would need to substantiate that the
+module can obtain the required 96 bits of entropy from the operating
+system. This should not be an insurmountable problem if the blocking
+calls to the operating system's randomness source are used and at
+least this amount is used as seed material for the DRBGs.
+
+### FIPS Module Boundary {#fips-module-boundary}
+
+Once in a FIPS module provided algorithm, we must remain within the
+FIPS module for any other cryptographic operations. It would be
+allowed by the FIPS rules for one FIPS module to use another FIPS
+module. However, for the purposes of the 3.0 design we are making the
+simplifying assumption that we will not allow this. For example an
+`EVP_DigestSign*` implementation uses both a signing algorithm and
+digest algorithm. We will not allow one of those algorithms to come
+from the FIPS module, and one to come from some other provider.
+
+All providers are assigned a unique `OSSL_PROVIDER` object when they
+are initialised. When the FIPS module is asked to use an algorithm it
+will verify that the implementation `OSSL_PROVIDER` object for that
+algorithm is the same as its own `OSSL_PROVIDER` object (i.e. the one
+that was passed to `OSSL_provider_init`). For example consider the
+case of an `EVP_DigestSign*` using RSA and SHA256. Both algorithms
+will be looked up externally to the FIPS module using the
+Core. The RSA signing algorithm is the first entry point and the
+"init" call will be passed references to the SHA256 algorithm to be
+used. The FIPS module implementation will check that the
+`OSSL_PROVIDER` object associated that the SHA256 implementation that
+it has been asked to use is also within the FIPS module boundary. If
+it is not then the "init" operation will fail. This is illustrated in
+the diagram below, which shows this operation from the perspective of
+the FIPS module.
+
+![](images/DigestSignFIPSModulePerspective.png)
+
+Note that within the FIPS module we are using EVP concepts
+(EVP_MD_CTX, EVP_PKEY_CTX, etc) in order to implement this. These are
+**copies** of the EVP implementation found in libcrypto. The FIPS
+module is **not** linked against libcrypto. This is to ensure that the
+complete operation stays within the boundary of the FIPS module
+without calling code that is external to it.
+
+### ASN.1 code {#asn.1-code}
+
+ASN.1 DER (distinguished encoding rules) is used to:
+
+* serialize **keys **and **parameters**
+* serialize **DSA and ECDSA signatures**, which consist of two
+ values, r and s
+* encode the signature digest OBJECT IDENTIFIER (OID) that is placed
+ in **RSA PKCS #1 padding**
+* serialize X.509 certificates and CRLs
+* other PDUs, such as PKCS #7/CMS, OCSP, PKCS #12, etc.
+
+The FIPS module will not have a copy of the ASN.1 DER encoder/parser
+and there will be no requirement for any provider to perform ASN.1
+serialization/deserialization for algorithms implemented by OpenSSL.
+
+All ASN.1 serialization/deserialization will be performed in
+libcrypto, with composite-value **key, parameter and signature**
+structures crossing the Core/provider boundary as an array of items,
+using the public data structure defined in
+[Appendix 2 - OpenSSL parameter passing](#appendix-2---openssl-parameter-passing).
+
+The encoded digest OIDs used for **RSA PKCS #1 padding** will either
+be pre-generated (as was done in the old FIPS module using the SHA_DATA macro)
+or generated on demand using a simple function that only generates
+encoded OIDs for the small set of digests supported by PKCS #1
+padding. These digest OIDs occur in the "OID tree" under a common
+node. Verifying the padding will include getting the encoded OID for
+the expected digest and comparing the bytes with what occurs in the
+padding; no DER parsing/decoding is required.
+
+
+
+## Code Maintenance {#code-maintenance}
+
+### Source code structure/tree clean-up {#source-code-structure-tree-clean-up}
+
+Cryptographic implementations (`crypto/evp/e_*.c` and most of
+`crypto/evp/m_*.c`; essentially any code that defines an `EVP_CIPHER`,
+`EVP_MD`, `EVP_PKEY_METHOD`, `EVP_MAC`, or `EVP_KDF`) must move out of
+the evp directory. They will all end up being part of one or two
+providers, so they should end up in a provider specific sub-tree.
+
+There will be a new directory `providers/`, where provider specific
+code is moved. `providers/build.info` defines exactly what source is
+used in what provider module(s).
+
+### Shared source code {#shared-source-code}
+
+The FIPS provider module and the default provider will share the same
+source, under different conditions, such as different include paths or
+different macros being defined (the latter requires added support in
+the build system). An example `build.info` that does this:
+
+```
+PROVIDERS=p_fips p_default
+
+SOURCE[p_fips]=foo.c
+INCLUDE[p_fips]=include/fips
+
+SOURCE[p_default]=foo.c
+INCLUDE[p_default]=include/default
+```
+
+Or, using macros:
+
+```
+PROVIDERS=p_fips p_default
+
+SOURCE[p_fips]=foo.c
+DEFINE[p_fips]=FIPS_MODE
+
+SOURCE[p_default]=foo.c
+```
+
+Note: some keywords aren't yet part of the `build.info` language.
+
+### Conditional Code {#conditional-code}
+
+We need a consistent approach to the compile-time inclusion of
+FIPS-specific code, and in some cases the exclusion of code that FIPS
+does not permit.
+
+Compile-time controls will be done via `#ifdef FIPS_MODE`. This
+ensures that all relevant files are compiled explicitly for non-FIPS
+or for use within the FIPS module. Since every file will be compiled
+twice (in the default provider, and in the FIPS module), once with
+each setting, there is no benefit to using a run-time if statement
+with constant value. (Further, a runtime setting will not always work
+(such as when expanding macros like BLOCK_CIPHER_custom, which create
+a global variable of function pointers.)
+
+The build system will support this by building FIPS provider object
+files with `-DFIPS_MODE` and default provider object files, which come
+from the same source, without the command line define.
+
+For runtime checks, a test for a TLS connection being in FIPS mode
+will be required. This can be done in a generic way by checking the
+property query string that is associated with a specific `SSL_CTX` or
+`SSL` object, to see if the "fips" property was set.
+
+## FIPS Testing {#fips-testing}
+
+The following types of tests are required:
+
+* CAVS testing for CMVP validated algorithms
+* FIPS Test Suite that can run all FIPS module algorithms.
+* POST failure testing.
+
+Acumen will write applications that use libcrypto to gain access to
+the FIPS provider via the EVP layer.
+
+Any special case code needed to return intermediate values (say for
+CAVS key generation), to display info (self test states), or change
+the normal flow of FIPS module code (e.g - self test failure or
+failing a keygen loop that supplies fixed rand values) will be
+controlled by embedding callbacks into the FIPS module code.
+
+It is recommended that this callback code would be conditionally
+compiled into the module, since some of the values should not be
+returned (e.g- intermediate values in keygen are not supposed to be
+output by the FIPS module).
+
+rand_bytes() will be overridden for tests that require fixed
+rand_bytes to be used.
+
+### FIPS Test callbacks {#fips-test-callbacks}
+
+
+The application can optionally supply a single callback function that
+can be used to process values received from the FIPS module. (Multiple
+callbacks could be registered if this is required).
+
+The optional application callback would be of the form:
+
+``` C
+static int fips_test_callback(const char *type, void *arg)
+{
+ return 1;
+}
+```
+
+The return value can be used to control flow in special cases inside
+the FIPS module code.
+
+The type is passed in from the FIPS module hook. Each different hook
+in the FIPS module should have a unique type. The type determines
+what the arg param contains (either a struct (e.g- intermediate
+values), a name, or int.
+
+The callback in the FIPS module will be of the form
+
+``` C
+MY_STRUCT data; /* values that need to be returned to the application */
+data.i = 1;
+.....
+if (FIPS_test_cb != NULL)
+ FIPS_test_cb(FIPS_TEST_CB_RSA_KEYGEN_GET, (void *)&data);
+```
+
+### POST Failure Testing and Logging. {#post-failure-testing-and-logging.}
+
+In order to support the failure of multiple tests all tests will
+always be run without early exiting (the failure is just flagged). A
+failure status will be returned after all the tests have completed.
+
+For logging or failure, the args would be:
+
+``` C
+struct {
+ const char *desc;
+ const char *state;
+ const char *fail_reason;
+};
+```
+
+Where:
+
+* type is one of "post_integrity", "post_cipher", "post_digest",
+ "post_signature", "post_drbg", ..
+* desc is the identifying name: e.g AES_128_CBC
+* state is one of
+* "start" - indicates the test is starting
+* "corrupt" - if this returns 0 then the test will fail
+* "pass" - indicates the test passed
+* "fail" - indicates the test failed
+* fail_reason - is the specific reason for failure (e.g- unable to
+ read the integrity module file, or integrity checksum file.)
+
+### CAVS Testing {#cavs-testing}
+
+CAVS testing will be performed by the lab.
+
+However each CAVS tests file could also be sampled and added to the
+unit tests. This would mean converting the file data of a single test
+into binary data inside a unit test.
+
+(DRBG_ctr is an example that does this already).
+
+This will ensure the following:
+
+
+
+* The required interfaces will be available to the CAVS tests (some
+ CAVS tests require access to internals, that are not normally
+ needed).
+* That the algorithm works.
+* Coverage.
+
+We could skip doing this if there is good communication with the lab,
+but there may be some extra callback hooks required in the code if the
+labs finds missing accessors for internals.
+
+## Legacy {#legacy}
+
+### EVP to low level API bridges {#evp-to-low-level-api-bridges}
+
+There are places where low level API structures are assigned to an `EVP_PKEY`
+object. The impact on the public `EVP_PKEY` is that it will have to keep a
+pointer to a possible low level structure and the type of that low
+level structure must be known internally in `libcrypto`. Any time the
+`EVP_PKEY` with such a pointer is used for any computation, it must
+check if the low level structure has changed and convert its data to
+parameters that can be used with the new providers.
+
+The exact mechanism to check if the contents of a low level structure
+has changed is to be determined. One possibility would be to have a
+dirty counter in the low level structure and a copy in the `EVP_PKEY`
+structure. The dirty counter gets incremented any time the low level
+structure is changed (functions such as `RSA_set0_key` would have to
+do the increment), and any time the `EVP_PKEY` is used for
+computations, its copy of the counter get checked against the low
+level dirty counter, and if they differ, the `EVP_PKEY` provider
+parameters get modified with data from the low level structure.
+
+(yet another idea is to have a callback function placed in the
+`EVP_PKEY` by the legacy functions, which does the update of
+parameters if it detects that low level changes have been made)
+
+### EVP method creators {#evp-method-creators}
+
+There is functionality to create diverse EVP method structures in
+OpenSSL 1.1.x, easily found like this:
+
+
+```
+grep EVP_CIPHER_meth util/libcrypto.num
+grep EVP_MD_meth util/libcrypto.num
+grep EVP_PKEY_meth util/libcrypto.num
+```
+
+### Associated types {#associated-types}
+
+The low level APIs are fairly standalone, so all low level API types
+will remain unchanged apart from an added dirty flag in some of the
+types. Associated `EVP_CIPHER`, `EVP_MD`, `EVP_PKEY_METHOD`,
+`EVP_MAC`, or `EVP_KDF` instances are handled separately through the
+implementation of dispatch tables in the Legacy provider module (see
+below).
+
+
+
+## Legacy Provider Module {#legacy-provider-module}
+
+Some algorithms that are considered "legacy" (an example could be
+IDEA) and that have current `EVP_CIPHER`, `EVP_MD`, `EVP_PKEY_METHOD`,
+`EVP_MAC`, or `EVP_KDF` implementations will move to a Legacy provider
+module rather than our default provider module.
+
+The methods for the following algorithms will become dispatch tables
+in the Legacy provider module:
+
+1. Blowfish
+2. CAST
+3. DES (but not 3DES)
+4. DSA
+5. IDEA
+6. MD2
+7. MD4
+8. MDC2
+9. RC2
+10. RC4
+11. RC5
+12. RIPEMD160
+13. SEED
+14. Whirlpool
+
+(note: this is not meant to be an exhaustive list, even though fairly
+complete _for the moment_)
+
+## The ENGINE API {#the-engine-api}
+
+The whole ENGINE API will be deprecated and removed in the major
+release after this one. By then, people will have to have learned how
+to create provider modules instead. In the meantime, it will be
+transformed into a tool to help implementers to transition from an
+ENGINE module implementation to a provider module implementation.
+
+Because algorithm constructors will be changed to construct dispatch
+tables, the ENGINE type will change into a collection of dispatch
+tables, and the ENGINE constructor functionality will change to
+collect the dispatch tables they get into the given ENGINE.
+
+Dispatch tables registered this way will get the added property
+_engine_ with the ENGINE identity as provider name property. That
+will make it possible for `ENGINE_by_id` and similar functionality to
+find the correct provider.
+
+The ENGINE module entry point `bind_engine` will be replaced with the
+provider module entry point, and the macro `IMPLEMENT_DYNAMIC_BIND_FN`
+will be changed to construct such an entry point. This entry point
+will create a provider style ENGINE structure, call the binding
+function which will fill it up with dispatch tables using the same
+method creation functions it has always used, then register all those
+dispatch tables collected in the ENGINE structure just like any
+provider module would, using the same method setting functions as
+before.
+
+As with the rest of this release, our goal is source-level
+compatibility.
+
+With OpenSSL 1.1.x and older, it's possible to hook in ENGINE provided
+methods to be used instead of the functions built into `libcrypto`,
+using functions like `ENGINE_get_default_RSA` and `ENGINE_get_RSA`.
+The first of the two needs no modification, while the latter will be
+changed to create the old-style methods (such as `RSA_METHOD`) from
+the corresponding dispatch table attached to the engine.
+
+# Appendix 1 - Property Syntax {#appendix-1---property-syntax}
+
+Property definitions and queries have a well defined syntax. This
+section presents this in both eBNF and as railroad diagrams. Okay,
+almost eBNF but using regular expression extensions in places.
+
+![](images/300PropDefinition.png){style="float: right; padding-left: 20px"}
+
+**Definition**
+
+```
+Definition
+ ::= SingleDefinition ( ',' SingleDefinition )*
+
+SingleDefinition
+ ::= PropertyName ( '=' Value )?
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropQuery.png){style="float: right; padding-left: 20px"}
+
+**Query**
+
+```
+Query ::= SingleQuery ( ',' SingleQuery )*
+
+SingleQuery
+ ::= '-'? PropertyName
+ | PropertyName ( '=' | '!=' ) Value )
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropValue.png){style="float: right; padding-left: 20px"}
+
+**Value**
+
+```
+Value ::= NumberLiteral
+ | StringLiteral
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropStringLiteral.png){style="float: right; padding-left: 20px"}
+
+**StringLiteral**
+
+```
+StringLiteral
+ ::= QuotedString
+ | UnquotedString
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropQuotedString.png){style="float: right; padding-left: 20px"}
+
+**QuotedString**[^4]
+
+```
+QuotedString
+ ::= '"' [^"]* '"'
+ | "'" [^']* "'"
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropUnquotedString.png){style="float: right; padding-left: 20px"}
+
+**UnquotedString**[^5]
+
+```
+UnquotedString
+ ::= [^{space},]+
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropNumberLiteral.png){style="float: right; padding-left: 20px"}
+
+**NumberLiteral**
+
+```
+NumberLiteral
+ ::= '0' ( [0-7]+ | 'x' [0-9A-Fa-f]+ )
+ | '-'? [1-9] [0-9]+
+```
+
+<br clear="all" />
+
+-----
+
+![](images/300PropPropertyName.png){style="float: right; padding-left: 20px"}
+
+**PropertyName**[^6]
+
+```
+PropertyName
+ ::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*
+```
+
+<br clear="all" />
+
+# Appendix 2 - Parameter Passing {#appendix-2---parameter-passing}
+
+Core or provider objects are supposed to be opaque to everything
+outside, and yet, we will need to be able to get parameters from them,
+or to pass parameters to them in a uniform way. We therefore need an
+intermediary non-opaque structure to support this.
+
+The types of data passed need to remain simple:
+
+* Numbers (integers of arbitrary size)
+* Character strings (assume UTF-8 encoding)
+* Octet strings (byte arrays of arbitrary size)
+
+Any parameter that's passing values to a module will need the
+following items:
+
+* An identifier, to indicate what parameter is being passed
+* The type of the value (from the list above)
+* The size of the value
+* The value itself
+
+Any parameters that are used to request values _from_ a module will
+need the following items:
+
+* An identifier to indicate what is being requested
+* The type of the value (from the list above)
+* The size of the buffer
+* A buffer where the values get filled in
+* The resultant output size, to be filled in by the function we ask
+ for parameters from
+
+These two structure are similar enough to be expressed as one and the same:
+
+``` C
+typedef struct ossl_param_st {
+ const char *key;
+ unsigned char data_type; /* declare what kind of content is sent or
+ expected */
+ void *buffer; /* value being passed in
+ or out */
+ size_t buffer_size; /* buffer size */
+ size_t *return_size; /* OPTIONAL: address to
+ content size */
+} OSSL_PARAM;
+```
+
+Usage examples:
+
+``` C
+ /* passing parameters to a module */
+ unsigned char *rsa_n = /* memory allocation */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ size_t rsa_n_size = BN_bn2lebinpad(N, rsa_n, BN_num_bytes(rsa_n));
+#else
+ size_t rsa_n_size = BN_bn2bin(N, rsa_n);
+#endif
+ struct OSSL_PARAM rsa_params[] = {
+ { RSA_N, OSSL_PARAM_INTEGER, rsa_n, rsa_n_size, NULL },
+ { 0, 0, 0, 0, 0 },
+ };
+
+ EVP_set_params(pkey, rsa_params);
+
+ /* requesting parameters from a module */
+ size_t rsa_n_buffer_size = BITS / 2 / 8 + 1;
+ unsigned char *rsa_n_buffer =
+ OPENSSL_malloc(rsa_n_size);
+ size_t rsa_n_size = 0;
+ OSSL_PARAM rsa_params[] = {
+ { RSA_N, OSSL_PARAM_INTEGER, rsa_n_buffer, rsa_n_buffer_size,
+ &rsa_n_size },
+ { 0, 0, 0, 0, 0 },
+ };
+
+ EVP_get_params(pkey, rsa_params);
+
+ /*
+ * Note: we could also have a ctrl functionality:
+ * EVP_ctrl(pkey, EVP_CTRL_SET_PARAMS, rsa_params);
+ * EVP_ctrl(pkey, EVP_CTRL_GET_PARAMS, rsa_params);
+ *
+ * This would allow other controls using the same API.
+ * For added flexibility, the signature could be something like:
+ *
+ * int EVP_ctrl(EVP_CTX *ctx, int cmd, ...);
+ */
+```
+
+## Data types {#data-types}
+
+
+This specification supports the following parameter types:
+
+
+
+* `INTEGER`
+* `UNSIGNED_INTEGER`
+ * These are arbitrary length and may therefore require an
+ arbitrarily sized buffer.
+ * The number is stored in native form, i.e. MSB first on big
+ endian systems and LSB first on little endian systems. This
+ means that arbitrary native integers can be stored in the
+ buffer, just make sure that the buffer size is correct and
+ properly aligned.
+* `REAL`
+ * These store C binary floating point values in their native
+ format and alignment.
+* `UTF8_STRING`
+ * This type of string is expected to be printable as is.
+* `OCTET_STRING`
+ * When printed, this is expected to become a hexdump.
+
+We also support pointer variants of the same types (which means that
+the `OSSL_PARAM` `buffer` only has to have space for a `void *`).
+This use is _fragile_ unless the pointed at values are constant over
+time.
+
+We have macros to declare the type of content in `data_type`:
+
+```
+#define OSSL_PARAM_INTEGER 1
+#define OSSL_PARAM_UNSIGNED_INTEGER 2
+#define OSSL_PARAM_UTF8_STRING 3
+#define OSSL_PARAM_OCTET_STRING 4
+/*
+ * This one is combined with one of the above, i.e. to get a string pointer:
+ * OSSL_PARAM_POINTER | OSSL_PARAM_UTF8_STRING
+ */
+#define OSSL_PARAM_POINTER 0x80
+```
+
+## Implementation details {#implementation-details}
+
+### Determining the size of the buffer {#determining-the-size-of-the-buffer}
+
+When requesting parameter values, the caller may choose to assign
+`NULL` to `buffer` in one or more parameter structures. The called
+getter should answer such a request by filling in the size pointed at
+by `return_size` and return, at which point the caller can allocate
+appropriately sized buffers and make a second call, at which point the
+getter can fill in the buffer with no problem.
+
+If the programmer wants, `return_size` could be made to point at
+`buffer_size` in the same `OSSL_PARAM`.
+
+## Uses beyond the immediately obvious {#uses-beyond-the-immediately-obvious}
+
+### CONF / NCONF values as parameters {#conf-nconf-values-as-parameters}
+
+Configuration values are interesting to providers! And yet, just
+passing a CONF pointer between the Core and the provider may not be
+feasible, even though it's _currently_ a non-opaque structure.
+
+Another method could be to make the CONF / NCONF values into
+parameters, with a bit of inspiration from git config value names.
+
+Let's start with imagining a provider configuration along the same
+lines as the what the current ENGINE configuration module supports:
+
+```
+[provider_section]
+# Configure provider named "foo"
+foo = foo_section
+# Configure provider named "bar"
+bar = bar_section
+
+[foo_section]
+provider_id = myfoo
+module_path = /usr/share/openssl/providers/foo.so
+selftests = foo_selftest_section
+algorithms = RSA, DSA, DH
+
+[foo_selftest_section]
+doodah = 1
+cookie = 0
+```
+
+The Core side provider structure for the provider "foo" could then
+answer to these requested parameter keys:
+
+* `"provider_id"` (value is `"myfoo"`)
+* `"module_path"` (value is `"/usr/share/openssl/providers/foo.so"`)
+* `"selftests.doodah"` (value is `1`)
+* `"selftests.cookie"` (value is `0`)
+* `"algorithms"` (value is `"RSA, DSA, DH"`)
+
+Note that the section names themselves never appear in the parameter
+key, but that the key that lead to the section does instead. This is
+suggested because OpenSSL allows arbitrarily named section names.
+
+## The tooth of time {#the-tooth-of-time}
+
+The parameter structure defined above isn't something that's been
+invented on the spot. It's highly inspired from OpenVMS programming
+paradigms that have proven stable over time. The actual inspiring
+structure is called "item_list_3", which is documented here:
+[OpenVMS Programming Concepts Manual, Volume I](https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-c04621447)
+
+# Appendix 3 - Algorithms {#appendix-3---algorithms}
+
+The algorithms which are to be included in the FIPS module are:
+
+<!-- this remains a table in markdown to get colspan and rowspan -->
+<table>
+ <tr>
+ <td colspan="2" ><strong>Requirement</strong>
+ </td>
+ <td><strong>Standard</strong>
+ </td>
+ <td><strong>Compliant</strong>[^7]<strong> </strong>
+ </td>
+ <td><strong>Notes</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>TDES
+ </td>
+ <td>CBC
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/fips/81/archive/1980-12-02">FIPS 81</a>
+ </td>
+ <td>✓
+ </td>
+ <td rowspan="2" >Refer also to <a href="https://csrc.nist.gov/publications/detail/sp/800-67/rev-2/final">SP 800-67rev2</a>. \
+ \
+TDES support being decryption only (from 2020) and banned (from 2025). \
+ \
+Limits to data length imposed.
+<p>
+Security Policy statement regarding the <a href="https://csrc.nist.gov/publications/detail/sp/800-67/rev-1/archive/2012-01-23">SP 800-67rev1 </a>transition and limitations will be required.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>ECB
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/fips/81/archive/1980-12-02">FIPS 81</a>
+ </td>
+ <td>✓
+ </td>
+ </tr>
+ <tr>
+ <td>AES
+ </td>
+ <td>CBC
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38a/final">SP 800-38A</a>
+ </td>
+ <td>✓
+ </td>
+ <td>All AES cipher modes supporting 128, 192 and 256 bits.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>CCM
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38c/final">SP 800-38C</a>
+ </td>
+ <td>✓
+ </td>
+ <td>It's likely easier to include all of these than to remove some of them.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>CTR
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38a/final">SP 800-38A</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>ECB
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38a/final">SP 800-38A</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>GCM
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38d/final">SP 800-38D</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Changes in IV. Module must generate the IV.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>GMAC
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38d/final">SP 800-38D</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>XTS
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38e/final">SP 800-38E</a>
+ </td>
+ <td>✗
+ </td>
+ <td>See <a href="https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Module-Validation-Program/documents/fips140-2/FIPS1402IG.pdf">FIPS 140-2 I.G.</a> A.9. Needs key check added. This mode does not support 192 bits. Check added by <a href="https://github.com/openssl/openssl/pull/7120">#7120</a>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>KW
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38f/final">SP 800-38F</a>
+ </td>
+ <td>✓
+ </td>
+ <td rowspan="2" >Differences from standard but within it.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>KWP
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-38f/final">SP 800-38F</a>
+ </td>
+ <td>✓
+ </td>
+ </tr>
+ <tr>
+ <td>Hash
+ </td>
+ <td>SHA-1
+ </td>
+ <td><a href="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf">FIPS 180-4</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>SHA-2
+ </td>
+ <td><a href="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf">FIPS 180-4</a>
+ </td>
+ <td>✓
+ </td>
+ <td>224, 256, 384, 512.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>SHA-2
+ </td>
+ <td><a href="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf">FIPS 180-4</a>
+ </td>
+ <td>✓
+ </td>
+ <td>512/224, 512/256. Appear to be compliant.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>SHA-3
+ </td>
+ <td><a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">FIPS 202</a>
+ </td>
+ <td>✓
+ </td>
+ <td>224, 256, 384, 512. Appear to be compliant.
+ </td>
+ </tr>
+ <tr>
+ <td>HMAC
+ </td>
+ <td>SHA-1
+ </td>
+ <td><a href="https://www.nist.gov/publications/keyed-hash-message-authentication-code-hmac-0?pub_id=901614">FIPS 198-1</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>SHA-2
+ </td>
+ <td><a href="https://www.nist.gov/publications/keyed-hash-message-authentication-code-hmac-0?pub_id=901614">FIPS 198-1</a>
+ </td>
+ <td>✓
+ </td>
+ <td>224, 256, 384, 512.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>SHA-3
+ </td>
+ <td><a href="https://www.nist.gov/publications/keyed-hash-message-authentication-code-hmac-0?pub_id=901614">FIPS 198-1</a>
+ </td>
+ <td>✓
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td>DRBG
+ </td>
+ <td>AES CTR
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final">SP 800-90A</a>
+ </td>
+ <td>✗
+ </td>
+ <td rowspan="3" >Issues with <a href="https://csrc.nist.gov/publications/detail/sp/800-90c/draft">SP 800-90C</a>.
+<p>
+All comply with <a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final">SP 800-90A</a>.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>Hash
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final">SP 800-90A</a>
+ </td>
+ <td>✗
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>HMAC
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final">SP 800-90A</a>
+ </td>
+ <td>✗
+ </td>
+ </tr>
+ <tr>
+ <td>DRBG
+ </td>
+ <td>Testing
+ </td>
+ <td>SP 800-90
+ </td>
+ <td>✗
+ </td>
+ <td>Support DRBG health test as per current version of these standards: <a href="https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final">A</a>, <a href="https://csrc.nist.gov/publications/detail/sp/800-90b/final">B</a> & <a href="https://csrc.nist.gov/publications/detail/sp/800-90c/draft">C</a>.
+ </td>
+ </tr>
+ <tr>
+ <td>RSA
+ </td>
+ <td>
+ </td>
+ <td><a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf">FIPS 186-4</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Refer also to <a href="https://csrc.nist.gov/publications/detail/sp/800-56b/rev-2/draft">SP 800-56B</a>. PKCS#1.5, PSS, Key pair generation. Modulus size changes.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>Key wrap (transport)
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-56b/rev-2/draft">SP 800-56B</a>
+ </td>
+ <td>✗
+ </td>
+ <td>OAEP. Update to <a href="https://csrc.nist.gov/publications/detail/sp/800-56b/rev-2/draft">SP 800-56B rev-1</a> standard.
+ </td>
+ </tr>
+ <tr>
+ <td>DH
+ </td>
+ <td>KAS
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final">SP 800-56A</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Update to <a href="https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final">SP 800-56A rev-3</a> standard.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>KAS
+ </td>
+ <td><a href="https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/keymgmt/KASVS.pdf">KASVS</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Additional testing to meet ZZonly. CVL/KAS.
+ </td>
+ </tr>
+ <tr>
+ <td>DSA
+ </td>
+ <td>
+ </td>
+ <td><a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf">FIPS 186-4</a>
+ </td>
+ <td>✗
+ </td>
+ <td>PQG generation & verification, signature generation & verification, key pair generation.
+ </td>
+ </tr>
+ <tr>
+ <td>ECDSA
+ </td>
+ <td>
+ </td>
+ <td><a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf">FIPS 186-4</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Key pair generation, public key generation, signature generation & verification.
+ </td>
+ </tr>
+ <tr>
+ <td>ECC
+ </td>
+ <td>KAS
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final">SP 800-56A</a>
+ </td>
+ <td>✗
+ </td>
+ <td>B-233, 283, 409, 571; K-233, 283, 409, 571; P-224, 256, 384, 521. Update to <a href="https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final">SP 800-56A rev-3</a> standard.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>KAS
+ </td>
+ <td><a href="https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/keymgmt/KASVS.pdf">KASVS</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Additional testing to meet ZZonly. CVL/KAS.
+ </td>
+ </tr>
+ <tr>
+ <td>KDF
+ </td>
+ <td>PBKDF2
+ </td>
+ <td><a href="https://csrc.nist.gov/publications/detail/sp/800-132/final">SP 800-132</a>
+ </td>
+ <td>✗
+ </td>
+ <td>Verify conformance with standards. See <a href="https://github.com/openssl/openssl/pull/6674">#6674</a>.
+ </td>
+ </tr>
+ <tr>
+ <td>TLS
+ </td>
+ <td>PRF
+ </td>
+ <td>
+ </td>
+ <td>✗
+ </td>
+ <td>For TLS 1.2 and 1.3.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>RSA
+ </td>
+ <td>
+ </td>
+ <td>N/A
+ </td>
+ <td rowspan="2" ><em>These two are not algorithms, they serve as a reminder that the custom code for these in libssl would need to move to libcrypto and then be incorporated into the FIPS module.</em>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>CBC
+ </td>
+ <td>
+ </td>
+ <td>N/A
+ </td>
+ </tr>
+</table>
+
+<!-- Footnotes themselves at the bottom. -->
+# Notes {#notes}
+
+[^1]: The output of the DRBGs are not required to be tested because of
+ [FIPS 140-2 IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf)
+ 9.8. However, the seed material being fed into the master DRBG
+ still requires the RCT or stuck bit testing.
+
+[^2]: The draft guidance has changed. The alternatives are: AES_GMAC,
+ AES_128_CCM, AES_256_GCM and AES_256_CCM. GMAC is arguably the
+ simplest of the three and thus might be preferable.
+
+[^3]: Using a different digest algorithm for HASH and HMAC DRBGs would
+ obviate the need to test the digest independently.
+
+[^4]: Quoted strings can contain UTF-8 characters.
+
+[^5]: Unquoted strings are passed through a lower case conversion and
+ can only contain ASCII characters.
+
+[^6]: Property names are case insensitive even though only upper case
+ is depicted here.
+
+[^7]: Current from a CMVP perspective.
+
diff --git a/docs/images/300Component.png b/docs/images/300Component.png
new file mode 100644
index 0000000..84d3c3c
Binary files /dev/null and b/docs/images/300Component.png differ
diff --git a/docs/images/300FIPSStateMachine.png b/docs/images/300FIPSStateMachine.png
new file mode 100644
index 0000000..b76a20a
Binary files /dev/null and b/docs/images/300FIPSStateMachine.png differ
diff --git a/docs/images/300Packaging.png b/docs/images/300Packaging.png
new file mode 100644
index 0000000..5674860
Binary files /dev/null and b/docs/images/300Packaging.png differ
diff --git a/docs/images/300PropDefinition.png b/docs/images/300PropDefinition.png
new file mode 100644
index 0000000..6a5ae38
Binary files /dev/null and b/docs/images/300PropDefinition.png differ
diff --git a/docs/images/300PropNumberLiteral.png b/docs/images/300PropNumberLiteral.png
new file mode 100644
index 0000000..bf9d7ca
Binary files /dev/null and b/docs/images/300PropNumberLiteral.png differ
diff --git a/docs/images/300PropPropertyName.png b/docs/images/300PropPropertyName.png
new file mode 100644
index 0000000..b8a9e7b
Binary files /dev/null and b/docs/images/300PropPropertyName.png differ
diff --git a/docs/images/300PropQuery.png b/docs/images/300PropQuery.png
new file mode 100644
index 0000000..aa25b07
Binary files /dev/null and b/docs/images/300PropQuery.png differ
diff --git a/docs/images/300PropQuotedString.png b/docs/images/300PropQuotedString.png
new file mode 100644
index 0000000..c9b776e
Binary files /dev/null and b/docs/images/300PropQuotedString.png differ
diff --git a/docs/images/300PropStringLiteral.png b/docs/images/300PropStringLiteral.png
new file mode 100644
index 0000000..ecd640b
Binary files /dev/null and b/docs/images/300PropStringLiteral.png differ
diff --git a/docs/images/300PropUnquotedString.png b/docs/images/300PropUnquotedString.png
new file mode 100644
index 0000000..a8504b0
Binary files /dev/null and b/docs/images/300PropUnquotedString.png differ
diff --git a/docs/images/300PropValue.png b/docs/images/300PropValue.png
new file mode 100644
index 0000000..56fd980
Binary files /dev/null and b/docs/images/300PropValue.png differ
diff --git a/docs/images/300ProviderCollab.png b/docs/images/300ProviderCollab.png
new file mode 100644
index 0000000..3c5f44f
Binary files /dev/null and b/docs/images/300ProviderCollab.png differ
diff --git a/docs/images/DigestExplicit.png b/docs/images/DigestExplicit.png
new file mode 100644
index 0000000..c683440
Binary files /dev/null and b/docs/images/DigestExplicit.png differ
diff --git a/docs/images/DigestSignFIPSExplicit.png b/docs/images/DigestSignFIPSExplicit.png
new file mode 100644
index 0000000..70b845e
Binary files /dev/null and b/docs/images/DigestSignFIPSExplicit.png differ
diff --git a/docs/images/DigestSignFIPSModulePerspective.png b/docs/images/DigestSignFIPSModulePerspective.png
new file mode 100644
index 0000000..c8cfaee
Binary files /dev/null and b/docs/images/DigestSignFIPSModulePerspective.png differ
diff --git a/docs/images/ToBeComponent.png b/docs/images/ToBeComponent.png
index 91306d7..84d3c3c 100644
Binary files a/docs/images/ToBeComponent.png and b/docs/images/ToBeComponent.png differ
diff --git a/docs/images/ToBePackaging.png b/docs/images/ToBePackaging.png
index 340cd04..5674860 100644
Binary files a/docs/images/ToBePackaging.png and b/docs/images/ToBePackaging.png differ
More information about the openssl-commits
mailing list