Home | History | Annotate | Line # | Download | only in designs
      1 Handling AlgorithmIdentifier and its parameters with provider operations
      2 ========================================================================
      3 
      4 Quick background
      5 ----------------
      6 
      7 We currently only support passing the AlgorithmIdentifier (`X509_ALGOR`)
      8 parameter field to symmetric cipher provider implementations.  We currently
      9 only support getting full AlgorithmIdentifier (`X509_ALGOR`) from signature
     10 provider implementations.
     11 
     12 We do support passing them to legacy implementations of other types of
     13 operation algorithms as well, but it's done in a way that can't be supported
     14 with providers, because it involves sharing specific structures between
     15 libcrypto and the backend implementation.
     16 
     17 For a longer background and explanation, see
     18 [Background / tl;dr](#background-tldr) at the end of this design.
     19 
     20 Establish OSSL_PARAM keys that any algorithms may become aware of
     21 -----------------------------------------------------------------
     22 
     23 We 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 
     32 This design proposes:
     33 
     34 1. Adding a parameter key "algorithm-id-params", to replace "algor_id_param",
     35    and deprecate the latter.
     36 2. 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 
     40 This way, these parameters can be used in the exact same manner with other
     41 operations, with the value of the AlgorithmIdentifier as well as its
     42 parameters as octet strings, to be used and interpreted by applications and
     43 provider implementations alike in whatever way they see fit.
     44 
     45 Applications can choose to add these in an `OSSL_PARAM` array, to be passed
     46 with the multitude of initialization functions that take such an array, or
     47 using 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 
     51 These 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 
     62 That should cover all algorithms that are, or should be possible to fetch by
     63 AlgorithmIdentifier.algorithm, and for which there's potentially a relevant
     64 AlgorithmIdentifier.parameters field.
     65 
     66 We may arguably want to consider `doc/man7/provider-keymgmt.pod` too, but
     67 an AlgorithmIdentifier that's attached directly to a key is usually part of
     68 a PrivKeyInfo or SubjectPublicKeyInfo structure, and those are handled by
     69 encoders and decoders as those see fit, and there's no tangible reason why
     70 that would have to change.
     71 
     72 Public convenience API
     73 ----------------------
     74 
     75 For convenience, the following set of functions would be added to pass the
     76 AlgorithmIdentifier parameter data to diverse operations, or to retrieve
     77 such 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  */
     84 EVP_CIPHER_CTX_set_algor_params(EVP_CIPHER_CTX *ctx, const X509_ALGOR *alg);
     85 EVP_CIPHER_CTX_get_algor_params(EVP_CIPHER_CTX *ctx, X509_ALGOR *alg);
     86 EVP_CIPHER_CTX_get_algor(EVP_CIPHER_CTX *ctx, X509_ALGOR **alg);
     87 
     88 EVP_MD_CTX_set_algor_params(EVP_MD_CTX *ctx, const X509_ALGOR *alg);
     89 EVP_MD_CTX_get_algor_params(EVP_MD_CTX *ctx, X509_ALGOR *alg);
     90 EVP_MD_CTX_get_algor(EVP_MD_CTX *ctx, X509_ALGOR **alg);
     91 
     92 EVP_MAC_CTX_set_algor_params(EVP_MAC_CTX *ctx, const X509_ALGOR *alg);
     93 EVP_MAC_CTX_get_algor_params(EVP_MAC_CTX *ctx, X509_ALGOR *alg);
     94 EVP_MAC_CTX_get_algor(EVP_MAC_CTX *ctx, X509_ALGOR **alg);
     95 
     96 EVP_KDF_CTX_set_algor_params(EVP_KDF_CTX *ctx, const X509_ALGOR *alg);
     97 EVP_KDF_CTX_get_algor_params(EVP_KDF_CTX *ctx, X509_ALGOR *alg);
     98 EVP_KDF_CTX_get_algor(EVP_KDF_CTX *ctx, X509_ALGOR **alg);
     99 
    100 EVP_PKEY_CTX_set_algor_params(EVP_PKEY_CTX *ctx, const X509_ALGOR *alg);
    101 EVP_PKEY_CTX_get_algor_params(EVP_PKEY_CTX *ctx, X509_ALGOR *alg);
    102 EVP_PKEY_CTX_get_algor(EVP_PKEY_CTX *ctx, X509_ALGOR **alg);
    103 ```
    104 
    105 Note that all might not need to be added immediately, depending on if they
    106 are considered useful or not.  For future proofing, however, they should
    107 probably all be added.
    108 
    109 Requirements on the providers
    110 -----------------------------
    111 
    112 Providers that implement ciphers or any operation that uses asymmetric keys
    113 will have to implement support for passing AlgorithmIdentifier parameter
    114 data, and will have to process that data in whatever manner that's necessary
    115 to meet the standards for that operation.
    116 
    117 Fallback strategies
    118 -------------------
    119 
    120 There are no possible fallback strategies, which is fine, considering that
    121 current provider functionality doesn't support passing AlgorithmIdentifier
    122 parameter data at all (except for `EVP_CIPHER`), and therefore do not work
    123 at all when such parameter data needs to be passed.
    124 
    125 -----
    126 
    127 -----
    128 
    129 Background / tl;dr
    130 ------------------
    131 
    132 ### AlgorithmIdenfier parameter and how it's used
    133 
    134 OpenSSL has historically done a few tricks to not have to pass
    135 AlgorithmIdenfier parameter data to the backend implementations of
    136 cryptographic 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 
    145 With providers, some of that support was retained, but not others.  Most
    146 crucially, the `EVP_PKEY` ctrls for PKCS#7 and CMS were not retained,
    147 because the way they were implemented violated the principle that provider
    148 implementations *MUST NOT* share complex OpenSSL specific structures with
    149 libcrypto.
    150 
    151 ### Usage examples
    152 
    153 Quite a lot of the available examples today revolve around CMS, with a
    154 number of RFCs that specify what parameters should be passed with certain
    155 operations / algorithms.  This list is not exhaustive, the reader is
    156 encouraged 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 
    173 Some of it can be claimed to already have support in OpenSSL.  However, this
    174 is with old libcrypto code that has special knowledge of the algorithms that
    175 are involved.
    176