Custom Provider - EVP_CIPHER_fetch fails

Matt Caswell matt at openssl.org
Tue Jan 3 14:33:35 UTC 2023



On 28/12/2022 10:49, Hareesh Das Ulleri wrote:
> However when I want to change the algorithm name to " AES-256-CBC-CTS " (This is the actual implementation), not able to fetch from the custom provider (taking default one). Even I tried to give along with an algo property string in test application and in provider, fetch is failing.
> 
> cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", "Custom-Prov=yes");
> 
> How can I fetch an cipher algorithm implementation even a default implementation exists ("default" provider may need to co-exist for other operations). Please suggest.

Where two or more implementations exist for the same algorithm in 
different providers then the one which is selected is not-defined. You 
must use property strings to resolve this.

In order for that to work you must define the algorithms in your custom 
provider with its associated properties.

For example here are some ciphers as defined in the legacy provider:

static const OSSL_ALGORITHM legacy_ciphers[] = {
#ifndef OPENSSL_NO_CAST
     ALG(PROV_NAMES_CAST5_ECB, ossl_cast5128ecb_functions),
     ALG(PROV_NAMES_CAST5_CBC, ossl_cast5128cbc_functions),
     ALG(PROV_NAMES_CAST5_OFB, ossl_cast5128ofb64_functions),
     ALG(PROV_NAMES_CAST5_CFB, ossl_cast5128cfb64_functions),
#endif /* OPENSSL_NO_CAST */
#ifndef OPENSSL_NO_BF
     ALG(PROV_NAMES_BF_ECB, ossl_blowfish128ecb_functions),
     ALG(PROV_NAMES_BF_CBC, ossl_blowfish128cbc_functions),
     ALG(PROV_NAMES_BF_OFB, ossl_blowfish128ofb64_functions),
     ALG(PROV_NAMES_BF_CFB, ossl_blowfish128cfb64_functions),
#endif /* OPENSSL_NO_BF */
    ...
}

Where ALG is a macro defined like this:

#define ALG(NAMES, FUNC) { NAMES, "provider=legacy", FUNC }

This means that all ciphers supplied by the legacy provider have the 
"provider=legacy" property string associated with them.

I would consider it good practice for all algorithms supplied by a 
custom provider to define the "provider=WHATEVER" property string. All 
OpenSSL providers do this.

With that your EVP_CIPHER_fetch call should look like this:

cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", "provider=Custom-Prov");


Matt


> 
> Thank you,
> Hareesh
> 
> -----Original Message-----
> From: Matt Caswell <matt at openssl.org>
> Sent: Tuesday, December 13, 2022 7:49 PM
> To: Hareesh Das Ulleri <hareesh.ulleri at ovt.com>; openssl-users at openssl.org
> Subject: Re: Custom Provider - EVP_CIPHER_fetch fails
> 
> [CAUTION]: EXTERNAL EMAIL
> 
> 
> On 13/12/2022 09:13, Hareesh Das Ulleri wrote:
>> Hello OpenSSL users,
>>
>>     I am in preparation of a provider (for a custom crypto) by
>> referring OpenSSL 3 design doc
> 
> Don't refer to the design doc. It has not been maintained with all the latest tweaks and updates to what was originally envisaged.
> 
>> (I use Linux 5.10 + OpenSSL 3.0.7). I believe, the custom provider has
>> all required call backs implemented for the cipher functionalities in
>> its dispatch table.
>>
> 
> You should refer to the man page for what is required to implement a custom cipher. See:
> 
> https://urldefense.com/v3/__https://www.openssl.org/docs/man3.0/man7/provider-cipher.html__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjpEScuW0w$
> 
> Note in particular this comment in the man page:
> 
> "A cipher algorithm implementation may not implement all of these functions. In order to be a consistent set of functions there must at least be a complete set of "encrypt" functions, or a complete set of "decrypt" functions, or a single "cipher" function. In all cases both the OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx functions must be present. All other functions are optional."
> 
> So, in other words, you must as a minimum implement OSSL_FUNC_cipher_encrypt_init (or OSSL_FUNC_cipher_decrypt_init), OSSL_FUNC_cipher_update, OSSL_FUNC_cipher_final, OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx.
> 
> You should probably also read the following pages for general information on writing a provider:
> 
> https://urldefense.com/v3/__https://www.openssl.org/docs/man3.0/man7/provider.html__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjr2VgFhFA$
> https://urldefense.com/v3/__https://www.openssl.org/docs/man3.0/man7/provider-base.html__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjqmYHiAcQ$
> 
> You might also want to refer to Richard Levitte's implementation of the toy Vigenère cipher as a provider here:
> 
> https://urldefense.com/v3/__https://github.com/provider-corner/vigenere__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjoTNn-vCA$
> 
>>     I have another test application (for encryption and decryption of a
>> text message). At the starting of the app, it calls OSSL_PROVIDER_load
>> and EVP_CIPHER_fetch functions to the custom provider. But
>> unfortunately custom provider fetch function fails…
> 
> 
> I suggest calling the OSSL_PROVIDER_available() function to determine whether your custom provider has been successfully loaded:
> 
> https://urldefense.com/v3/__https://www.openssl.org/docs/man3.0/man3/OSSL_PROVIDER_available.html__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjqQex0Yvg$
> 
>>
>> What could be the missing or how to make sure that the custom provider
>> is loaded correctly before calling the fetch function?
>>
>> cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", NULL);  -> This
>> will work, default provider
>>
>> cipher = EVP_CIPHER_fetch(NULL, "CUSTOM_ALGO", NULL);  -> returns
>> NULL, custom provider
>>
>> _Confg file:_
>>
>> openssl_conf = openssl_init
>>
>> [openssl_init]
>>
>> providers = provider_section
>>
>> [provider_section]
>>
>> customProv = customProv_section
>>
>> default = default_sect
>>
>> [customProv_section]
>>
>> provider_id = customProv
>>
>> module_path = /userfs/lib/customProv.so
>>
>> algorithms = CUSTOM_ALGO
>>
>> activate = 1
>>
>> [default_sect]
>>
>> algorithms = AES-256-CBC-CTS
>>
>> activate = 1
> 
> This config file does not look correct. I guess you based it on some of the examples in the design doc which are out of date.
> 
> The man page for config file formats is here:
> 
> https://urldefense.com/v3/__https://www.openssl.org/docs/man3.0/man5/config.html__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjooudQYNw$
> 
> See the "Provider Configuration" section on that page in particular.
> 
> Also worth looking at are some of the test config files used in the OpenSSL code base for loading providers, e.g.
> 
> https://urldefense.com/v3/__https://github.com/openssl/openssl/blob/openssl-3.0/test/default-and-legacy.cnf__;!!AYUVhIwY!6U5m1Q3RFPFx8ih3X6UUd7d2rGn85M_2O1G29O1jiYnm8L3aX9Q8HpvSCrZsJGZIRglgUjqOGgUZbA$
> 
> Matt
> 
> 
>>
>> Thank you,
>>
>> Hareesh
>>


More information about the openssl-users mailing list