| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | Fetching composite algorithms and using them - adding the bits still missing | 
					
						
							|  |  |  | ============================================================================ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Quick background | 
					
						
							|  |  |  | ---------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | We currently support - at least in the public libcrypto API - explicitly | 
					
						
							|  |  |  | fetching composite algorithms (such as AES-128-CBC or HMAC-SHA256), and | 
					
						
							|  |  |  | using them in most cases.  In some cases (symmetric ciphers), our providers | 
					
						
							|  |  |  | also provide them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | However, there is one class of algorithms where the support for *using* | 
					
						
							|  |  |  | explicitly fetched algorithms is lacking: asymmetric algorithms. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For a longer background and explanation, see | 
					
						
							|  |  |  | [Background / tl;dr](#background-tldr) at the end of this design. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Public API - Add variants of `EVP_PKEY_CTX` initializers | 
					
						
							|  |  |  | -------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As far as this design is concerned, these API sets are affected: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | - SIGNATURE | 
					
						
							| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | - ASYM_CIPHER | 
					
						
							|  |  |  | - KEYEXCH | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | The proposal is to add these initializer functions: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` C | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | int EVP_PKEY_sign_init_ex2(EVP_PKEY_CTX *pctx, | 
					
						
							|  |  |  |                            EVP_SIGNATURE *algo, const OSSL_PARAM params[]); | 
					
						
							|  |  |  | int EVP_PKEY_verify_init_ex2(EVP_PKEY_CTX *pctx, | 
					
						
							|  |  |  |                              EVP_SIGNATURE *algo, const OSSL_PARAM params[]); | 
					
						
							|  |  |  | int EVP_PKEY_verify_recover_init_ex2(EVP_PKEY_CTX *pctx, | 
					
						
							|  |  |  |                                      EVP_SIGNATURE *algo, const OSSL_PARAM params[]); | 
					
						
							| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int EVP_PKEY_encrypt_init_ex2(EVP_PKEY_CTX *ctx, EVP_ASYM_CIPHER *asymciph, | 
					
						
							|  |  |  |                               const OSSL_PARAM params[]); | 
					
						
							|  |  |  | int EVP_PKEY_decrypt_init_ex2(EVP_PKEY_CTX *ctx, EVP_ASYM_CIPHER *asymciph, | 
					
						
							|  |  |  |                               const OSSL_PARAM params[]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int EVP_PKEY_derive_init_ex2(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange, | 
					
						
							|  |  |  |                              const OSSL_PARAM params[]); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | Detailed proposal for these APIs will be or are prepared in other design | 
					
						
							|  |  |  | documents: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | - [Functions for explicitly fetched signature algorithms] | 
					
						
							|  |  |  | - [Functions for explicitly fetched asym-cipher algorithms] (not yet designed) | 
					
						
							|  |  |  | - [Functions for explicitly fetched keyexch algorithms] (not yet designed) | 
					
						
							| 
									
										
										
										
											2023-09-18 15:30:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ----- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ----- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Background / tl;dr | 
					
						
							|  |  |  | ------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### What is a composite algorithm?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A composite algorithm is an algorithm that's composed of more than one other | 
					
						
							|  |  |  | algorithm.  In OpenSSL parlance with a focus on signatures, they have been | 
					
						
							|  |  |  | known as "sigalgs", but this is really broader than just signature algorithms. | 
					
						
							|  |  |  | Examples are: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -   AES-128-CBC | 
					
						
							|  |  |  | -   hmacWithSHA256 | 
					
						
							|  |  |  | -   sha256WithRSAEncryption | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### The connection with AlgorithmIdentifiers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AlgorithmIdentifier is an ASN.1 structure that defines an algorithm as an | 
					
						
							|  |  |  | OID, along with parameters that should be passed to that algorithm. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It is expected that an application should be able to take that OID and | 
					
						
							|  |  |  | fetch it directly, after conversion to string form (either a name if the | 
					
						
							|  |  |  | application or libcrypto happens to know it, or the OID itself in canonical | 
					
						
							|  |  |  | numerical form).  To enable this, explicit fetching is necessary. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### What we have today
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | As a matter of fact, we already have built-in support for fetching | 
					
						
							|  |  |  | composite algorithms, although our providers do not fully participate in | 
					
						
							|  |  |  | that support, and *most of the time*, we also have public APIs to use the | 
					
						
							|  |  |  | fetched result, commonly known as support for explicit fetching. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The idea is that providers can declare the different compositions of a base | 
					
						
							|  |  |  | algorithm in the `OSSL_ALGORITHM` array, each pointing to different | 
					
						
							|  |  |  | `OSSL_DISPATCH` tables, which would in turn refer to pretty much the same | 
					
						
							|  |  |  | functions, apart from the constructor function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For example, we already do this with symmetric ciphers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Another example, which we could implement in our providers today, would be | 
					
						
							|  |  |  | compositions of HMAC: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` C | 
					
						
							|  |  |  | static const OSSL_ALGORITHM deflt_macs[] = { | 
					
						
							|  |  |  |     /* ... */ | 
					
						
							|  |  |  |     { "HMAC-SHA1:hmacWithSHA1:1.2.840.113549.2.7", | 
					
						
							|  |  |  |       "provider=default", ossl_hmac_sha1_functions }, | 
					
						
							|  |  |  |     { "HMAC-SHA224:hmacWithSHA224:1.2.840.113549.2.8", | 
					
						
							|  |  |  |       "provider=default", ossl_hmac_sha224_functions }, | 
					
						
							|  |  |  |     { "HMAC-SHA256:hmacWithSHA256:1.2.840.113549.2.9", | 
					
						
							|  |  |  |       "provider=default", ossl_hmac_sha256_functions }, | 
					
						
							|  |  |  |     { "HMAC-SHA384:hmacWithSHA384:1.2.840.113549.2.10", | 
					
						
							|  |  |  |       "provider=default", ossl_hmac_sha384_functions }, | 
					
						
							|  |  |  |     { "HMAC-SHA512:hmacWithSHA512:1.2.840.113549.2.11", | 
					
						
							|  |  |  |       "provider=default", ossl_hmac_sha512_functions }, | 
					
						
							|  |  |  |     /* ... */ | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### What we don't have today
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There are some classes of algorithms for which we have no support for using | 
					
						
							|  |  |  | the result of explicit fetching.  So for example, while it's possible for a | 
					
						
							|  |  |  | provider to declare composite algorithms through the `OSSL_ALGORITHM` array, | 
					
						
							|  |  |  | there's currently no way for an application to use them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This all revolves around asymmetric algorithms, where we currently only | 
					
						
							|  |  |  | support implicit fetching. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is hurtful in multiple ways: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -   It fails the provider authors in terms being able to consistently | 
					
						
							|  |  |  |     declare all algorithms through `OSSL_ALGORITHM` arrays. | 
					
						
							|  |  |  | -   It fails the applications in terms of being able to fetch algorithms and | 
					
						
							|  |  |  |     use the result. | 
					
						
							|  |  |  | -   It fails discoverability, for example through the `openssl list` | 
					
						
							|  |  |  |     command. | 
					
						
							| 
									
										
										
										
											2023-11-09 17:42:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | <!-- links --> | 
					
						
							|  |  |  | [Functions for explicitly fetched signature algorithms]: | 
					
						
							|  |  |  |     functions-for-explicitly-fetched-signature-algorithms.md |