Simultaneous derivation of several EVP_SKEY objects#29160
Simultaneous derivation of several EVP_SKEY objects#29160beldmit wants to merge 1 commit intoopenssl:masterfrom
Conversation
|
I think that the returned keys should include both their data and length rather than assuming the caller necessarily knows this. This means a public structure or accessor functions. An SKEY that contains other SKEYs might be a neat solution as hinted at in the document. |
If they are handles (PKCS#11), it doesn't apply. |
I had this idea on my mind, but what's next? Smth like |
|
I adjusted the proposed function signature according to Simo's proposal about returning IVs as raw bytes array and providing the algorithm information, please re-review |
|
Not sure if I understand. Is there a reason the caller can't make multiple |
|
@levitte thanks! It gives a different approach - but it means that the context should be able to store the information got from a call, right? |
It is super slow and for TLS you have a single HKDF whose output is chopped in different secrets. So you would repeat the same computation multiple time and then just pick a different part of it and throw away the rest, which in the PKCS#11 case is multiple session keys being created and then thrown away. A function in PKCS#11 that does this is for example: Which returns 4 key handles and 2 IVs (see Another similar derivation is the SSH KDF which also produces 4 keys and 4 IVs from the same base material. Being able to do this in a single operation from a token is a major performance and usability benefit. |
|
@simo5 if you can store the result in the KDF context, it wouldn't require operations on token - you pass the result between libcrypto and the provider and return the next element. |
Ok discussed this a bit with @beldmit we can definitely store multiple key handles internally in the provider's KDF context, and use the normal Then use an accessor function named something like: This means either using a get_param dispatcher function to return a pointer, or better add a get_key dispatcher function to return a keydata pointer |
|
We already have a Adding a sounds easy enough |
|
Another thought could be to make it an iterator instead, where a callback is called for every iteration (new EVP_SKEY created), and still leave it to the caller to figure out where to store them all. "Make me {n} keys and IVs, pass each to this callback", kinda? I'm thinking that's a viable way to avoid having a STACK_OF() return value (which appears to be desirable) |
|
A callback could work, but I do not see it as necessary, a getter works just fine, after all you need to know what to do with the keys anyway otherwise you do not need all the churn of going through creating EVP_SKEY structures for them. |
|
Updated version pushed |
|
Just "thinking loudly" here. I have been thinking for a while about what information is really needed to perform these kind of KDFs (I am using mostly knowledge of TLS and SSH key derivation to inform my opinion). Fundamentally we need this kind of info: Encryption key type needed (AES, ChaCha-Poly, ..) this info applies to both keys, and should not be disjoint. So basically 3 somewhat interrelated sets: So at most 4 parameters (at least for TLS and SSH key derivation). So we could simplify the design of the API to be like this: int EVP_KDF_derive_SKEYs(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *mgmt,
const char *propquery, const OSSL_PARAM params[]);Where we use params to change defaults as needed. If all parameters need to be tweaked from defaults from whatever reason the "worst case" code would look something like: I think I would prefer this method of setting up the key derivation because in the case the defaults are sufficient then the above potentially reduces to just: We could reduce the parameters to just three if we define key type that include the size (ie "AES-128" instead of just "AES") which I would favor. Of course these could also be explicit arguments to the function (assumed types fully specified including size): int EVP_KDF_derive_SKEYs(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *mgmt,
const char *key_type, const char *mac_type, int ivlen,
const char *propquery, const OSSL_PARAM params[]);The reason why I am hesitant about the above is that if a future KDF comes around that requires something different we'll have a poorly matching function and will need either a EVP_KDF_derive_SKEYs_ex, or start using parameters anyway to provide the additional info ... |
405672d to
7ab409d
Compare
|
I pushed the simplified API design inspired by @simo5 comment, please review |
A proposed design for using EVP_SKEY objects in the TLS stack
ec8b7c7 to
6beb07a
Compare
|
Ping @openssl/committers for the 2nd review and let's put this PR under the Christmas tree |
|
This pull request is ready to merge |
A proposed design for using EVP_SKEY objects in the TLS stack Reviewed-by: Richard Levitte <[email protected]> Reviewed-by: Simo Sorce <[email protected]> (Merged from #29160)
|
Merged. Thanks for review, it made the design as simple as possible |
A proposed design for using EVP_SKEY objects in the TLS stack
Checklist