|
| 1 | +Simultaneous derivation of several EVP_SKEY objects |
| 2 | +=================================================== |
| 3 | + |
| 4 | +There are situations where we need to derive several symmetric keys |
| 5 | +simultaneously. The most relevant one for OpenSSL is TLS protocol, when we |
| 6 | +need to derive 2-4 keys, depending on the protocol version. With raw bytes |
| 7 | +buffer, the approach was to derive a combined buffer of the necessary length |
| 8 | +and chop it. It doesn't work this way for EVP_SKEY objects. |
| 9 | + |
| 10 | +This document proposes API and a general approach to deal with such situations. |
| 11 | + |
| 12 | +Model use case |
| 13 | +-------------- |
| 14 | + |
| 15 | +TLS 1.2 and below requires simultaneous derivation of 2 IVs and 2 or 4 keys (2 for |
| 16 | +ciphers and 2 for MACs). IVs are public and can be accessed directly, keys are |
| 17 | +returned as EVP_SKEY objects. |
| 18 | + |
| 19 | +The API is designed from the perspective of being a transparent wrapper for |
| 20 | +PKCS#11 mechanisms for simultaneous key generation and avoid the extra calls to |
| 21 | +token API from the provider. |
| 22 | + |
| 23 | +Libcrypto API |
| 24 | +------------- |
| 25 | + |
| 26 | +As all the objects are derived in one transaction, we can store a single opaque |
| 27 | +pointer keeping all the keys inside in the EVP_KDF_CTX object, and provide the |
| 28 | +API for access to a particular object. |
| 29 | + |
| 30 | +To derive the opaque keys and and bytes buffers, we use the function |
| 31 | + |
| 32 | +```C |
| 33 | +int EVP_KDF_derive_SKEYs(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *mgmt, |
| 34 | + const char *propquery, const OSSL_PARAM params[]); |
| 35 | +``` |
| 36 | +
|
| 37 | +This function doesn't directly return objects when this functions succeeds, |
| 38 | +they are stored in the EVP_KDF_CTX object. |
| 39 | +
|
| 40 | +The options that define key types and sizes, number of keys or IVs and their |
| 41 | +length can generally be specified by passing appropriate parameters in the |
| 42 | +`params` argument. If no params are provided, defaults may be used by specific |
| 43 | +KDF operations. |
| 44 | +
|
| 45 | +The params can also be set by a preceding call to `EVP_KDF_CTX_set_params`. |
| 46 | +
|
| 47 | +To access the individual EVP_SKEY values, we introduce the functions |
| 48 | +
|
| 49 | +```C |
| 50 | +EVP_SKEY *EVP_KDF_CTX_get0_SKEY(EVP_KDF_CTX *ctx, const char *purpose); |
| 51 | +EVP_SKEY *EVP_KDF_CTX_get1_SKEY(EVP_KDF_CTX *ctx, const char *purpose); |
| 52 | +``` |
| 53 | + |
| 54 | +where the `purpose` argument is a name of the particular EVP_SKEY purpose (e.g. |
| 55 | +"client_MAC_key", "server_CIPHER_key") as specified by the documentation of the |
| 56 | +specific KDF operation that was executed. |
| 57 | + |
| 58 | +To access an IV, the proposed API is |
| 59 | + |
| 60 | +```C |
| 61 | +int EVP_KDF_CTX_get0_IV(EVP_KDF_CTX *ctx, const char *purpose, |
| 62 | + unsigned char **pIV, size_t *pIVlen); |
| 63 | +``` |
| 64 | +
|
| 65 | +where the `purpose` argument is a documented name of the particular IV purpose |
| 66 | +(e.g. "client_IV") and `pIVlen` argument is a way to get the length of |
| 67 | +generated IV. |
| 68 | +
|
| 69 | +Provider API |
| 70 | +------------ |
| 71 | +
|
| 72 | +We extend the EVP_KDF structure with the following member functions: |
| 73 | +
|
| 74 | +```C |
| 75 | +OSSL_CORE_MAKE_FUNC(int, kdf_derive_multi, (void *kctx, |
| 76 | + const OSSL_PARAM params[])) |
| 77 | +
|
| 78 | +OSSL_CORE_MAKE_FUNC(int, kdf_get_skey, |
| 79 | + (void *kctx, void *skeydata, const char *purpose, bool incr_refcount)) |
| 80 | +
|
| 81 | +OSSL_CORE_MAKE_FUNC(unsigned char *, kdf_get_iv, |
| 82 | + (void *kctx, const char *purpose)) |
| 83 | +
|
| 84 | +``` |
| 85 | + |
| 86 | +Providers may either imply some KDF-specific defaults when it's obvious from |
| 87 | +the KDF specification or throw an error otherwise. |
0 commit comments