Home | History | Annotate | Line # | Download | only in designs
      1 Fetching composite algorithms and using them - adding the bits still missing
      2 ============================================================================
      3 
      4 Quick background
      5 ----------------
      6 
      7 We currently support - at least in the public libcrypto API - explicitly
      8 fetching composite algorithms (such as AES-128-CBC or HMAC-SHA256), and
      9 using them in most cases.  In some cases (symmetric ciphers), our providers
     10 also provide them.
     11 
     12 However, there is one class of algorithms where the support for *using*
     13 explicitly fetched algorithms is lacking: asymmetric algorithms.
     14 
     15 For a longer background and explanation, see
     16 [Background / tl;dr](#background-tldr) at the end of this design.
     17 
     18 Public API - Add variants of `EVP_PKEY_CTX` initializers
     19 --------------------------------------------------------
     20 
     21 As far as this design is concerned, these API sets are affected:
     22 
     23 - SIGNATURE
     24 - ASYM_CIPHER
     25 - KEYEXCH
     26 
     27 The proposal is to add these initializer functions:
     28 
     29 ``` C
     30 int EVP_PKEY_sign_init_ex2(EVP_PKEY_CTX *pctx,
     31                            EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
     32 int EVP_PKEY_verify_init_ex2(EVP_PKEY_CTX *pctx,
     33                              EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
     34 int EVP_PKEY_verify_recover_init_ex2(EVP_PKEY_CTX *pctx,
     35                                      EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
     36 
     37 int EVP_PKEY_encrypt_init_ex2(EVP_PKEY_CTX *ctx, EVP_ASYM_CIPHER *asymciph,
     38                               const OSSL_PARAM params[]);
     39 int EVP_PKEY_decrypt_init_ex2(EVP_PKEY_CTX *ctx, EVP_ASYM_CIPHER *asymciph,
     40                               const OSSL_PARAM params[]);
     41 
     42 int EVP_PKEY_derive_init_ex2(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange,
     43                              const OSSL_PARAM params[]);
     44 ```
     45 
     46 Detailed proposal for these APIs will be or are prepared in other design
     47 documents:
     48 
     49 - [Functions for explicitly fetched signature algorithms]
     50 - [Functions for explicitly fetched asym-cipher algorithms] (not yet designed)
     51 - [Functions for explicitly fetched keyexch algorithms] (not yet designed)
     52 
     53 -----
     54 
     55 -----
     56 
     57 Background / tl;dr
     58 ------------------
     59 
     60 ### What is a composite algorithm?
     61 
     62 A composite algorithm is an algorithm that's composed of more than one other
     63 algorithm.  In OpenSSL parlance with a focus on signatures, they have been
     64 known as "sigalgs", but this is really broader than just signature algorithms.
     65 Examples are:
     66 
     67 -   AES-128-CBC
     68 -   hmacWithSHA256
     69 -   sha256WithRSAEncryption
     70 
     71 ### The connection with AlgorithmIdentifiers
     72 
     73 AlgorithmIdentifier is an ASN.1 structure that defines an algorithm as an
     74 OID, along with parameters that should be passed to that algorithm.
     75 
     76 It is expected that an application should be able to take that OID and
     77 fetch it directly, after conversion to string form (either a name if the
     78 application or libcrypto happens to know it, or the OID itself in canonical
     79 numerical form).  To enable this, explicit fetching is necessary.
     80 
     81 ### What we have today
     82 
     83 As a matter of fact, we already have built-in support for fetching
     84 composite algorithms, although our providers do not fully participate in
     85 that support, and *most of the time*, we also have public APIs to use the
     86 fetched result, commonly known as support for explicit fetching.
     87 
     88 The idea is that providers can declare the different compositions of a base
     89 algorithm in the `OSSL_ALGORITHM` array, each pointing to different
     90 `OSSL_DISPATCH` tables, which would in turn refer to pretty much the same
     91 functions, apart from the constructor function.
     92 
     93 For example, we already do this with symmetric ciphers.
     94 
     95 Another example, which we could implement in our providers today, would be
     96 compositions of HMAC:
     97 
     98 ``` C
     99 static const OSSL_ALGORITHM deflt_macs[] = {
    100     /* ... */
    101     { "HMAC-SHA1:hmacWithSHA1:1.2.840.113549.2.7",
    102       "provider=default", ossl_hmac_sha1_functions },
    103     { "HMAC-SHA224:hmacWithSHA224:1.2.840.113549.2.8",
    104       "provider=default", ossl_hmac_sha224_functions },
    105     { "HMAC-SHA256:hmacWithSHA256:1.2.840.113549.2.9",
    106       "provider=default", ossl_hmac_sha256_functions },
    107     { "HMAC-SHA384:hmacWithSHA384:1.2.840.113549.2.10",
    108       "provider=default", ossl_hmac_sha384_functions },
    109     { "HMAC-SHA512:hmacWithSHA512:1.2.840.113549.2.11",
    110       "provider=default", ossl_hmac_sha512_functions },
    111     /* ... */
    112 ```
    113 
    114 ### What we don't have today
    115 
    116 There are some classes of algorithms for which we have no support for using
    117 the result of explicit fetching.  So for example, while it's possible for a
    118 provider to declare composite algorithms through the `OSSL_ALGORITHM` array,
    119 there's currently no way for an application to use them.
    120 
    121 This all revolves around asymmetric algorithms, where we currently only
    122 support implicit fetching.
    123 
    124 This is hurtful in multiple ways:
    125 
    126 -   It fails the provider authors in terms being able to consistently
    127     declare all algorithms through `OSSL_ALGORITHM` arrays.
    128 -   It fails the applications in terms of being able to fetch algorithms and
    129     use the result.
    130 -   It fails discoverability, for example through the `openssl list`
    131     command.
    132 
    133 <!-- links -->
    134 [Functions for explicitly fetched signature algorithms]:
    135     functions-for-explicitly-fetched-signature-algorithms.md
    136