1Handling AlgorithmIdentifier and its parameters with provider operations
2========================================================================
3
4Quick background
5----------------
6
7We currently only support passing the AlgorithmIdentifier (`X509_ALGOR`)
8parameter field to symmetric cipher provider implementations.  We currently
9only support getting full AlgorithmIdentifier (`X509_ALGOR`) from signature
10provider implementations.
11
12We do support passing them to legacy implementations of other types of
13operation algorithms as well, but it's done in a way that can't be supported
14with providers, because it involves sharing specific structures between
15libcrypto and the backend implementation.
16
17For a longer background and explanation, see
18[Background / tl;dr](#background-tldr) at the end of this design.
19
20Establish OSSL_PARAM keys that any algorithms may become aware of
21-----------------------------------------------------------------
22
23We already have known parameter keys:
24
25- "algor_id_param", also known as the macro `OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS`.
26
27  This is currently only specified for `EVP_CIPHER`, in support of
28  `EVP_CIPHER_param_to_asn1()` and `EVP_CIPHER_asn1_to_param()`
29
30- "algorithm-id", also known as the macro `OSSL_SIGNATURE_PARAM_ALGORITHM_ID`.
31
32This design proposes:
33
341. Adding a parameter key "algorithm-id-params", to replace "algor_id_param",
35   and deprecate the latter.
362. Making both "algorithm-id" and "algorithm-id-params" generically available,
37   rather than only tied to `EVP_SIGNATURE` ("algorithm-id") or `EVP_CIPHER`
38   ("algor_id_param").
39
40This way, these parameters can be used in the exact same manner with other
41operations, with the value of the AlgorithmIdentifier as well as its
42parameters as octet strings, to be used and interpreted by applications and
43provider implementations alike in whatever way they see fit.
44
45Applications can choose to add these in an `OSSL_PARAM` array, to be passed
46with the multitude of initialization functions that take such an array, or
47using specific operation `OSSL_PARAM` setters and getters (such as
48`EVP_PKEY_CTX_set_params`), or using other available convenience functions
49(see below).
50
51These parameter will have to be documented in the following files:
52
53- `doc/man7/provider-asym_cipher.pod`
54- `doc/man7/provider-cipher.pod`
55- `doc/man7/provider-digest.pod`
56- `doc/man7/provider-kdf.pod`
57- `doc/man7/provider-kem.pod`
58- `doc/man7/provider-keyexch.pod`
59- `doc/man7/provider-mac.pod`
60- `doc/man7/provider-signature.pod`
61
62That should cover all algorithms that are, or should be possible to fetch by
63AlgorithmIdentifier.algorithm, and for which there's potentially a relevant
64AlgorithmIdentifier.parameters field.
65
66We may arguably want to consider `doc/man7/provider-keymgmt.pod` too, but
67an AlgorithmIdentifier that's attached directly to a key is usually part of
68a PrivKeyInfo or SubjectPublicKeyInfo structure, and those are handled by
69encoders and decoders as those see fit, and there's no tangible reason why
70that would have to change.
71
72Public convenience API
73----------------------
74
75For convenience, the following set of functions would be added to pass the
76AlgorithmIdentifier parameter data to diverse operations, or to retrieve
77such parameter data from them.
78
79``` C
80/*
81 * These two would essentially be aliases for EVP_CIPHER_param_to_asn1()
82 * and EVP_CIPHER_asn1_to_param().
83 */
84EVP_CIPHER_CTX_set_algor_params(EVP_CIPHER_CTX *ctx, const X509_ALGOR *alg);
85EVP_CIPHER_CTX_get_algor_params(EVP_CIPHER_CTX *ctx, X509_ALGOR *alg);
86EVP_CIPHER_CTX_get_algor(EVP_CIPHER_CTX *ctx, X509_ALGOR **alg);
87
88EVP_MD_CTX_set_algor_params(EVP_MD_CTX *ctx, const X509_ALGOR *alg);
89EVP_MD_CTX_get_algor_params(EVP_MD_CTX *ctx, X509_ALGOR *alg);
90EVP_MD_CTX_get_algor(EVP_MD_CTX *ctx, X509_ALGOR **alg);
91
92EVP_MAC_CTX_set_algor_params(EVP_MAC_CTX *ctx, const X509_ALGOR *alg);
93EVP_MAC_CTX_get_algor_params(EVP_MAC_CTX *ctx, X509_ALGOR *alg);
94EVP_MAC_CTX_get_algor(EVP_MAC_CTX *ctx, X509_ALGOR **alg);
95
96EVP_KDF_CTX_set_algor_params(EVP_KDF_CTX *ctx, const X509_ALGOR *alg);
97EVP_KDF_CTX_get_algor_params(EVP_KDF_CTX *ctx, X509_ALGOR *alg);
98EVP_KDF_CTX_get_algor(EVP_KDF_CTX *ctx, X509_ALGOR **alg);
99
100EVP_PKEY_CTX_set_algor_params(EVP_PKEY_CTX *ctx, const X509_ALGOR *alg);
101EVP_PKEY_CTX_get_algor_params(EVP_PKEY_CTX *ctx, X509_ALGOR *alg);
102EVP_PKEY_CTX_get_algor(EVP_PKEY_CTX *ctx, X509_ALGOR **alg);
103```
104
105Note that all might not need to be added immediately, depending on if they
106are considered useful or not.  For future proofing, however, they should
107probably all be added.
108
109Requirements on the providers
110-----------------------------
111
112Providers that implement ciphers or any operation that uses asymmetric keys
113will have to implement support for passing AlgorithmIdentifier parameter
114data, and will have to process that data in whatever manner that's necessary
115to meet the standards for that operation.
116
117Fallback strategies
118-------------------
119
120There are no possible fallback strategies, which is fine, considering that
121current provider functionality doesn't support passing AlgorithmIdentifier
122parameter data at all (except for `EVP_CIPHER`), and therefore do not work
123at all when such parameter data needs to be passed.
124
125-----
126
127-----
128
129Background / tl;dr
130------------------
131
132### AlgorithmIdenfier parameter and how it's used
133
134OpenSSL has historically done a few tricks to not have to pass
135AlgorithmIdenfier parameter data to the backend implementations of
136cryptographic operations:
137
138- In some cases, they were passed as part of the lower level key structure
139  (for example, the `RSA` structure can also carry RSA-PSS parameters).
140- In the `EVP_CIPHER` case, there is functionality to pass the parameter
141  data specifically.
142- For asymmetric key operations, PKCS#7 and CMS support was added as
143  `EVP_PKEY` ctrls.
144
145With providers, some of that support was retained, but not others.  Most
146crucially, the `EVP_PKEY` ctrls for PKCS#7 and CMS were not retained,
147because the way they were implemented violated the principle that provider
148implementations *MUST NOT* share complex OpenSSL specific structures with
149libcrypto.
150
151### Usage examples
152
153Quite a lot of the available examples today revolve around CMS, with a
154number of RFCs that specify what parameters should be passed with certain
155operations / algorithms.  This list is not exhaustive, the reader is
156encouraged to research further usages.
157
158- [DSA](https://www.rfc-editor.org/rfc/rfc3370#section-3.1) signatures
159  typically have the domain parameters *p*, *q* and *g*.
160- [RC2 key wrap](https://www.rfc-editor.org/rfc/rfc3370#section-4.3.2)
161- [PBKDF2](https://www.rfc-editor.org/rfc/rfc3370#section-4.4.1)
162- [3DES-CBC](https://www.rfc-editor.org/rfc/rfc3370#section-5.1)
163- [RC2-CBC](https://www.rfc-editor.org/rfc/rfc3370#section-5.2)
164
165- [GOST 28147-89](https://www.rfc-editor.org/rfc/rfc4490.html#section-5.1)
166
167- [RSA-OAEP](https://www.rfc-editor.org/rfc/rfc8017#appendix-A.2.1)
168- [RSA-PSS](https://www.rfc-editor.org/rfc/rfc8017#appendix-A.2.3)
169
170- [XOR-MD5](https://www.rfc-editor.org/rfc/rfc6210.html) is experimental,
171  but it does demonstrate the possibility of a parametrized hash algorithm.
172
173Some of it can be claimed to already have support in OpenSSL.  However, this
174is with old libcrypto code that has special knowledge of the algorithms that
175are involved.
176