📒 Blog home page: Actor's blog
🎉 Welcome to pay attention 🔎 give the thumbs-up 👍 Collection ⭐ Leave a message 📝
❤️ Look forward to communicating together!
🙏 The author's level is very limited. If you find an error, please let me know. Thank you!
🌺 If you have any questions, you can communicate by private letter!!!
🥦 OpenSSL provider
OpenSSL comes with a set of providers.
The algorithms available in each of these providers may vary depending on the build time configuration options. The OpenSSL list command can be used to list the currently available algorithms.
The algorithm name displayed in OpenSSL list can be used as the algorithm identifier of the corresponding acquisition function. Also refer to the provider specific man pages linked below for more details on using the algorithms available in each provider.
In addition to OpenSSL providers, third parties can also implement providers.
🥬 Default provider
The default provider is built as part of the libcrypto library and contains all the most commonly used algorithm implementations. If necessary (if other providers are loaded and provide implementations of the same algorithm), you can use the attribute query string "provider=default" as the search criteria for these implementations. The default provider includes all the features in the following basic providers.
If you do not load any providers at all, the default provider is automatically loaded. If any provider is explicitly loaded, the default provider also needs to be explicitly loaded, if required.
🥒 Basic provider
The basic provider is built-in as part of the libcrypto library and contains algorithm implementations for encoding and decoding OpenSSL keys. If necessary (if other providers are loaded and provide implementations of the same algorithm), you can use the attribute query string "provider=base" as the search criteria for these implementations. Some encoding and decoding algorithm implementations are not FIPS algorithm implementations themselves, but support algorithms from FIPS providers and are allowed to be used in "FIPS mode". The attribute query string "fips=yes" can be used to select such algorithms.
🌶️ FIPS provider
FIPS provider is a dynamically loadable module, so it must be loaded explicitly in code or through OpenSSL configuration. It contains an algorithm implementation that has been verified according to FIPS 140-2 standard. If necessary (if other providers are loaded and implementations of the same algorithm are provided), you can use the attribute query string "provider=fips" as the search criteria for these implementations. You can also use the attribute "fips=yes" to select all approved algorithm implementations in the FIPS provider. FIPS providers may also contain unapproved algorithm implementations that can be selected using the attribute "fips=no".
🌽 Legacy provider
The legacy provider is a dynamically loadable module, so it must be loaded explicitly in code or through OpenSSL configuration. It contains algorithmic implementations that are considered unsafe or no longer commonly used, such as MD2 or RC4. If necessary (if other providers are loaded and provide implementations of the same algorithm), you can use the attribute "provider=legacy" as the search criteria for these implementations.
🥕 Empty provider
The empty provider is built in as part of the libcrypto library. It doesn't contain any algorithms at all. When extracting an algorithm, if no other provider is explicitly loaded, the default provider is automatically loaded. To prevent this from happening, you can explicitly load the null provider.
🧄 Using algorithms in applications
By using the "EVP"API, the encryption algorithm is available to applications. Each different operation (such as encryption, digest, message authentication code, etc.) has a set of EVP function calls that can be called to use them.
Most of them follow a common pattern. First create a "context" object. For example, for summary operations, you will use EVP_MD_CTX, for encryption / decryption operations, you will use EVP_CIPHER_CTX. Then initialize the operation so that it can be used through the "init" function - you can optionally pass in a set of parameters (using the OSSL_PARAM type) to configure the behavior of the operation. The next data is fed into the operation through a series of "update" calls. This is done using a "final" call, which usually provides some kind of output. Finally, clean up and release the context.
A complete example of performing this procedure using SHA256 to digest data is shown below. This process is similar to other operations, such as encryption / decryption, signature, message authentication code, etc.
#include <stdio.h> #include <openssl/evp.h> #include <openssl/bio.h> int main(void) { EVP_MD_CTX *ctx = NULL; EVP_MD *sha256 = NULL; const unsigned char msg[] = { 0x00, 0x01, 0x02, 0x03 }; unsigned int len = 0; unsigned char *outdigest = NULL; /* Create a context for the digest operation */ ctx = EVP_MD_CTX_new(); if (ctx == NULL) goto err; /* * Fetch the SHA256 algorithm implementation for doing the digest. We're * using the "default" library context here (first NULL parameter), and * we're not supplying any particular search criteria for our SHA256 * implementation (second NULL parameter). Any SHA256 implementation will * do. */ sha256 = EVP_MD_fetch(NULL, "SHA256", NULL); if (sha256 == NULL) goto err; /* Initialise the digest operation */ if (!EVP_DigestInit_ex(ctx, sha256, NULL)) goto err; /* * Pass the message to be digested. This can be passed in over multiple * EVP_DigestUpdate calls if necessary */ if (!EVP_DigestUpdate(ctx, msg, sizeof(msg))) goto err; /* Allocate the output buffer */ outdigest = OPENSSL_malloc(EVP_MD_get_size(sha256)); if (outdigest == NULL) goto err; /* Now calculate the digest itself */ if (!EVP_DigestFinal_ex(ctx, outdigest, &len)) goto err; /* Print out the digest result */ BIO_dump_fp(stdout, outdigest, len); err: /* Clean up all the resources we allocated */ OPENSSL_free(outdigest); EVP_MD_free(sha256); EVP_MD_CTX_free(ctx); }