ossl-guide-tls-introduction

title: ossl-guide-tls-introduction(7ossl)

summary: guide\-tls\-introduction

text:
# ossl-guide-tls-introduction(7ossl)

## NAME
ossl-guide-tls-introduction - OpenSSL Guide: An introduction to SSL/TLS in OpenSSL

## INTRODUCTION
This page will provide an introduction to some basic SSL/TLS concepts and background and how it is used within OpenSSL. It assumes that you have a basic understanding of TCP/IP and sockets.

## WHAT IS TLS?
TLS stands for Transport Layer Security. TLS allows applications to securely communicate with each other across a network such that the confidentiality of the information exchanged is protected (i.e. it prevents eavesdroppers from listening in to the communication). Additionally it protects the integrity of the information exchanged to prevent an attacker from changing it. Finally it provides authentication so that one or both parties can be sure that they are talking to who they think they are talking to and not some imposter.

Sometimes TLS is referred to by its predecessor's name SSL (Secure Sockets Layer). OpenSSL dates from a time when the SSL name was still in common use and hence many of the functions and names used by OpenSSL contain the "SSL" abbreviation. Nonetheless OpenSSL contains a fully fledged TLS implementation.

TLS is based on a client/server model. The application that initiates a communication is known as the client. The application that responds to a remotely initiated communication is the server. The term "endpoint" refers to either of the client or the server in a communication. The term "peer" refers to the endpoint at the other side of the communication that we are currently referring to. So if we are currently talking about the client then the peer would be the server.

TLS is a standardised protocol and there are numerous different implementations of it. Due to the standards an OpenSSL client or server is able to communicate seamlessly with an application using some different implementation of TLS. TLS (and its predecessor SSL) have been around for a significant period of time and the protocol has undergone various changes over the years. Consequently there are different versions of the protocol available. TLS includes the ability to perform version negotiation so that the highest protocol version that the client and server share in common is used.

TLS acts as a security layer over some lower level transport protocol. Typically the transport layer will be TCP.

## SSL AND TLS VERSIONS
SSL was initially developed by Netscape Communications and its first publicly released version was SSLv2 in 1995. Note that SSLv1 was never publicly released. SSLv3 came along quickly afterwards in 1996. Subsequently development of the protocol moved to the IETF which released the first version of TLS (TLSv1.0) in 1999 as RFC2246. TLSv1.1 was released in 2006 as RFC4346 and TLSv1.2 came along in 2008 as RFC5246. The most recent version of the standard is TLSv1.3 which was released in 2018 as RFC8446.

Today TLSv1.3 and TLSv1.2 are the most commonly deployed versions of the protocol. The IETF have formally deprecated TLSv1.1 and TLSv1.0, so anything below TLSv1.2 should be avoided since the older protocol versions are susceptible to security problems.

OpenSSL does not support SSLv2 (it was removed in OpenSSL 1.1.0). Support for SSLv3 is available as a compile time option - but it is not built by default. Support for TLSv1.0, TLSv1.1, TLSv1.2 and TLSv1.3 are all available by default in a standard build of OpenSSL. However special run-time configuration is required in order to make TLSv1.0 and TLSv1.1 work successfully.

OpenSSL will always try to negotiate the highest protocol version that it has been configured to support. In most cases this will mean either TLSv1.3 or TLSv1.2 is chosen.

## CERTIFICATES
In order for a client to establish a connection to a server it must authenticate the identify of that server, i.e. it needs to confirm that the server is really the server that it claims to be and not some imposter. In order to do this the server will send to the client a digital certificate (also commonly referred to as an X.509 certificate). The certificate contains various information about the server including its full DNS hostname. Also within the certificate is the server's public key. The server operator will have a private key which is linked to the public key and must not be published.

Along with the certificate the server will also send to the client proof that it knows the private key associated with the public key in the certificate. It does this by digitally signing a message to the client using that private key. The client can verify the signature using the public key from the certificate. If the signature verifies successfully then the client knows that the server is in possession of the correct private key.

The certificate that the server sends will also be signed by a Certificate Authority. The Certificate Authority (commonly known as a CA) is a third party organisation that is responsible for verifying the information in the server's certificate (including its DNS hostname). The CA should only sign the certificate if it has been able to confirm that the server operator does indeed have control of the server associated with its DNS hostname and that the server operator has control of the private key.

In this way, if the client trusts the CA that has signed the server's certificate and it can verify that the server has the right private key then it can trust that the server truly does represent the DNS hostname given in the certificate. The client must also verify that the hostname given in the certificate matches the hostname that it originally sent the request to.

Once all of these checks have been done the client has successfully verified the identify of the server. OpenSSL can perform all of these checks automatically but it must be provided with certain information in order to do so, i.e. the set of CAs that the client trusts as well as the DNS hostname for the server that this client is trying to connect to.

Note that it is common for certificates to be built up into a chain. For example a server's certificate may be signed by a key owned by a an intermediate CA. That intermediate CA also has a certificate containing its public key which is in turn signed by a key owned by a root CA. The client may only trust the root CA, but if the server sends both its own certificate and the certificate for the intermediate CA then the client can still successfully verify the identity of the server. There is a chain of trust between the root CA and the server.

By default it is only the client that authenticates the server using this method. However it is also possible to set things up such that the server additionally authenticates the client. This is known as "client authentication". In this approach the client will still authenticate the server in the same way, but the server will request a certificate from the client. The client sends the server its certificate and the server authenticates it in the same way that the client does.

## TRUSTED CERTIFICATE STORE
The system described above only works if a chain of trust can be built between the set of CAs that the endpoint trusts and the certificate that the peer is using. The endpoint must therefore have a set of certificates for CAs that it trusts before any communication can take place. OpenSSL itself does not provide such a set of certificates. Therefore you will need to make sure you have them before you start if you are going to be verifying certificates (i.e. always if the endpoint is a client, and only if client authentication is in use for a server).

Fortunately other organisations do maintain such a set of certificates. If you have obtained your copy of OpenSSL from an Operating System (OS) vendor (e.g. a Linux distribution) then normally the set of CA certificates will also be distributed with that copy.

You can check this by running the OpenSSL command line application like this:

```
 openssl version -d
```

This will display a value for OPENSSLDIR. Look in the certs sub directory of OPENSSLDIR and check its contents. For example if OPENSSLDIR is "/usr/local/ssl", then check the contents of the "/usr/local/ssl/certs" directory.

You are expecting to see a list of files, typically with the suffix ".pem" or ".0". If they exist then you already have a suitable trusted certificate store.

If you are running your version of OpenSSL on Windows then OpenSSL (from version 3.2 onwards) will use the default Windows set of trusted CAs.

If you have built your version of OpenSSL from source, or obtained it from some other location and it does not have a set of trusted CA certificates then you will have to obtain them yourself. One such source is the Curl project. See the page <https://curl.se/docs/caextract.html> where you can download trusted certificates in a single file. Rename the file to "cert.pem" and store it directly in OPENSSLDIR. For example if OPENSSLDIR is "/usr/local/ssl", then save it as "/usr/local/ssl/cert.pem".

You can also use environment variables to override the default location that OpenSSL will look for its trusted certificate store. Set the SSL_CERT_PATH environment variable to give the directory where OpenSSL should looks for its certificates or the SSL_CERT_FILE environment variable to give the name of a single file containing all of the certificates. See openssl-env(7) for further details about OpenSSL environment variables. For example you could use this capability to have multiple versions of OpenSSL all installed on the same system using different values for OPENSSLDIR but all using the same trusted certificate store.

You can test that your trusted certificate store is setup correctly by using it via the OpenSSL command line. Use the following command to connect to a TLS server:

```
 openssl s_client www.openssl.org:443
```

Once the command has connected type the letter "Q" followed by "<enter>" to exit the session. This will print a lot of information on the screen about the connection. Look for a block of text like this:

```
 SSL handshake has read 4584 bytes and written 403 bytes
 Verification: OK
```

Hopefully if everything has worked then the "Verification" line will say "OK". If its not working as expected then you might see output like this instead:

```
 SSL handshake has read 4584 bytes and written 403 bytes
 Verification error: unable to get local issuer certificate
```

The "unable to get local issuer certificate" error means that OpenSSL has been unable to find a trusted CA for the chain of certificates provided by the server in its trusted certificate store. Check your trusted certificate store configuration again.

Note that s_client is a testing tool and will still allow you to connect to the TLS server regardless of the verification error. Most applications should not do this and should abort the connection in the event of a verification error.

## IMPORTANT OBJECTS FOR AN OPENSSL TLS APPLICATION
A TLS connection is represented by the SSL object in an OpenSSL based application. Once a connection with a remote peer has been established an endpoint can "write" data to the SSL object to send data to the peer, or "read" data from it to receive data from the server.

A new SSL object is created from an SSL_CTX object. Think of an SSL_CTX as a "factory" for creating SSL objects. You can create a single SSL_CTX object and then create multiple connections (i.e. SSL objects) from it. Typically you can set up common configuration options on the SSL_CTX so that all the SSL object created from it inherit the same configuration options.

Note that internally to OpenSSL various items that are shared between multiple SSL objects are cached in the SSL_CTX for performance reasons. Therefore it is considered best practice to create one SSL_CTX for use by multiple SSL objects instead of having one SSL_CTX for each SSL object that you create.

Each SSL object is also associated with two BIO objects. A BIO object is used for sending or receiving data from the underlying transport layer. For example you might create a BIO to represent a TCP socket. The SSL object uses one BIO for reading data and one BIO for writing data. In most cases you would use the same BIO for each direction but there could be some circumstances where you want them to be different.

It is up to the application programmer to create the BIO objects that are needed and supply them to the SSL object. See ossl-guide-tls-client-block(7) for further information.

Finally, an endpoint can establish a "session" with its peer. The session holds various TLS parameters about the connection between the client and the server. The session details can then be reused in a subsequent connection attempt to speed up the process of connecting. This is known as "resumption". Sessions are represented in OpenSSL by the SSL_SESSION object. In TLSv1.2 there is always exactly one session per connection. In TLSv1.3 there can be any number per connection including none.

## PHASES OF A TLS CONNECTION
A TLS connection starts with an initial "set up" phase. The endpoint creates the SSL_CTX (if one has not already been created) and configures it.

A client then creates an SSL object to represent the new TLS connection. Any connection specific configuration parameters are then applied and the underlying socket is created and associated with the SSL via BIO objects.

A server will create a socket for listening for incoming connection attempts from clients. Once a connection attempt is made the server will create an SSL object in the same way as for a client and associate it with a BIO for the newly created incoming socket.

After set up is complete the TLS "handshake" phase begins. A TLS handshake consists of the client and server exchanging a series of TLS handshake messages to establish the connection. The client starts by sending a "ClientHello" handshake message and the server responds with a "ServerHello". The handshake is complete once an endpoint has sent its last message (known as the "Finished" message) and received a Finished message from its peer. Note that this might occur at slightly different times for each peer. For example in TLSv1.3 the server always sends its Finished message before the client. The client later responds with its Finished message. At this point the client has completed the handshake because it has both sent and received a Finished message. The server has sent its Finished message but the Finished message from the client may still be in-flight, so the server is still in the handshake phase. It is even possible that the server will fail to complete the handshake (if it considers there is some problem with the messages sent from the client), even though the client may have already progressed to sending application data. In TLSv1.2 this can happen the other way around, i.e. the server finishes first and the client finishes second.

Once the handshake is complete the application data transfer phase begins. Strictly speaking there are some situations where the client can start sending application data even earlier (using the TLSv1.3 "early data" capability) - but we're going to skip over that for this basic introduction.

During application data transfer the client and server can read and write data to the connection freely. The details of this are typically left to some higher level application protocol (for example HTTP). Not all information exchanged during this phase is application data. Some protocol level messages may still be exchanged - so it is not necessarily the case that, just because the underlying socket is "readable", that application data will be available to read.

When the connection is no longer required then it should be shutdown. A shutdown may be initiated by either the client or the server via a message known as a "close_notify" alert. The client or server that receives a close_notify may respond with one and then the connection is fully closed and application data can no longer be sent or received.

Once shutdown is complete a TLS application must clean up by freeing the SSL object.

## FURTHER READING
See ossl-guide-tls-client-block(7) to see an example of applying these concepts in order to write a simple TLS client based on a blocking socket. See ossl-guide-quic-introduction(7) for an introduction to QUIC in OpenSSL.

## SEE ALSO
ossl-guide-introduction(7), ossl-guide-libraries-introduction(7), ossl-guide-libssl-introduction(7), ossl-guide-tls-client-block(7), ossl-guide-quic-introduction(7)

## COPYRIGHT
Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


package: openssl

title: ossl_store(7ossl)

summary: Store retrieval functions

text:
# ossl_store(7ossl)

## NAME
ossl_store - Store retrieval functions

## SYNOPSIS
\#include <openssl/store.h>

## DESCRIPTION

### General
A STORE is a layer of functionality to retrieve a number of supported objects from a repository of any kind, addressable as a filename or as a URI.

The functionality supports the pattern "open a channel to the repository", "loop and retrieve one object at a time", and "finish up by closing the channel".

The retrieved objects are returned as a wrapper type OSSL_STORE_INFO, from which an OpenSSL type can be retrieved.

### URI schemes and loaders
Support for a URI scheme is called a STORE "loader", and can be added dynamically from the calling application or from a loadable engine.

Support for the 'file' scheme is built into "libcrypto". See ossl_store-file(7) for more information.

### UI_METHOD and pass phrases
The OSS_STORE API does nothing to enforce any specific format or encoding on the pass phrase that the UI_METHOD provides. However, the pass phrase is expected to be UTF-8 encoded. The result of any other encoding is undefined.

## EXAMPLES

### A generic call

```
 #include <openssl/ui.h> /* for UI_get_default_method */
 #include <openssl/store.h>
 OSSL_STORE_CTX *ctx = OSSL_STORE_open("file:/foo/bar/data.pem",
                        UI_get_default_method(), NULL, NULL, NULL);
 /*
  * OSSL_STORE_eof() simulates file semantics for any repository to signal
  * that no more data can be expected
  */
 while (!OSSL_STORE_eof(ctx)) {
     OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
     /*
      * Do whatever is necessary with the OSSL_STORE_INFO,
      * here just one example
      */
     switch (OSSL_STORE_INFO_get_type(info)) {
     case OSSL_STORE_INFO_CERT:
         /* Print the X.509 certificate text */
         X509_print_fp(stdout, OSSL_STORE_INFO_get0_CERT(info));
         /* Print the X.509 certificate PEM output */
         PEM_write_X509(stdout, OSSL_STORE_INFO_get0_CERT(info));
         break;
     }
     OSSL_STORE_INFO_free(info);
 }
 OSSL_STORE_close(ctx);
```

## SEE ALSO
OSSL_STORE_INFO(3), OSSL_STORE_LOADER(3), OSSL_STORE_open(3), OSSL_STORE_expect(3), OSSL_STORE_SEARCH(3)

## COPYRIGHT
Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


title: ossl_store-file(7ossl)

summary: The store 'file' scheme loader

text:
# ossl_store-file(7ossl)

## NAME
ossl_store-file - The store 'file' scheme loader

## SYNOPSIS
\#include <openssl/store.h>

## DESCRIPTION
Support for the 'file' scheme is built into "libcrypto". Since files come in all kinds of formats and content types, the 'file' scheme has its own layer of functionality called "file handlers", which are used to try to decode diverse types of file contents.

In case a file is formatted as PEM, each called file handler receives the PEM name (everything following any '"-----BEGIN "') as well as possible PEM headers, together with the decoded PEM body. Since PEM formatted files can contain more than one object, the file handlers are called upon for each such object.

If the file isn't determined to be formatted as PEM, the content is loaded in raw form in its entirety and passed to the available file handlers as is, with no PEM name or headers.

Each file handler is expected to handle PEM and non-PEM content as appropriate. Some may refuse non-PEM content for the sake of determinism (for example, there are keys out in the wild that are represented as an ASN.1 OCTET STRING. In raw form, it's not easily possible to distinguish those from any other data coming as an ASN.1 OCTET STRING, so such keys would naturally be accepted as PEM files only).

## NOTES
When needed, the 'file' scheme loader will require a pass phrase by using the UI_METHOD that was passed via OSSL_STORE_open(). This pass phrase is expected to be UTF-8 encoded, anything else will give an undefined result. The files made accessible through this loader are expected to be standard compliant with regards to pass phrase encoding. Files that aren't should be re-generated with a correctly encoded pass phrase. See passphrase-encoding(7) for more information.

## SEE ALSO
ossl_store(7), passphrase-encoding(7)

## COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


passphrase-encoding

title: passphrase-encoding(7ossl)

summary: encoding

text:
# passphrase-encoding(7ossl)

## NAME
passphrase-encoding - How diverse parts of OpenSSL treat pass phrases character encoding

## DESCRIPTION
In a modern world with all sorts of character encodings, the treatment of pass phrases has become increasingly complex. This manual page attempts to give an overview over how this problem is currently addressed in different parts of the OpenSSL library.

### The general case
The OpenSSL library doesn't treat pass phrases in any special way as a general rule, and trusts the application or user to choose a suitable character set and stick to that throughout the lifetime of affected objects. This means that for an object that was encrypted using a pass phrase encoded in ISO-8859-1, that object needs to be decrypted using a pass phrase encoded in ISO-8859-1. Using the wrong encoding is expected to cause a decryption failure.

### PKCS#12
PKCS#12 is a bit different regarding pass phrase encoding. The standard stipulates that the pass phrase shall be encoded as an ASN.1 BMPString, which consists of the code points of the basic multilingual plane, encoded in big endian (UCS-2 BE).

OpenSSL tries to adapt to this requirements in one of the following manners:

1.

Treats the received pass phrase as UTF-8 encoded and tries to re-encode it to UTF-16 (which is the same as UCS-2 for characters U+0000 to U+D7FF and U+E000 to U+FFFF, but becomes an expansion for any other character), or failing that, proceeds with step 2.

2.

Assumes that the pass phrase is encoded in ASCII or ISO-8859-1 and opportunistically prepends each byte with a zero byte to obtain the UCS-2 encoding of the characters, which it stores as a BMPString. Note that since there is no check of your locale, this may produce UCS-2 / UTF-16 characters that do not correspond to the original pass phrase characters for other character sets, such as any ISO-8859-X encoding other than ISO-8859-1 (or for Windows, CP 1252 with exception for the extra "graphical" characters in the 0x80-0x9F range).

OpenSSL versions older than 1.1.0 do variant 2 only, and that is the reason why OpenSSL still does this, to be able to read files produced with older versions.

It should be noted that this approach isn't entirely fault free.

A pass phrase encoded in ISO-8859-2 could very well have a sequence such as 0xC3 0xAF (which is the two characters "LATIN CAPITAL LETTER A WITH BREVE" and "LATIN CAPITAL LETTER Z WITH DOT ABOVE" in ISO-8859-2 encoding), but would be misinterpreted as the perfectly valid UTF-8 encoded code point U+00EF (LATIN SMALL LETTER I WITH DIAERESIS) if the pass phrase doesn't contain anything that would be invalid UTF-8. A pass phrase that contains this kind of byte sequence will give a different outcome in OpenSSL 1.1.0 and newer than in OpenSSL older than 1.1.0.

```
 0x00 0xC3 0x00 0xAF                    # OpenSSL older than 1.1.0
 0x00 0xEF                              # OpenSSL 1.1.0 and newer
```

On the same accord, anything encoded in UTF-8 that was given to OpenSSL older than 1.1.0 was misinterpreted as ISO-8859-1 sequences.

### OSSL_STORE
ossl_store(7) acts as a general interface to access all kinds of objects, potentially protected with a pass phrase, a PIN or something else. This API stipulates that pass phrases should be UTF-8 encoded, and that any other pass phrase encoding may give undefined results. This API relies on the application to ensure UTF-8 encoding, and doesn't check that this is the case, so what it gets, it will also pass to the underlying loader.

## RECOMMENDATIONS
This section assumes that you know what pass phrase was used for encryption, but that it may have been encoded in a different character encoding than the one used by your current input method. For example, the pass phrase may have been used at a time when your default encoding was ISO-8859-1 (i.e. "naïve" resulting in the byte sequence 0x6E 0x61 0xEF 0x76 0x65), and you're now in an environment where your default encoding is UTF-8 (i.e. "naïve" resulting in the byte sequence 0x6E 0x61 0xC3 0xAF 0x76 0x65). Whenever it's mentioned that you should use a certain character encoding, it should be understood that you either change the input method to use the mentioned encoding when you type in your pass phrase, or use some suitable tool to convert your pass phrase from your default encoding to the target encoding.

Also note that the sub-sections below discuss human readable pass phrases. This is particularly relevant for PKCS#12 objects, where human readable pass phrases are assumed. For other objects, it's as legitimate to use any byte sequence (such as a sequence of bytes from /dev/urandom that's been saved away), which makes any character encoding discussion irrelevant; in such cases, simply use the same byte sequence as it is.

### Creating new objects
For creating new pass phrase protected objects, make sure the pass phrase is encoded using UTF-8. This is default on most modern Unixes, but may involve an effort on other platforms. Specifically for Windows, setting the environment variable OPENSSL_WIN32_UTF8 will have anything entered on [Windows] console prompt converted to UTF-8 (command line and separately prompted pass phrases alike).

### Opening existing objects
For opening pass phrase protected objects where you know what character encoding was used for the encryption pass phrase, make sure to use the same encoding again.

For opening pass phrase protected objects where the character encoding that was used is unknown, or where the producing application is unknown, try one of the following:

1.

Try the pass phrase that you have as it is in the character encoding of your environment. It's possible that its byte sequence is exactly right.

2.

Convert the pass phrase to UTF-8 and try with the result. Specifically with PKCS#12, this should open up any object that was created according to the specification.

3.

Do a naïve (i.e. purely mathematical) ISO-8859-1 to UTF-8 conversion and try with the result. This differs from the previous attempt because ISO-8859-1 maps directly to U+0000 to U+00FF, which other non-UTF-8 character sets do not. This also takes care of the case when a UTF-8 encoded string was used with OpenSSL older than 1.1.0. (for example, "ï", which is 0xC3 0xAF when encoded in UTF-8, would become 0xC3 0x83 0xC2 0xAF when re-encoded in the naïve manner. The conversion to BMPString would then yield 0x00 0xC3 0x00 0xA4 0x00 0x00, the erroneous/non-compliant encoding used by OpenSSL older than 1.1.0)

## SEE ALSO
evp(7), ossl_store(7), EVP_BytesToKey(3), EVP_DecryptInit(3), PEM_do_header(3), PKCS12_parse(3), PKCS12_newpass(3), d2i_PKCS8PrivateKey_bio(3)

## COPYRIGHT
Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


property

title: property(7ossl)

text:
# property(7ossl)

## NAME
property - Properties, a selection mechanism for algorithm implementations

## DESCRIPTION
As of OpenSSL 3.0, a new method has been introduced to decide which of multiple implementations of an algorithm will be used. The method is centered around the concept of properties. Each implementation defines a number of properties and when an algorithm is being selected, filters based on these properties can be used to choose the most appropriate implementation of the algorithm.

Properties are like variables, they are referenced by name and have a value assigned.

### Property Names
Property names fall into two categories: those reserved by the OpenSSL project and user defined names. A reserved property name consists of a single C-style identifier (except for leading underscores not being permitted), which begins with a letter and can be followed by any number of letters, numbers and underscores. Property names are case-insensitive, but OpenSSL will only use lowercase letters.

A user defined property name is similar, but it must consist of two or more C-style identifiers, separated by periods. The last identifier in the name can be considered the 'true' property name, which is prefixed by some sort of 'namespace'. Providers for example could include their name in the prefix and use property names like

```
  <provider_name>.<property_name>
  <provider_name>.<algorithm_name>.<property_name>
```

### Properties
A property is a name=value pair. A property definition is a sequence of comma separated properties. There can be any number of properties in a definition, however each name must be unique. For example: "" defines an empty property definition (i.e., no restriction); "my.foo=bar" defines a property named my.foo which has a string value bar and "iteration.count=3" defines a property named iteration.count which has a numeric value of 3. The full syntax for property definitions appears below.

### Implementations
Each implementation of an algorithm can define any number of properties. For example, the default provider defines the property provider=default for all of its algorithms. Likewise, OpenSSL's FIPS provider defines provider=fips and the legacy provider defines provider=legacy for all of their algorithms.

### Queries
A property query clause is a single conditional test. For example, "fips=yes", "provider!=default" or "?iteration.count=3". The first two represent mandatory clauses, such clauses must match for any algorithm to even be under consideration. The third clause represents an optional clause. Matching such clauses is not a requirement, but any additional optional match counts in favor of the algorithm. More details about that in the Lookups section. A property query is a sequence of comma separated property query clauses. It is an error if a property name appears in more than one query clause. The full syntax for property queries appears below, but the available syntactic features are:

- = is an infix operator providing an equality test.

- != is an infix operator providing an inequality test.

- ? is a prefix operator that means that the following clause is optional but preferred.

- - is a prefix operator that means any global query clause involving the following property name should be ignored.

- "..." is a quoted string. The quotes are not included in the body of the string.

- '...' is a quoted string. The quotes are not included in the body of the string.

### Lookups
When an algorithm is looked up, a property query is used to determine the best matching algorithm. All mandatory query clauses must be present and the implementation that additionally has the largest number of matching optional query clauses will be used. If there is more than one such optimal candidate, the result will be chosen from amongst those in an indeterminate way. Ordering of optional clauses is not significant.

### Shortcut
In order to permit a more concise expression of boolean properties, there is one short cut: a property name alone (e.g. "my.property") is exactly equivalent to "my.property=yes" in both definitions and queries.

### Global and Local
Two levels of property query are supported. A context based property query that applies to all fetch operations and a local property query. Where both the context and local queries include a clause with the same name, the local clause overrides the context clause.

It is possible for a local property query to remove a clause in the context property query by preceding the property name with a '-'. For example, a context property query that contains "fips=yes" would normally result in implementations that have "fips=yes".

However, if the setting of the "fips" property is irrelevant to the operations being performed, the local property query can include the clause "-fips". Note that the local property query could not use "fips=no" because that would disallow any implementations with "fips=yes" rather than not caring about the setting.

## SYNTAX
The lexical syntax in EBNF is given by:

```
 Definition     ::= PropertyName ( '=' Value )?
                        ( ',' PropertyName ( '=' Value )? )*
 Query          ::= PropertyQuery ( ',' PropertyQuery )*
 PropertyQuery  ::= '-' PropertyName
                  | '?'? ( PropertyName (( '=' | '!=' ) Value)?)
 Value          ::= NumberLiteral | StringLiteral
 StringLiteral  ::= QuotedString | UnquotedString
 QuotedString   ::= '"' [^"]* '"' | "'" [^']* "'"
 UnquotedString ::= [A-Za-z] [^{space},]+
 NumberLiteral  ::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ ) | '-'? [1-9] [0-9]+
 PropertyName   ::= [A-Za-z] [A-Za-z0-9_]* ( '.' [A-Za-z] [A-Za-z0-9_]* )*
```

The flavour of EBNF being used is defined by: <https://www.w3.org/TR/2010/REC-xquery-20101214/#EBNFNotation>.

## HISTORY
Properties were added in OpenSSL 3.0

## COPYRIGHT
Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


provider

title: provider(7ossl)

text:
# provider(7ossl)

## NAME
provider - OpenSSL operation implementation providers

## SYNOPSIS
\#include <openssl/provider.h>

## DESCRIPTION

### General
This page contains information useful to provider authors.

A provider, in OpenSSL terms, is a unit of code that provides one or more implementations for various operations for diverse algorithms that one might want to perform.

An operation is something one wants to do, such as encryption and decryption, key derivation, MAC calculation, signing and verification, etc.

An algorithm is a named method to perform an operation. Very often, the algorithms revolve around cryptographic operations, but may also revolve around other types of operation, such as managing certain types of objects.

See crypto(7) for further details.

### Provider
A provider offers an initialization function, as a set of base functions in the form of an OSSL_DISPATCH(3) array, and by extension, a set of OSSL_ALGORITHM(3)s (see openssl-core.h(7)). It may be a dynamically loadable module, or may be built-in, in OpenSSL libraries or in the application. If it's a dynamically loadable module, the initialization function must be named "OSSL_provider_init" and must be exported. If it's built-in, the initialization function may have any name.

The initialization function must have the following signature:

```
 int NAME(const OSSL_CORE_HANDLE *handle,
          const OSSL_DISPATCH *in, const OSSL_DISPATCH **out,
          void **provctx);
```

handle is the OpenSSL library object for the provider, and works as a handle for everything the OpenSSL libraries need to know about the provider. For the provider itself, it is passed to some of the functions given in the dispatch array in.

in is a dispatch array of base functions offered by the OpenSSL libraries, and the available functions are further described in provider-base(7).

*out must be assigned a dispatch array of base functions that the provider offers to the OpenSSL libraries. The functions that may be offered are further described in provider-base(7), and they are the central means of communication between the OpenSSL libraries and the provider.

*provctx should be assigned a provider specific context to allow the provider multiple simultaneous uses. This pointer will be passed to various operation functions offered by the provider.

Note that the provider will not be made available for applications to use until the initialization function has completed and returned successfully.

One of the functions the provider offers to the OpenSSL libraries is the central mechanism for the OpenSSL libraries to get access to operation implementations for diverse algorithms. Its referred to with the number OSSL_FUNC_PROVIDER_QUERY_OPERATION and has the following signature:

```
 const OSSL_ALGORITHM *provider_query_operation(void *provctx,
                                                int operation_id,
                                                const int *no_store);
```

provctx is the provider specific context that was passed back by the initialization function.

operation_id is an operation identity (see "Operations" below).

no_store is a flag back to the OpenSSL libraries which, when nonzero, signifies that the OpenSSL libraries will not store a reference to the returned data in their internal store of implementations.

The returned OSSL_ALGORITHM(3) is the foundation of any OpenSSL library API that uses providers for their implementation, most commonly in the fetching type of functions (see "ALGORITHM FETCHING" in crypto(7)).

### Operations
Operations are referred to with numbers, via macros with names starting with "OSSL_OP_".

With each operation comes a set of defined function types that a provider may or may not offer, depending on its needs.

Currently available operations are:

Digests

In the OpenSSL libraries, the corresponding method object is EVP_MD. The number for this operation is OSSL_OP_DIGEST. The functions the provider can offer are described in provider-digest(7).

Symmetric ciphers

In the OpenSSL libraries, the corresponding method object is EVP_CIPHER. The number for this operation is OSSL_OP_CIPHER. The functions the provider can offer are described in provider-cipher(7).

Message Authentication Code (MAC)

In the OpenSSL libraries, the corresponding method object is EVP_MAC. The number for this operation is OSSL_OP_MAC. The functions the provider can offer are described in provider-mac(7).

Key Derivation Function (KDF)

In the OpenSSL libraries, the corresponding method object is EVP_KDF. The number for this operation is OSSL_OP_KDF. The functions the provider can offer are described in provider-kdf(7).

Key Exchange

In the OpenSSL libraries, the corresponding method object is EVP_KEYEXCH. The number for this operation is OSSL_OP_KEYEXCH. The functions the provider can offer are described in provider-keyexch(7).

Asymmetric Ciphers

In the OpenSSL libraries, the corresponding method object is EVP_ASYM_CIPHER. The number for this operation is OSSL_OP_ASYM_CIPHER. The functions the provider can offer are described in provider-asym_cipher(7).

Asymmetric Key Encapsulation

In the OpenSSL libraries, the corresponding method object is EVP_KEM. The number for this operation is OSSL_OP_KEM. The functions the provider can offer are described in provider-kem(7).

Encoding

In the OpenSSL libraries, the corresponding method object is OSSL_ENCODER. The number for this operation is OSSL_OP_ENCODER. The functions the provider can offer are described in provider-encoder(7).

Decoding

In the OpenSSL libraries, the corresponding method object is OSSL_DECODER. The number for this operation is OSSL_OP_DECODER. The functions the provider can offer are described in provider-decoder(7).

Random Number Generation

The number for this operation is OSSL_OP_RAND. The functions the provider can offer for random number generation are described in provider-rand(7).

Key Management

The number for this operation is OSSL_OP_KEYMGMT. The functions the provider can offer for key management are described in provider-keymgmt(7).

Signing and Signature Verification

The number for this operation is OSSL_OP_SIGNATURE. The functions the provider can offer for digital signatures are described in provider-signature(7).

Store Management

The number for this operation is OSSL_OP_STORE. The functions the provider can offer for store management are described in provider-storemgmt(7).

Algorithm naming

Algorithm names are case insensitive. Any particular algorithm can have multiple aliases associated with it. The canonical OpenSSL naming scheme follows this format:

ALGNAME[VERSION?][-SUBNAME[VERSION?]?][-SIZE?][-MODE?]

VERSION is only present if there are multiple versions of an algorithm (e.g. MD2, MD4, MD5). It may be omitted if there is only one version.

SUBNAME may be present where multiple algorithms are combined together, e.g. MD5-SHA1.

SIZE is only present if multiple versions of an algorithm exist with different sizes (e.g. AES-128-CBC, AES-256-CBC)

MODE is only present where applicable.

Other aliases may exist for example where standards bodies or common practice use alternative names or names that OpenSSL has used historically.

Provider dependencies

Providers may depend for their proper operation on the availability of (functionality implemented in) other providers. As there is no mechanism to express such dependencies towards the OpenSSL core, provider authors must take care that such dependencies are either completely avoided or made visible to users, e.g., by documentation and/or defensive programming, e.g., outputting error messages if required external dependencies are not available, e.g., when no provider implementing the required functionality has been activated. In particular, provider initialization should not depend on other providers already having been initialized.

Note on naming clashes

It is possible to register the same algorithm name from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation of a particular algorithm will be returned. Such naming clashes may also occur if algorithms only differ in capitalization as "Algorithm naming" is case insensitive.

## OPENSSL PROVIDERS
OpenSSL provides a number of its own providers. These are the default, base, fips, legacy and null providers. See crypto(7) for an overview of these providers.

## SEE ALSO
EVP_DigestInit_ex(3), EVP_EncryptInit_ex(3), OSSL_LIB_CTX(3), EVP_set_default_properties(3), EVP_MD_fetch(3), EVP_CIPHER_fetch(3), EVP_KEYMGMT_fetch(3), openssl-core.h(7), provider-base(7), provider-digest(7), provider-cipher(7), provider-keyexch(7)

## HISTORY
The concept of providers and everything surrounding them was introduced in OpenSSL 3.0.

## COPYRIGHT
Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


title: provider-asym_cipher(7ossl)

summary: The asym_cipher library <\-> provider functions

text:
# provider-asym_cipher(7ossl)

## NAME
provider-asym_cipher - The asym_cipher library <-> provider functions

## SYNOPSIS

```
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
 /*
  * None of these are actual functions, but are displayed like this for
  * the function signatures for functions that are offered as function
  * pointers in OSSL_DISPATCH arrays.
  */
 /* Context management */
 void *OSSL_FUNC_asym_cipher_newctx(void *provctx);
 void OSSL_FUNC_asym_cipher_freectx(void *ctx);
 void *OSSL_FUNC_asym_cipher_dupctx(void *ctx);
 /* Encryption */
 int OSSL_FUNC_asym_cipher_encrypt_init(void *ctx, void *provkey,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_asym_cipher_encrypt(void *ctx, unsigned char *out, size_t *outlen,
                                   size_t outsize, const unsigned char *in,
                                   size_t inlen);
 /* Decryption */
 int OSSL_FUNC_asym_cipher_decrypt_init(void *ctx, void *provkey,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_asym_cipher_decrypt(void *ctx, unsigned char *out, size_t *outlen,
                                   size_t outsize, const unsigned char *in,
                                   size_t inlen);
 /* Asymmetric Cipher parameters */
 int OSSL_FUNC_asym_cipher_get_ctx_params(void *ctx, OSSL_PARAM params[]);
 const OSSL_PARAM *OSSL_FUNC_asym_cipher_gettable_ctx_params(void *provctx);
 int OSSL_FUNC_asym_cipher_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
 const OSSL_PARAM *OSSL_FUNC_asym_cipher_settable_ctx_params(void *provctx);
```

## DESCRIPTION
This documentation is primarily aimed at provider authors. See provider(7) for further information.

The asymmetric cipher (OSSL_OP_ASYM_CIPHER) operation enables providers to implement asymmetric cipher algorithms and make them available to applications via the API functions EVP_PKEY_encrypt(3), EVP_PKEY_decrypt(3) and other related functions).

All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays via OSSL_ALGORITHM(3) arrays that are returned by the provider's provider_query_operation() function (see "Provider Functions" in provider-base(7)).

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from an OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. For example, the "function" OSSL_FUNC_asym_cipher_newctx() has these:

```
 typedef void *(OSSL_FUNC_asym_cipher_newctx_fn)(void *provctx);
 static ossl_inline OSSL_FUNC_asym_cipher_newctx_fn
     OSSL_FUNC_asym_cipher_newctx(const OSSL_DISPATCH *opf);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

```
 OSSL_FUNC_asym_cipher_newctx               OSSL_FUNC_ASYM_CIPHER_NEWCTX
 OSSL_FUNC_asym_cipher_freectx              OSSL_FUNC_ASYM_CIPHER_FREECTX
 OSSL_FUNC_asym_cipher_dupctx               OSSL_FUNC_ASYM_CIPHER_DUPCTX
 OSSL_FUNC_asym_cipher_encrypt_init         OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT
 OSSL_FUNC_asym_cipher_encrypt              OSSL_FUNC_ASYM_CIPHER_ENCRYPT
 OSSL_FUNC_asym_cipher_decrypt_init         OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT
 OSSL_FUNC_asym_cipher_decrypt              OSSL_FUNC_ASYM_CIPHER_DECRYPT
 OSSL_FUNC_asym_cipher_get_ctx_params       OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS
 OSSL_FUNC_asym_cipher_gettable_ctx_params  OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS
 OSSL_FUNC_asym_cipher_set_ctx_params       OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS
 OSSL_FUNC_asym_cipher_settable_ctx_params  OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS
```

An asymmetric cipher algorithm implementation may not implement all of these functions. In order to be a consistent set of functions a provider must implement OSSL_FUNC_asym_cipher_newctx and OSSL_FUNC_asym_cipher_freectx. It must also implement both of OSSL_FUNC_asym_cipher_encrypt_init and OSSL_FUNC_asym_cipher_encrypt, or both of OSSL_FUNC_asym_cipher_decrypt_init and OSSL_FUNC_asym_cipher_decrypt. OSSL_FUNC_asym_cipher_get_ctx_params is optional but if it is present then so must OSSL_FUNC_asym_cipher_gettable_ctx_params. Similarly, OSSL_FUNC_asym_cipher_set_ctx_params is optional but if it is present then so must OSSL_FUNC_asym_cipher_settable_ctx_params.

An asymmetric cipher algorithm must also implement some mechanism for generating, loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation. See provider-keymgmt(7) for further details.

### Context Management Functions
OSSL_FUNC_asym_cipher_newctx() should create and return a pointer to a provider side structure for holding context information during an asymmetric cipher operation. A pointer to this context will be passed back in a number of the other asymmetric cipher operation function calls. The parameter provctx is the provider context generated during provider initialisation (see provider(7)).

OSSL_FUNC_asym_cipher_freectx() is passed a pointer to the provider side asymmetric cipher context in the ctx parameter. This function should free any resources associated with that context.

OSSL_FUNC_asym_cipher_dupctx() should duplicate the provider side asymmetric cipher context in the ctx parameter and return the duplicate copy.

### Encryption Functions
OSSL_FUNC_asym_cipher_encrypt_init() initialises a context for an asymmetric encryption given a provider side asymmetric cipher context in the ctx parameter, and a pointer to a provider key object in the provkey parameter. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_asym_cipher_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)). OSSL_FUNC_asym_cipher_encrypt() performs the actual encryption itself. A previously initialised asymmetric cipher context is passed in the ctx parameter. The data to be encrypted is pointed to by the in parameter which is inlen bytes long. Unless out is NULL, the encrypted data should be written to the location pointed to by the out parameter and it should not exceed outsize bytes in length. The length of the encrypted data should be written to *outlen. If out is NULL then the maximum length of the encrypted data should be written to *outlen.

### Decryption Functions
OSSL_FUNC_asym_cipher_decrypt_init() initialises a context for an asymmetric decryption given a provider side asymmetric cipher context in the ctx parameter, and a pointer to a provider key object in the provkey parameter. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_asym_cipher_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)).

OSSL_FUNC_asym_cipher_decrypt() performs the actual decryption itself. A previously initialised asymmetric cipher context is passed in the ctx parameter. The data to be decrypted is pointed to by the in parameter which is inlen bytes long. Unless out is NULL, the decrypted data should be written to the location pointed to by the out parameter and it should not exceed outsize bytes in length. The length of the decrypted data should be written to *outlen. If out is NULL then the maximum length of the decrypted data should be written to *outlen.

### Asymmetric Cipher Parameters
See OSSL_PARAM(3) for further details on the parameters structure used by the OSSL_FUNC_asym_cipher_get_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() functions.

OSSL_FUNC_asym_cipher_get_ctx_params() gets asymmetric cipher parameters associated with the given provider side asymmetric cipher context ctx and stores them in params. Passing NULL for params should return true.

OSSL_FUNC_asym_cipher_set_ctx_params() sets the asymmetric cipher parameters associated with the given provider side asymmetric cipher context ctx to params. Any parameter settings are additional to any that were previously set. Passing NULL for params should return true.

Parameters currently recognised by built-in asymmetric cipher algorithms are as follows. Not all parameters are relevant to, or are understood by all asymmetric cipher algorithms:

"pad-mode" (OSSL_ASYM_CIPHER_PARAM_PAD_MODE) <UTF8 string> OR <integer>

The type of padding to be used. The interpretation of this value will depend on the algorithm in use.

"digest" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST) <UTF8 string>

Gets or sets the name of the OAEP digest algorithm used when OAEP padding is in use.

"digest" (OSSL_ASYM_CIPHER_PARAM_DIGEST) <UTF8 string>

Gets or sets the name of the digest algorithm used by the algorithm (where applicable).

"digest-props" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the OAEP digest algorithm.

"digest-props" (OSSL_ASYM_CIPHER_PARAM_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the cipher digest algorithm.

"mgf1-digest" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST) <UTF8 string>

Gets or sets the name of the MGF1 digest algorithm used when OAEP or PSS padding is in use.

"mgf1-digest-props" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the MGF1 digest algorithm.

"oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string ptr>

Gets the OAEP label used when OAEP padding is in use.

"oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string>

Sets the OAEP label used when OAEP padding is in use.

"tls-client-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer>

The TLS protocol version first requested by the client.

"tls-negotiated-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer>

The negotiated TLS protocol version.

"implicit-rejection" (OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION) <unsigned integer>

Gets or sets the use of the implicit rejection mechanism for RSA PKCS#1 v1.5 decryption. When set (non zero value), the decryption API will return a deterministically random value if the PKCS#1 v1.5 padding check fails. This makes exploitation of the Bleichenbacher significantly harder, even if the code using the RSA decryption API is not implemented in side-channel free manner. Set by default in OpenSSL providers.

OSSL_FUNC_asym_cipher_gettable_ctx_params() and OSSL_FUNC_asym_cipher_settable_ctx_params() get a constant OSSL_PARAM(3) array that describes the gettable and settable parameters, i.e. parameters that can be used with OSSL_FUNC_asym_cipherget_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() respectively.

## RETURN VALUES
OSSL_FUNC_asym_cipher_newctx() and OSSL_FUNC_asym_cipher_dupctx() should return the newly created provider side asymmetric cipher context, or NULL on failure.

All other functions should return 1 for success or 0 on error.

## SEE ALSO
provider(7)

## HISTORY
The provider ASYM_CIPHER interface was introduced in OpenSSL 3.0.

## COPYRIGHT
Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


provider-base

title: provider-base(7ossl)

summary: base

text:
# provider-base(7ossl)

## NAME
provider-base - The basic OpenSSL library <-> provider functions

## SYNOPSIS

```
 #include <openssl/core_dispatch.h>
 /*
  * None of these are actual functions, but are displayed like this for
  * the function signatures for functions that are offered as function
  * pointers in OSSL_DISPATCH arrays.
  */
 /* Functions offered by libcrypto to the providers */
 const OSSL_ITEM *core_gettable_params(const OSSL_CORE_HANDLE *handle);
 int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]);
 typedef void (*OSSL_thread_stop_handler_fn)(void *arg);
 int core_thread_start(const OSSL_CORE_HANDLE *handle,
                       OSSL_thread_stop_handler_fn handfn,
                       void *arg);
 OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle);
 void core_new_error(const OSSL_CORE_HANDLE *handle);
 void core_set_error_debug(const OSSL_CORE_HANDLE *handle,
                           const char *file, int line, const char *func);
 void core_vset_error(const OSSL_CORE_HANDLE *handle,
                      uint32_t reason, const char *fmt, va_list args);
 int core_obj_add_sigid(const OSSL_CORE_HANDLE *prov, const char  *sign_name,
                        const char *digest_name, const char *pkey_name);
 int core_obj_create(const OSSL_CORE_HANDLE *handle, const char *oid,
                     const char *sn, const char *ln);
 /*
  * Some OpenSSL functionality is directly offered to providers via
  * dispatch
  */
 void *CRYPTO_malloc(size_t num, const char *file, int line);
 void *CRYPTO_zalloc(size_t num, const char *file, int line);
 void CRYPTO_free(void *ptr, const char *file, int line);
 void CRYPTO_clear_free(void *ptr, size_t num,
                        const char *file, int line);
 void *CRYPTO_realloc(void *addr, size_t num,
                      const char *file, int line);
 void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
                            const char *file, int line);
 void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
 void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
 void CRYPTO_secure_free(void *ptr, const char *file, int line);
 void CRYPTO_secure_clear_free(void *ptr, size_t num,
                               const char *file, int line);
 int CRYPTO_secure_allocated(const void *ptr);
 void OPENSSL_cleanse(void *ptr, size_t len);
 unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen);
 OSSL_CORE_BIO *BIO_new_file(const char *filename, const char *mode);
 OSSL_CORE_BIO *BIO_new_membuf(const void *buf, int len);
 int BIO_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
                 size_t *bytes_read);
 int BIO_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
                  size_t *written);
 int BIO_up_ref(OSSL_CORE_BIO *bio);
 int BIO_free(OSSL_CORE_BIO *bio);
 int BIO_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list args);
 int BIO_vsnprintf(char *buf, size_t n, const char *fmt, va_list args);
 void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb,
                                  void *cbarg);
 size_t get_entropy(const OSSL_CORE_HANDLE *handle,
                    unsigned char **pout, int entropy,
                    size_t min_len, size_t max_len);
 size_t get_user_entropy(const OSSL_CORE_HANDLE *handle,
                         unsigned char **pout, int entropy,
                         size_t min_len, size_t max_len);
 void cleanup_entropy(const OSSL_CORE_HANDLE *handle,
                      unsigned char *buf, size_t len);
 void cleanup_user_entropy(const OSSL_CORE_HANDLE *handle,
                           unsigned char *buf, size_t len);
 size_t get_nonce(const OSSL_CORE_HANDLE *handle,
                  unsigned char **pout, size_t min_len, size_t max_len,
                  const void *salt, size_t salt_len);
 size_t get_user_nonce(const OSSL_CORE_HANDLE *handle,
                       unsigned char **pout, size_t min_len, size_t max_len,
                       const void *salt, size_t salt_len);
 void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
                    unsigned char *buf, size_t len);
 void cleanup_user_nonce(const OSSL_CORE_HANDLE *handle,
                         unsigned char *buf, size_t len);
 /* Functions for querying the providers in the application library context */
 int provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
                     int (*create_cb)(const OSSL_CORE_HANDLE *provider,
                                      void *cbdata),
                     int (*remove_cb)(const OSSL_CORE_HANDLE *provider,
                                      void *cbdata),
                     int (*global_props_cb)(const char *props, void *cbdata),
                     void *cbdata);
 void provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle);
 const char *provider_name(const OSSL_CORE_HANDLE *prov);
 void *provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov);
 const OSSL_DISPATCH *provider_get0_dispatch(const OSSL_CORE_HANDLE *prov);
 int provider_up_ref(const OSSL_CORE_HANDLE *prov, int activate);
 int provider_free(const OSSL_CORE_HANDLE *prov, int deactivate);
 /* Functions offered by the provider to libcrypto */
 void provider_teardown(void *provctx);
 const OSSL_ITEM *provider_gettable_params(void *provctx);
 int provider_get_params(void *provctx, OSSL_PARAM params[]);
 const OSSL_ALGORITHM *provider_query_operation(void *provctx,
                                                int operation_id,
                                                const int *no_store);
 void provider_unquery_operation(void *provctx, int operation_id,
                                 const OSSL_ALGORITHM *algs);
 const OSSL_ITEM *provider_get_reason_strings(void *provctx);
 int provider_get_capabilities(void *provctx, const char *capability,
                               OSSL_CALLBACK *cb, void *arg);
 int provider_self_test(void *provctx);
```

## DESCRIPTION
All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays, in the call of the provider initialization function. See "Provider" in provider(7) for a description of the initialization function. They are known as "upcalls".

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from a OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. For example, the "function" core_gettable_params() has these:

```
 typedef OSSL_PARAM *
     (OSSL_FUNC_core_gettable_params_fn)(const OSSL_CORE_HANDLE *handle);
 static ossl_inline OSSL_NAME_core_gettable_params_fn
     OSSL_FUNC_core_gettable_params(const OSSL_DISPATCH *opf);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

For in (the OSSL_DISPATCH(3) array passed from libcrypto to the provider):

```
 core_gettable_params           OSSL_FUNC_CORE_GETTABLE_PARAMS
 core_get_params                OSSL_FUNC_CORE_GET_PARAMS
 core_thread_start              OSSL_FUNC_CORE_THREAD_START
 core_get_libctx                OSSL_FUNC_CORE_GET_LIBCTX
 core_new_error                 OSSL_FUNC_CORE_NEW_ERROR
 core_set_error_debug           OSSL_FUNC_CORE_SET_ERROR_DEBUG
 core_vset_error                OSSL_FUNC_CORE_VSET_ERROR
 core_obj_add_sigid             OSSL_FUNC_CORE_OBJ_ADD_SIGID
 core_obj_create                OSSL_FUNC_CORE_OBJ_CREATE
 CRYPTO_malloc                  OSSL_FUNC_CRYPTO_MALLOC
 CRYPTO_zalloc                  OSSL_FUNC_CRYPTO_ZALLOC
 CRYPTO_free                    OSSL_FUNC_CRYPTO_FREE
 CRYPTO_clear_free              OSSL_FUNC_CRYPTO_CLEAR_FREE
 CRYPTO_realloc                 OSSL_FUNC_CRYPTO_REALLOC
 CRYPTO_clear_realloc           OSSL_FUNC_CRYPTO_CLEAR_REALLOC
 CRYPTO_secure_malloc           OSSL_FUNC_CRYPTO_SECURE_MALLOC
 CRYPTO_secure_zalloc           OSSL_FUNC_CRYPTO_SECURE_ZALLOC
 CRYPTO_secure_free             OSSL_FUNC_CRYPTO_SECURE_FREE
 CRYPTO_secure_clear_free       OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE
 CRYPTO_secure_allocated        OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
 BIO_new_file                   OSSL_FUNC_BIO_NEW_FILE
 BIO_new_mem_buf                OSSL_FUNC_BIO_NEW_MEMBUF
 BIO_read_ex                    OSSL_FUNC_BIO_READ_EX
 BIO_write_ex                   OSSL_FUNC_BIO_WRITE_EX
 BIO_up_ref                     OSSL_FUNC_BIO_UP_REF
 BIO_free                       OSSL_FUNC_BIO_FREE
 BIO_vprintf                    OSSL_FUNC_BIO_VPRINTF
 BIO_vsnprintf                  OSSL_FUNC_BIO_VSNPRINTF
 BIO_puts                       OSSL_FUNC_BIO_PUTS
 BIO_gets                       OSSL_FUNC_BIO_GETS
 BIO_ctrl                       OSSL_FUNC_BIO_CTRL
 OPENSSL_cleanse                OSSL_FUNC_OPENSSL_CLEANSE
 OSSL_SELF_TEST_set_callback    OSSL_FUNC_SELF_TEST_CB
 ossl_rand_get_entropy          OSSL_FUNC_GET_ENTROPY
 ossl_rand_get_user_entropy     OSSL_FUNC_GET_USER_ENTROPY
 ossl_rand_cleanup_entropy      OSSL_FUNC_CLEANUP_ENTROPY
 ossl_rand_cleanup_user_entropy OSSL_FUNC_CLEANUP_USER_ENTROPY
 ossl_rand_get_nonce            OSSL_FUNC_GET_NONCE
 ossl_rand_get_user_nonce       OSSL_FUNC_GET_USER_NONCE
 ossl_rand_cleanup_nonce        OSSL_FUNC_CLEANUP_NONCE
 ossl_rand_cleanup_user_nonce   OSSL_FUNC_CLEANUP_USER_NONCE
 provider_register_child_cb     OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB
 provider_deregister_child_cb   OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB
 provider_name                  OSSL_FUNC_PROVIDER_NAME
 provider_get0_provider_ctx     OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX
 provider_get0_dispatch         OSSL_FUNC_PROVIDER_GET0_DISPATCH
 provider_up_ref                OSSL_FUNC_PROVIDER_UP_REF
 provider_free                  OSSL_FUNC_PROVIDER_FREE
```

For *out (the OSSL_DISPATCH(3) array passed from the provider to libcrypto):

```
 provider_teardown              OSSL_FUNC_PROVIDER_TEARDOWN
 provider_gettable_params       OSSL_FUNC_PROVIDER_GETTABLE_PARAMS
 provider_get_params            OSSL_FUNC_PROVIDER_GET_PARAMS
 provider_query_operation       OSSL_FUNC_PROVIDER_QUERY_OPERATION
 provider_unquery_operation     OSSL_FUNC_PROVIDER_UNQUERY_OPERATION
 provider_get_reason_strings    OSSL_FUNC_PROVIDER_GET_REASON_STRINGS
 provider_get_capabilities      OSSL_FUNC_PROVIDER_GET_CAPABILITIES
 provider_self_test             OSSL_FUNC_PROVIDER_SELF_TEST
```

### Core functions
core_gettable_params() returns a constant array of descriptor OSSL_PARAM(3), for parameters that core_get_params() can handle.

core_get_params() retrieves parameters from the core for the given handle. See "Core parameters" below for a description of currently known parameters.

The core_thread_start() function informs the core that the provider has stated an interest in the current thread. The core will inform the provider when the thread eventually stops. It must be passed the handle for this provider, as well as a callback handfn which will be called when the thread stops. The callback will subsequently be called, with the supplied argument arg, from the thread that is stopping and gets passed the provider context as an argument. This may be useful to perform thread specific clean up such as freeing thread local variables.

core_get_libctx() retrieves the core context in which the library object for the current provider is stored, accessible through the handle. This function is useful only for built-in providers such as the default provider. Never cast this to OSSL_LIB_CTX in a provider that is not built-in as the OSSL_LIB_CTX of the library loading the provider might be a completely different structure than the OSSL_LIB_CTX of the library the provider is linked to. Use OSSL_LIB_CTX_new_child(3) instead to obtain a proper library context that is linked to the application library context.

core_new_error(), core_set_error_debug() and core_vset_error() are building blocks for reporting an error back to the core, with reference to the handle.

core_new_error()

allocates a new thread specific error record. This corresponds to the OpenSSL function ERR_new(3).

core_set_error_debug()

sets debugging information in the current thread specific error record. The debugging information includes the name of the file file, the line line and the function name func where the error occurred. This corresponds to the OpenSSL function ERR_set_debug(3).

core_vset_error()

sets the reason for the error, along with any addition data. The reason is a number defined by the provider and used to index the reason strings table that's returned by provider_get_reason_strings(). The additional data is given as a format string fmt and a set of arguments args, which are treated in the same manner as with BIO_vsnprintf(). file and line may also be passed to indicate exactly where the error occurred or was reported. This corresponds to the OpenSSL function ERR_vset_error(3).

The core_obj_create() function registers a new OID and associated short name sn and long name ln for the given handle. It is similar to the OpenSSL function OBJ_create(3) except that it returns 1 on success or 0 on failure. It will treat as success the case where the OID already exists (even if the short name sn or long name ln provided as arguments differ from those associated with the existing OID, in which case the new names are not associated).

The core_obj_add_sigid() function registers a new composite signature algorithm (sign_name) consisting of an underlying signature algorithm (pkey_name) and digest algorithm (digest_name) for the given handle. It assumes that the OIDs for the composite signature algorithm as well as for the underlying signature and digest algorithms are either already known to OpenSSL or have been registered via a call to core_obj_create(). It corresponds to the OpenSSL function OBJ_add_sigid(3), except that the objects are identified by name rather than a numeric NID. Any name (OID, short name or long name) can be used to identify the object. It will treat as success the case where the composite signature algorithm already exists (even if registered against a different underlying signature or digest algorithm). For digest_name, NULL or an empty string is permissible for signature algorithms that do not need a digest to operate correctly. The function returns 1 on success or 0 on failure.

CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_free(), CRYPTO_clear_free(), CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(), CRYPTO_secure_zalloc(), CRYPTO_secure_free(), CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(), BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_write_ex(), BIO_up_ref(), BIO_free(), BIO_vprintf(), BIO_vsnprintf(), BIO_gets(), BIO_puts(), BIO_ctrl(), OPENSSL_cleanse() and OPENSSL_hexstr2buf() correspond exactly to the public functions with the same name. As a matter of fact, the pointers in the OSSL_DISPATCH(3) array are typically direct pointers to those public functions. Note that the BIO functions take an OSSL_CORE_BIO type rather than the standard BIO type. This is to ensure that a provider does not mix BIOs from the core with BIOs used on the provider side (the two are not compatible). OSSL_SELF_TEST_set_callback() is used to set an optional callback that can be passed into a provider. This may be ignored by a provider.

get_entropy() retrieves seeding material from the operating system. The seeding material will have at least entropy bytes of randomness and the output will have at least min_len and at most max_len bytes. The buffer address is stored in *pout and the buffer length is returned to the caller. On error, zero is returned.

get_user_entropy() is the same as get_entropy() except that it will attempt to gather seed material via the seed source specified by a call to RAND_set_seed_source_type(3) or via "Random Configuration" in config(5).

cleanup_entropy() is used to clean up and free the buffer returned by get_entropy(). The entropy pointer returned by get_entropy() is passed in buf and its length in len.

cleanup_user_entropy() is used to clean up and free the buffer returned by get_user_entropy(). The entropy pointer returned by get_user_entropy() is passed in buf and its length in len.

get_nonce() retrieves a nonce using the passed salt parameter of length salt_len and operating system specific information. The salt should contain uniquely identifying information and this is included, in an unspecified manner, as part of the output. The output is stored in a buffer which contains at least min_len and at most max_len bytes. The buffer address is stored in *pout and the buffer length returned to the caller. On error, zero is returned.

get_user_nonce() is the same as get_nonce() except that it will attempt to gather seed material via the seed source specified by a call to RAND_set_seed_source_type(3) or via "Random Configuration" in config(5).

cleanup_nonce() is used to clean up and free the buffer returned by get_nonce(). The nonce pointer returned by get_nonce() is passed in buf and its length in len.

cleanup_user_nonce() is used to clean up and free the buffer returned by get_user_nonce(). The nonce pointer returned by get_user_nonce() is passed in buf and its length in len.

provider_register_child_cb() registers callbacks for being informed about the loading and unloading of providers in the application's library context. handle is this provider's handle and cbdata is this provider's data that will be passed back to the callbacks. It returns 1 on success or 0 otherwise. These callbacks may be called while holding locks in libcrypto. In order to avoid deadlocks the callback implementation must not be long running and must not call other OpenSSL API functions or upcalls.

create_cb is a callback that will be called when a new provider is loaded into the application's library context. It is also called for any providers that are already loaded at the point that this callback is registered. The callback is passed the handle being used for the new provider being loadded and this provider's data in cbdata. It should return 1 on success or 0 on failure.

remove_cb is a callback that will be called when a new provider is unloaded from the application's library context. It is passed the handle being used for the provider being unloaded and this provider's data in cbdata. It should return 1 on success or 0 on failure.

global_props_cb is a callback that will be called when the global properties from the parent library context are changed. It should return 1 on success or 0 on failure.

provider_deregister_child_cb() unregisters callbacks previously registered via provider_register_child_cb(). If provider_register_child_cb() has been called then provider_deregister_child_cb() should be called at or before the point that this provider's teardown function is called.

provider_name() returns a string giving the name of the provider identified by handle.

provider_get0_provider_ctx() returns the provider context that is associated with the provider identified by prov.

provider_get0_dispatch() gets the dispatch table registered by the provider identified by prov when it initialised.

provider_up_ref() increments the reference count on the provider prov. If activate is nonzero then the provider is also loaded if it is not already loaded. It returns 1 on success or 0 on failure.

provider_free() decrements the reference count on the provider prov. If deactivate is nonzero then the provider is also unloaded if it is not already loaded. It returns 1 on success or 0 on failure.

### Provider functions
provider_teardown() is called when a provider is shut down and removed from the core's provider store. It must free the passed provctx.

provider_gettable_params() should return a constant array of descriptor OSSL_PARAM(3), for parameters that provider_get_params() can handle.

provider_get_params() should process the OSSL_PARAM(3) array params, setting the values of the parameters it understands.

provider_query_operation() should return a constant OSSL_ALGORITHM(3) that corresponds to the given operation_id. It should indicate if the core may store a reference to this array by setting *no_store to 0 (core may store a reference) or 1 (core may not store a reference).

provider_unquery_operation() informs the provider that the result of a provider_query_operation() is no longer directly required and that the function pointers have been copied. The operation_id should match that passed to provider_query_operation() and algs should be its return value.

provider_get_reason_strings() should return a constant OSSL_ITEM(3) array that provides reason strings for reason codes the provider may use when reporting errors using core_put_error().

The provider_get_capabilities() function should call the callback cb passing it a set of OSSL_PARAM(3)s and the caller supplied argument arg. The OSSL_PARAM(3)s should provide details about the capability with the name given in the capability argument relevant for the provider context provctx. If a provider supports multiple capabilities with the given name then it may call the callback multiple times (one for each capability). Capabilities can be useful for describing the services that a provider can offer. For further details see the "CAPABILITIES" section below. It should return 1 on success or 0 on error.

The provider_self_test() function should perform known answer tests on a subset of the algorithms that it uses, and may also verify the integrity of the provider module. It should return 1 on success or 0 on error. It will return 1 if this function is not used.

None of these functions are mandatory, but a provider is fairly useless without at least provider_query_operation(), and provider_gettable_params() is fairly useless if not accompanied by provider_get_params().

### Provider parameters
provider_get_params() can return the following provider parameters to the core:

"name" (OSSL_PROV_PARAM_NAME) <UTF8 ptr>

This points to a string that should give a unique name for the provider.

"version" (OSSL_PROV_PARAM_VERSION) <UTF8 ptr>

This points to a string that is a version number associated with this provider. OpenSSL in-built providers use OPENSSL_VERSION_STR, but this may be different for any third party provider. This string is for informational purposes only.

"buildinfo" (OSSL_PROV_PARAM_BUILDINFO) <UTF8 ptr>

This points to a string that is a build information associated with this provider. OpenSSL in-built providers use OPENSSL_FULL_VERSION_STR, but this may be different for any third party provider.

"status" (OSSL_PROV_PARAM_STATUS) <unsigned integer>

This returns 0 if the provider has entered an error state, otherwise it returns 1.

provider_gettable_params() should return the above parameters.

### Core parameters
core_get_params() can retrieve the following core parameters for each provider:

"openssl-version" (OSSL_PROV_PARAM_CORE_VERSION) <UTF8 string ptr>

This points to the OpenSSL libraries' full version string, i.e. the string expanded from the macro OPENSSL_VERSION_STR.

"provider-name" (OSSL_PROV_PARAM_CORE_PROV_NAME) <UTF8 string ptr>

This points to the OpenSSL libraries' idea of what the calling provider is named.

"module-filename" (OSSL_PROV_PARAM_CORE_MODULE_FILENAME) <UTF8 string ptr>

This points to a string containing the full filename of the providers module file.

Additionally, provider specific configuration parameters from the config file are available, in dotted name form. The dotted name form is a concatenation of section names and final config command name separated by periods.

For example, let's say we have the following config example:

```
 config_diagnostics = 1
 openssl_conf = openssl_init
 [openssl_init]
 providers = providers_sect
 [providers_sect]
 foo = foo_sect
 [foo_sect]
 activate = 1
 data1 = 2
 data2 = str
 more = foo_more
 [foo_more]
 data3 = foo,bar
```

The provider will have these additional parameters available:

"activate"

pointing at the string "1"

"data1"

pointing at the string "2"

"data2"

pointing at the string "str"

"more.data3"

pointing at the string "foo,bar"

For more information on handling parameters, see OSSL_PARAM(3) as OSSL_PARAM_int(3).

## CAPABILITIES
Capabilities describe some of the services that a provider can offer. Applications can query the capabilities to discover those services.

"TLS-GROUP" Capability

The "TLS-GROUP" capability can be queried by libssl to discover the list of TLS groups that a provider can support. Each group supported can be used for key exchange (KEX) or key encapsulation method (KEM) during a TLS handshake. TLS clients can advertise the list of TLS groups they support in the supported_groups extension, and TLS servers can select a group from the offered list that they also support. In this way a provider can add to the list of groups that libssl already supports with additional ones.

Each TLS group that a provider supports should be described via the callback passed in through the provider_get_capabilities function. Each group should have the following details supplied (all are mandatory, except OSSL_CAPABILITY_TLS_GROUP_IS_KEM):

"tls-group-name" (OSSL_CAPABILITY_TLS_GROUP_NAME) <UTF8 string>

The name of the group as given in the IANA TLS Supported Groups registry <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.

"tls-group-name-internal" (OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL) <UTF8 string>

The name of the group as known by the provider. This could be the same as the "tls-group-name", but does not have to be.

"tls-group-id" (OSSL_CAPABILITY_TLS_GROUP_ID) <unsigned integer>

The TLS group id value as given in the IANA TLS Supported Groups registry. It is possible to register the same group id from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation for a particular group id will be used.

"tls-group-alg" (OSSL_CAPABILITY_TLS_GROUP_ALG) <UTF8 string>

The name of a Key Management algorithm that the provider offers and that should be used with this group. Keys created should be able to support key exchange or key encapsulation method (KEM), as implied by the optional OSSL_CAPABILITY_TLS_GROUP_IS_KEM flag. The algorithm must support key and parameter generation as well as the key/parameter generation parameter, OSSL_PKEY_PARAM_GROUP_NAME. The group name given via "tls-group-name-internal" above will be passed via OSSL_PKEY_PARAM_GROUP_NAME when libssl wishes to generate keys/parameters.

"tls-group-sec-bits" (OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS) <unsigned integer>

The number of bits of security offered by keys in this group. The number of bits should be comparable with the ones given in table 2 and 3 of the NIST SP800-57 document.

"tls-group-is-kem" (OSSL_CAPABILITY_TLS_GROUP_IS_KEM) <unsigned integer>

Boolean flag to describe if the group should be used in key exchange (KEX) mode (0, default) or in key encapsulation method (KEM) mode (1). This parameter is optional: if not specified, KEX mode is assumed as the default mode for the group.

In KEX mode, in a typical Diffie-Hellman fashion, both sides execute keygen then derive against the peer public key. To operate in KEX mode, the group implementation must support the provider functions as described in provider-keyexch(7).

In KEM mode, the client executes keygen and sends its public key, the server executes encapsulate using the client's public key and sends back the resulting ciphertext, finally the client executes decapsulate to retrieve the same shared secret generated by the server's encapsulate. To operate in KEM mode, the group implementation must support the provider functions as described in provider-kem(7).

Both in KEX and KEM mode, the resulting shared secret is then used according to the protocol specification.

"tls-min-tls" (OSSL_CAPABILITY_TLS_GROUP_MIN_TLS) <integer>

"tls-max-tls" (OSSL_CAPABILITY_TLS_GROUP_MAX_TLS) <integer>

"tls-min-dtls" (OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS) <integer>

"tls-max-dtls" (OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS) <integer>

These parameters can be used to describe the minimum and maximum TLS and DTLS versions supported by the group. The values equate to the on-the-wire encoding of the various TLS versions. For example TLSv1.3 is 0x0304 (772 decimal), and TLSv1.2 is 0x0303 (771 decimal). A 0 indicates that there is no defined minimum or maximum. A -1 indicates that the group should not be used in that protocol.

"TLS-SIGALG" Capability

The "TLS-SIGALG" capability can be queried by libssl to discover the list of TLS signature algorithms that a provider can support. Each signature supported can be used for client- or server-authentication in addition to the built-in signature algorithms. TLS1.3 clients can advertise the list of TLS signature algorithms they support in the signature_algorithms extension, and TLS servers can select an algorithm from the offered list that they also support. In this way a provider can add to the list of signature algorithms that libssl already supports with additional ones.

Each TLS signature algorithm that a provider supports should be described via the callback passed in through the provider_get_capabilities function. Each algorithm can have the following details supplied:

"iana-name" (OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME) <UTF8 string>

The name of the signature algorithm as given in the IANA TLS Signature Scheme registry as "Description": <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme>. This value must be supplied.

"iana-code-point" (OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT) <unsigned integer>

The TLS algorithm ID value as given in the IANA TLS SignatureScheme registry. This value must be supplied. It is possible to register the same code point from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation for a particular code point will be used.

"sigalg-name" (OSSL_CAPABILITY_TLS_SIGALG_NAME) <UTF8 string>

A name for the full (possibly composite hash-and-signature) signature algorithm. The provider may, but is not obligated to, provide a signature implementation with this name; if it doesn't, this is assumed to be a composite of a pure signature algorithm and a hash algorithm, which must be given with the parameters "sig-name" and "hash-name". This value must be supplied.

"sigalg-oid" (OSSL_CAPABILITY_TLS_SIGALG_OID) <UTF8 string>

The OID of the "sigalg-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "sigalg-name" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"sig-name" (OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME) <UTF8 string>

The name of the pure signature algorithm that is part of a composite "sigalg-name". If "sigalg-name" is implemented by the provider, this parameter is redundant and must not be given. This value is optional.

"sig-oid" (OSSL_CAPABILITY_TLS_SIGALG_SIG_OID) <UTF8 string>

The OID of the "sig-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "sig-name" parameter for its (short) name. Otherwise, it is assumed to already exist in the object database. This can be done by the provider using the core_obj_create() upcall. This value is optional.

"hash-name" (OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME) <UTF8 string>

The name of the hash algorithm that is part of a composite "sigalg-name". If "sigalg-name" is implemented by the provider, this parameter is redundant and must not be given. This value is optional.

"hash-oid" (OSSL_CAPABILITY_TLS_SIGALG_HASH_OID) <UTF8 string>

The OID of the "hash-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "hash-name" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"key-type" (OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE) <UTF8 string>

The key type of the public key of applicable certificates. If this parameter isn't present, it's assumed to be the same as "sig-name" if that's present, otherwise "sigalg-name". This value is optional.

"key-type-oid" (OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID) <UTF8 string>

The OID of the "key-type" in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "key-type" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"sec-bits" (OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS) <unsigned integer>

The number of bits of security offered by keys of this algorithm. The number of bits should be comparable with the ones given in table 2 and 3 of the NIST SP800-57 document. This number is used to determine the security strength of the algorithm if no digest algorithm has been registered that otherwise defines the security strength. If the signature algorithm implements its own digest internally, this value needs to be set to properly reflect the overall security strength. This value must be supplied.

"tls-min-tls" (OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS) <integer>

"tls-max-tls" (OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS) <integer>

These parameters can be used to describe the minimum and maximum TLS versions supported by the signature algorithm. The values equate to the on-the-wire encoding of the various TLS versions. For example TLSv1.3 is 0x0304 (772 decimal), and TLSv1.2 is 0x0303 (771 decimal). A 0 indicates that there is no defined minimum or maximum. A -1 indicates that the signature algorithm should not be used in that protocol. Presently values representing anything other than TLS1.3 mean that the complete algorithm is ignored.

## NOTES
The core_obj_create() and core_obj_add_sigid() functions were not thread safe in OpenSSL 3.0.

## EXAMPLES
This is an example of a simple provider made available as a dynamically loadable module. It implements the fictitious algorithm "FOO" for the fictitious operation "BAR".

```
 #include <malloc.h>
 #include <openssl/core.h>
 #include <openssl/core_dispatch.h>
 /* Errors used in this provider */
 #define E_MALLOC       1
 static const OSSL_ITEM reasons[] = {
     { E_MALLOC, "memory allocation failure" }.
     OSSL_DISPATCH_END
 };
 /*
  * To ensure we get the function signature right, forward declare
  * them using function types provided by openssl/core_dispatch.h
  */
 OSSL_FUNC_bar_newctx_fn foo_newctx;
 OSSL_FUNC_bar_freectx_fn foo_freectx;
 OSSL_FUNC_bar_init_fn foo_init;
 OSSL_FUNC_bar_update_fn foo_update;
 OSSL_FUNC_bar_final_fn foo_final;
 OSSL_FUNC_provider_query_operation_fn p_query;
 OSSL_FUNC_provider_get_reason_strings_fn p_reasons;
 OSSL_FUNC_provider_teardown_fn p_teardown;
 OSSL_provider_init_fn OSSL_provider_init;
 OSSL_FUNC_core_put_error *c_put_error = NULL;
 /* Provider context */
 struct prov_ctx_st {
     OSSL_CORE_HANDLE *handle;
 }
 /* operation context for the algorithm FOO */
 struct foo_ctx_st {
     struct prov_ctx_st *provctx;
     int b;
 };
 static void *foo_newctx(void *provctx)
 {
     struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx));
     if (fooctx != NULL)
         fooctx->provctx = provctx;
     else
         c_put_error(provctx->handle, E_MALLOC, __FILE__, __LINE__);
     return fooctx;
 }
 static void foo_freectx(void *fooctx)
 {
     free(fooctx);
 }
 static int foo_init(void *vfooctx)
 {
     struct foo_ctx_st *fooctx = vfooctx;
     fooctx->b = 0x33;
 }
 static int foo_update(void *vfooctx, unsigned char *in, size_t inl)
 {
     struct foo_ctx_st *fooctx = vfooctx;
     /* did you expect something serious? */
     if (inl == 0)
         return 1;
     for (; inl-- > 0; in++)
         *in ^= fooctx->b;
     return 1;
 }
 static int foo_final(void *vfooctx)
 {
     struct foo_ctx_st *fooctx = vfooctx;
     fooctx->b = 0x66;
 }
 static const OSSL_DISPATCH foo_fns[] = {
     { OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx },
     { OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx },
     { OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init },
     { OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update },
     { OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final },
     OSSL_DISPATCH_END
 };
 static const OSSL_ALGORITHM bars[] = {
     { "FOO", "provider=chumbawamba", foo_fns },
     { NULL, NULL, NULL }
 };
 static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id,
                                      int *no_store)
 {
     switch (operation_id) {
     case OSSL_OP_BAR:
         return bars;
     }
     return NULL;
 }
 static const OSSL_ITEM *p_reasons(void *provctx)
 {
     return reasons;
 }
 static void p_teardown(void *provctx)
 {
     free(provctx);
 }
 static const OSSL_DISPATCH prov_fns[] = {
     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown },
     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query },
     { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons },
     OSSL_DISPATCH_END
 };
 int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
                        const OSSL_DISPATCH *in,
                        const OSSL_DISPATCH **out,
                        void **provctx)
 {
     struct prov_ctx_st *pctx = NULL;
     for (; in->function_id != 0; in++)
         switch (in->function_id) {
         case OSSL_FUNC_CORE_PUT_ERROR:
             c_put_error = OSSL_FUNC_core_put_error(in);
             break;
         }
     *out = prov_fns;
     if ((pctx = malloc(sizeof(*pctx))) == NULL) {
         /*
          * ALEA IACTA EST, if the core retrieves the reason table
          * regardless, that string will be displayed, otherwise not.
          */
         c_put_error(handle, E_MALLOC, __FILE__, __LINE__);
         return 0;
     }
     pctx->handle = handle;
     return 1;
 }
```

This relies on a few things existing in openssl/core_dispatch.h:

```
 #define OSSL_OP_BAR            4711
 #define OSSL_FUNC_BAR_NEWCTX      1
 typedef void *(OSSL_FUNC_bar_newctx_fn)(void *provctx);
 static ossl_inline OSSL_FUNC_bar_newctx(const OSSL_DISPATCH *opf)
 { return (OSSL_FUNC_bar_newctx_fn *)opf->function; }
 #define OSSL_FUNC_BAR_FREECTX     2
 typedef void (OSSL_FUNC_bar_freectx_fn)(void *ctx);
 static ossl_inline OSSL_FUNC_bar_freectx(const OSSL_DISPATCH *opf)
 { return (OSSL_FUNC_bar_freectx_fn *)opf->function; }
 #define OSSL_FUNC_BAR_INIT        3
 typedef void *(OSSL_FUNC_bar_init_fn)(void *ctx);
 static ossl_inline OSSL_FUNC_bar_init(const OSSL_DISPATCH *opf)
 { return (OSSL_FUNC_bar_init_fn *)opf->function; }
 #define OSSL_FUNC_BAR_UPDATE      4
 typedef void *(OSSL_FUNC_bar_update_fn)(void *ctx,
                                       unsigned char *in, size_t inl);
 static ossl_inline OSSL_FUNC_bar_update(const OSSL_DISPATCH *opf)
 { return (OSSL_FUNC_bar_update_fn *)opf->function; }
 #define OSSL_FUNC_BAR_FINAL       5
 typedef void *(OSSL_FUNC_bar_final_fn)(void *ctx);
 static ossl_inline OSSL_FUNC_bar_final(const OSSL_DISPATCH *opf)
 { return (OSSL_FUNC_bar_final_fn *)opf->function; }
```

## SEE ALSO
provider(7)

## HISTORY
The concept of providers and everything surrounding them was introduced in OpenSSL 3.0.

## COPYRIGHT
Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.