Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
Am Montag, 14. Januar 2019, 18:53:16 CET schrieb Eric Biggers: Hi Eric, > > I would not suggest this, because that rounds contrary to the concept of > > the kernel crypto API IMHO. The caller has to provide the wrapping > > cipher. It is perfectly viable to allow a caller to invoke a specific > > keyed message digest. > Sure, but it would not conform to the HKDF specification. Are you sure it > is okay to specify an arbitrary keyed hash? Technically, I see no issue why this should not be possible. You see that with the SP800-108 KDF implementations where using CMAC is perfectly legal (and which I also test). Though, using another keyed hash implementation like CMAC is not covered by the HKDF spec. If a caller would use hkdf(cmac(aes)), it would produce cryptographically strong values. Though this implementation does not conform to any standard. I do not think we should prevent a caller to select such combination in the kernel crypto API. IMHO there would even be valid reasons why one would use cmac(aes) for a kdf. For example, when you would want to use a hardware AES which somehow also employs a hardware key that is inaccessible to software in order to tie the KDF result to the local hardware. This could even be a valid use case for Ext4 FBE encryption where you derive a key. The KDF could be used to link the derived key to the local hardware to prevent the encrypted data could be copied to another system and decrypted successfully there. Ciao Stephan
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
On Mon, Jan 14, 2019 at 10:30:39AM +0100, Stephan Müller wrote: > Am Samstag, 12. Januar 2019, 06:12:54 CET schrieb Eric Biggers: > > Hi Eric, > > [...] > > > > The extract and expand phases use different instances of the underlying > > > keyed message digest cipher to ensure that while the extraction phase > > > generates a new key for the expansion phase, the cipher for the > > > expansion phase can still be used. This approach is intended to aid > > > multi-threaded uses cases. > > > > I think you partially misunderstood what I was asking for. One HMAC tfm is > > sufficient as long as HKDF-Expand is separated from HKDF-Extract, which > > you've done. So just use one HMAC tfm, and in crypto_hkdf_seed() key it > > with the 'salt', and then afterwards with the 'prk'. > > Ok, thanks for the clarification. I will remove the 2nd HMAC TFM then. > > > > Also everywhere in this patchset, please avoid using the word "cipher" to > > refer to algorithms that are not encryption/decryption. I know a lot of > > the crypto API docs do this, but I think it is a mistake and confusing. > > Hash algorithms and KDFs are not "ciphers". > > As you wish, I will refer to specific name of the cryptographic operation. > > [...] > > > > + * NOTE: In-place cipher operations are not supported. > > > + */ > > > > What does an "in-place cipher operation" mean in this context? That the > > 'info' buffer must not overlap the 'dst' buffer? > > Correct, no overlapping. > > > Maybe > > crypto_rng_generate() should check that for all crypto_rngs? Or is it > > different for different crypto_rngs? > > This is the case in general for all KDFs (and even RNGs). It is no technical > or cryptographic error to have overlapping buffers. The only issue is that > the > result will not match the expected value. > > The issue is that the input buffer to the generate function is an input to > every round of the KDF. If the input and output buffer overlap, starting with > the 2nd iteration of the KDF, the input is the output of the 1st round. > Again, > I do not think it is a cryptographic error though. > > (To support my conclusion: A colleague of mine has proposed an update to the > HKDF specification where the input data changes for each KDF round. This > proposal was considered appropriate by one of the authors of HKDF.) > > If the requested output is smaller or equal to the output block size of the > KDF, overlapping buffers are even harmless since the implementation will > calculate the correct output. > > Due to that, I removed the statement. But I am not sure we should add a > technical block to deny overlapping input/output buffers. > > [...] > > > > > > + desc->flags = crypto_shash_get_flags(expand_kmd) & > > > + CRYPTO_TFM_REQ_MAY_SLEEP; > > > > This line setting desc->flags doesn't make sense. How is the user meant to > > control whether crypto_rng_generate() can sleep or not? Or can it always > > sleep? Either way this part is wrong since the user can't get access to the > > HMAC tfm to set this flag being checked for. > > Could you please help me why a user should set this flag? Isn't the > implementation specifying that flag to allow identifying whether the > implementation could or could not sleep? Thus, we simply copy the sleeping > flag from the lower level keyed message digest implementation. > > At least that is also the implementation found in crypto/hmac.c. > > [...] Whether the crypto_shash* stuff can sleep is controlled on a per-request basis, not a per-implementation basis. So I don't understand what you are talking about here. > > > > + if (dlen < h) { > > > + u8 tmpbuffer[CRYPTO_HKDF_MAX_DIGESTSIZE]; > > > + > > > + err = crypto_shash_finup(desc, &ctr, 1, tmpbuffer); > > > + if (err) > > > + goto out; > > > + memcpy(dst, tmpbuffer, dlen); > > > + memzero_explicit(tmpbuffer, h); > > > + goto out; > > > + } else { > > > > No need for the 'else'. > > Could you please help me why that else branch is not needed? If the buffer to > be generated is equal or larger than the output block length of the keyed > message digest, I would like to directly operate on the output buffer to > avoid > a memcpy. I'm simply saying you don't need the 'else' keyword as the previous block ends with a goto. > > > > > + err = crypto_shash_finup(desc, &ctr, 1, dst); > > > + if (err) > > > + goto out; > > > + > > > + prev = dst; > > > + dst += h; > > > + dlen -= h; > > > + ctr++; > > > + } > > > + } > > [...] > > > > > + struct crypto_shash *extract_kmd = ctx->extract_kmd; > > > + struct crypto_shash *expand_kmd = ctx->expand_kmd; > > > + struct rtattr *rta = (struct rtattr *)seed; > > > + SHASH_DESC_ON_STACK(desc, extract_
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
Am Samstag, 12. Januar 2019, 06:12:54 CET schrieb Eric Biggers: Hi Eric, [...] > > The extract and expand phases use different instances of the underlying > > keyed message digest cipher to ensure that while the extraction phase > > generates a new key for the expansion phase, the cipher for the > > expansion phase can still be used. This approach is intended to aid > > multi-threaded uses cases. > > I think you partially misunderstood what I was asking for. One HMAC tfm is > sufficient as long as HKDF-Expand is separated from HKDF-Extract, which > you've done. So just use one HMAC tfm, and in crypto_hkdf_seed() key it > with the 'salt', and then afterwards with the 'prk'. Ok, thanks for the clarification. I will remove the 2nd HMAC TFM then. > > Also everywhere in this patchset, please avoid using the word "cipher" to > refer to algorithms that are not encryption/decryption. I know a lot of > the crypto API docs do this, but I think it is a mistake and confusing. > Hash algorithms and KDFs are not "ciphers". As you wish, I will refer to specific name of the cryptographic operation. [...] > > + * NOTE: In-place cipher operations are not supported. > > + */ > > What does an "in-place cipher operation" mean in this context? That the > 'info' buffer must not overlap the 'dst' buffer? Correct, no overlapping. > Maybe > crypto_rng_generate() should check that for all crypto_rngs? Or is it > different for different crypto_rngs? This is the case in general for all KDFs (and even RNGs). It is no technical or cryptographic error to have overlapping buffers. The only issue is that the result will not match the expected value. The issue is that the input buffer to the generate function is an input to every round of the KDF. If the input and output buffer overlap, starting with the 2nd iteration of the KDF, the input is the output of the 1st round. Again, I do not think it is a cryptographic error though. (To support my conclusion: A colleague of mine has proposed an update to the HKDF specification where the input data changes for each KDF round. This proposal was considered appropriate by one of the authors of HKDF.) If the requested output is smaller or equal to the output block size of the KDF, overlapping buffers are even harmless since the implementation will calculate the correct output. Due to that, I removed the statement. But I am not sure we should add a technical block to deny overlapping input/output buffers. [...] > > > > + desc->flags = crypto_shash_get_flags(expand_kmd) & > > + CRYPTO_TFM_REQ_MAY_SLEEP; > > This line setting desc->flags doesn't make sense. How is the user meant to > control whether crypto_rng_generate() can sleep or not? Or can it always > sleep? Either way this part is wrong since the user can't get access to the > HMAC tfm to set this flag being checked for. Could you please help me why a user should set this flag? Isn't the implementation specifying that flag to allow identifying whether the implementation could or could not sleep? Thus, we simply copy the sleeping flag from the lower level keyed message digest implementation. At least that is also the implementation found in crypto/hmac.c. [...] > > + if (dlen < h) { > > + u8 tmpbuffer[CRYPTO_HKDF_MAX_DIGESTSIZE]; > > + > > + err = crypto_shash_finup(desc, &ctr, 1, tmpbuffer); > > + if (err) > > + goto out; > > + memcpy(dst, tmpbuffer, dlen); > > + memzero_explicit(tmpbuffer, h); > > + goto out; > > + } else { > > No need for the 'else'. Could you please help me why that else branch is not needed? If the buffer to be generated is equal or larger than the output block length of the keyed message digest, I would like to directly operate on the output buffer to avoid a memcpy. > > > + err = crypto_shash_finup(desc, &ctr, 1, dst); > > + if (err) > > + goto out; > > + > > + prev = dst; > > + dst += h; > > + dlen -= h; > > + ctr++; > > + } > > + } [...] > > > + struct crypto_shash *extract_kmd = ctx->extract_kmd; > > + struct crypto_shash *expand_kmd = ctx->expand_kmd; > > + struct rtattr *rta = (struct rtattr *)seed; > > + SHASH_DESC_ON_STACK(desc, extract_kmd); > > + u32 saltlen; > > + unsigned int h = crypto_shash_digestsize(extract_kmd); > > + int err; > > + const uint8_t null_salt[CRYPTO_HKDF_MAX_DIGESTSIZE] = { 0 }; > > static const > Why would I want to turn that buffer into a static variable? All we need it for is in case there is no salt provided. [...] > > + > > + if (!RTA_OK(rta, slen)) > > + return -EINVAL; > > + if (rta->rta_type != 1) > > + return -EINVAL; > > + if (RTA_PAYLOAD(rta) < sizeof(saltlen)) > > +
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
On Sun, 2019-01-13 at 08:56 +0100, Stephan Müller wrote: > The question may arise why to plug the KDFs into RNGs. The answer is > quite simple: KDFs are a form of random number generator. In that > they take some input for initialization (aka seed, salt, key, > personalization string). Then they produce pseudo-random bit > sequences of arbitrary length. Possibly the generation operation can > be modified by providing some additional input to be used by the > generation process (aka label, context, info string, additional > information string). Thus, the RNG interface is a natural fit for the > KDFs. Philosophically, that's quite wrong. KDFs are a class of pseudorandom functions (PRFs). PRFs are designed so that the output is indistinguishable from a random number generator to observers who don't know the input but is deterministically useful for participants who do. That means the're definitely not RNGs they're functions whose output is designed to look like the output of an RNG. I suppose the mathematical thing that distinguishes PRFs and RNGs is entropy: PRFs have zero entropy because given the same inputs you expect the same output. Now whether it makes sense to use the RNG API or not I'll leave that up to the crypto people. I would have expected any cryptographic RNG API to be mostly about entropy management (the Linux core internal one certainly is), but it appears that the one in crypto isn't. James
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
Am Samstag, 12. Januar 2019, 10:55:35 CET schrieb Herbert Xu: Hi Herbert, > On Fri, Jan 11, 2019 at 09:12:54PM -0800, Eric Biggers wrote: > > Hi Stephan, > > > > On Fri, Jan 11, 2019 at 08:10:39PM +0100, Stephan Müller wrote: > > > The RFC5869 compliant Key Derivation Function is implemented as a > > > random number generator considering that it behaves like a deterministic > > > RNG. > > > > Thanks for the proof of concept! I guess it ended up okay. But can you > > explain more the benefits of using the crypto_rng interface, as opposed > > to just some crypto_hkdf_*() helper functions that are exported for > > modules to use? > I agree. I see no benefit in adding this through the RNG API as > opposed to just providing it as a helper. If some form of hardware > acceleration were to eventuate in the future we could always revisit > this. The advantages for using the kernel crypto API to add KDFs as opposed to adding helper wrappers are the following in my view: - employment of the kernel crypto API testmgr - invocation of the testmgr is transparent and thus already provided without any additional code to link to it - FIPS 140-2 compliance: To mark a KDF as FIPS 140-2 approved cipher, it must be subject to a known-answer self test (implemented by the testmgr) as well as to an enforcement of the integrity check verification. In FIPS 140-2 mode, the kernel crypto API panic()s when a kernel crypto API module is loaded and its signature does not check out. As this is only relevant for crypto modules (and not arbitrary other kernel modules), this is implemented with the invocations the crypto_register_alg as well as crypto_register_template functions. Thus, when using a wrapper code to implement the KDF, they can per definition not be FIPS 140-2 approved. - The invoker of a KDF has one consistent API. This implies that the KDF selection now becomes more of a "configuration" choice. For example, when you look at the KDF use case for the keys subsystem (security/keys/dh.c), selecting the type of KDF would only necessitate a change of a string referencing the KDF. A lot of people somehow favor the extract-and-expand KDFs over the traditional KDFs. Now, that the RFC5869 HKDF is also approved as per SP800-56A rev3, I could see that folks may want to switch to HKDF for the key management. When we have a common API, this choice could even be left to the caller. The question may arise why to plug the KDFs into RNGs. The answer is quite simple: KDFs are a form of random number generator. In that they take some input for initialization (aka seed, salt, key, personalization string). Then they produce pseudo-random bit sequences of arbitrary length. Possibly the generation operation can be modified by providing some additional input to be used by the generation process (aka label, context, info string, additional information string). Thus, the RNG interface is a natural fit for the KDFs. Ciao Stephan
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
On Fri, Jan 11, 2019 at 09:12:54PM -0800, Eric Biggers wrote: > Hi Stephan, > > On Fri, Jan 11, 2019 at 08:10:39PM +0100, Stephan Müller wrote: > > The RFC5869 compliant Key Derivation Function is implemented as a > > random number generator considering that it behaves like a deterministic > > RNG. > > > > Thanks for the proof of concept! I guess it ended up okay. But can you > explain > more the benefits of using the crypto_rng interface, as opposed to just some > crypto_hkdf_*() helper functions that are exported for modules to use? I agree. I see no benefit in adding this through the RNG API as opposed to just providing it as a helper. If some form of hardware acceleration were to eventuate in the future we could always revisit this. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
Hi Stephan, On Fri, Jan 11, 2019 at 08:10:39PM +0100, Stephan Müller wrote: > The RFC5869 compliant Key Derivation Function is implemented as a > random number generator considering that it behaves like a deterministic > RNG. > Thanks for the proof of concept! I guess it ended up okay. But can you explain more the benefits of using the crypto_rng interface, as opposed to just some crypto_hkdf_*() helper functions that are exported for modules to use? > The extract and expand phases use different instances of the underlying > keyed message digest cipher to ensure that while the extraction phase > generates a new key for the expansion phase, the cipher for the > expansion phase can still be used. This approach is intended to aid > multi-threaded uses cases. I think you partially misunderstood what I was asking for. One HMAC tfm is sufficient as long as HKDF-Expand is separated from HKDF-Extract, which you've done. So just use one HMAC tfm, and in crypto_hkdf_seed() key it with the 'salt', and then afterwards with the 'prk'. Also everywhere in this patchset, please avoid using the word "cipher" to refer to algorithms that are not encryption/decryption. I know a lot of the crypto API docs do this, but I think it is a mistake and confusing. Hash algorithms and KDFs are not "ciphers". > > Signed-off-by: Stephan Mueller > --- > crypto/Kconfig | 6 + > crypto/Makefile | 1 + > crypto/hkdf.c | 290 > 3 files changed, 297 insertions(+) > create mode 100644 crypto/hkdf.c > > diff --git a/crypto/Kconfig b/crypto/Kconfig > index cc80d89e0cf5..0eee5e129fa3 100644 > --- a/crypto/Kconfig > +++ b/crypto/Kconfig > @@ -568,6 +568,12 @@ config CRYPTO_KDF > Support for KDF compliant to SP800-108. All three types of > KDF specified in SP800-108 are implemented. > > +config CRYPTO_HKDF > + tristate "HMAC-based Extract-and expand Key Derivation Function" > + select CRYPTO_RNG > + help > + Support for KDF compliant to RFC5869. > + Make the description "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)"? There is a missing dash, and probably the acronym "HKDF" should be in there. > config CRYPTO_XCBC > tristate "XCBC support" > select CRYPTO_HASH > diff --git a/crypto/Makefile b/crypto/Makefile > index 69a0bb64b0ac..6bbb0a4dea13 100644 > --- a/crypto/Makefile > +++ b/crypto/Makefile > @@ -59,6 +59,7 @@ crypto_user-$(CONFIG_CRYPTO_STATS) += crypto_user_stat.o > obj-$(CONFIG_CRYPTO_CMAC) += cmac.o > obj-$(CONFIG_CRYPTO_HMAC) += hmac.o > obj-$(CONFIG_CRYPTO_KDF) += kdf.o > +obj-$(CONFIG_CRYPTO_HKDF) += hkdf.o > obj-$(CONFIG_CRYPTO_VMAC) += vmac.o > obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o > obj-$(CONFIG_CRYPTO_NULL2) += crypto_null.o > diff --git a/crypto/hkdf.c b/crypto/hkdf.c > new file mode 100644 > index ..35a975ed64a8 > --- /dev/null > +++ b/crypto/hkdf.c > @@ -0,0 +1,290 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +/* > + * RFC 5869 Key-derivation function > + * People don't know what RFC xyz is. Please be more explicit than just the RFC number, e.g. "HKDF: HMAC-based Extract-and-Expand Key Derivation Function (RFC 5869)" > + * Copyright (C) 2019, Stephan Mueller > + */ > + > +/* > + * The HKDF extract phase is applied with crypto_rng_reset(). > + * The HKDF expand phase is applied with crypto_rng_generate(). > + * > + * NOTE: In-place cipher operations are not supported. > + */ What does an "in-place cipher operation" mean in this context? That the 'info' buffer must not overlap the 'dst' buffer? Maybe crypto_rng_generate() should check that for all crypto_rngs? Or is it different for different crypto_rngs? > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct crypto_hkdf_ctx { > + struct crypto_shash *extract_kmd; > + struct crypto_shash *expand_kmd; > +}; > + > +#define CRYPTO_HKDF_MAX_DIGESTSIZE 64 > + > +/* > + * HKDF expand phase > + */ > +static int crypto_hkdf_random(struct crypto_rng *rng, > + const u8 *info, unsigned int infolen, > + u8 *dst, unsigned int dlen) Why call it crypto_hkdf_random() instead of crypto_hkdf_generate()? The latter would match rng_alg::generate. > +{ > + struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); const > + struct crypto_shash *expand_kmd = ctx->expand_kmd; > + SHASH_DESC_ON_STACK(desc, expand_kmd); > + unsigned int h = crypto_shash_digestsize(expand_kmd); const > + int err = 0; > + u8 *dst_orig = dst; > + const u8 *prev = NULL; > + uint8_t ctr = 0x01; u8 instead of uint8_t > + > + if (dlen > h * 255) > + return -EINVAL; > + > + desc->tfm = expand_kmd; > + desc->flags = crypto_shash_get_flags(expand_kmd) & > + CRYPTO_TFM_REQ_MAY_SLEEP; This line setting desc->flags doesn't make sense. How is the user meant to control whether
[PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function
The RFC5869 compliant Key Derivation Function is implemented as a random number generator considering that it behaves like a deterministic RNG. The extract and expand phases use different instances of the underlying keyed message digest cipher to ensure that while the extraction phase generates a new key for the expansion phase, the cipher for the expansion phase can still be used. This approach is intended to aid multi-threaded uses cases. Signed-off-by: Stephan Mueller --- crypto/Kconfig | 6 + crypto/Makefile | 1 + crypto/hkdf.c | 290 3 files changed, 297 insertions(+) create mode 100644 crypto/hkdf.c diff --git a/crypto/Kconfig b/crypto/Kconfig index cc80d89e0cf5..0eee5e129fa3 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -568,6 +568,12 @@ config CRYPTO_KDF Support for KDF compliant to SP800-108. All three types of KDF specified in SP800-108 are implemented. +config CRYPTO_HKDF + tristate "HMAC-based Extract-and expand Key Derivation Function" + select CRYPTO_RNG + help + Support for KDF compliant to RFC5869. + config CRYPTO_XCBC tristate "XCBC support" select CRYPTO_HASH diff --git a/crypto/Makefile b/crypto/Makefile index 69a0bb64b0ac..6bbb0a4dea13 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -59,6 +59,7 @@ crypto_user-$(CONFIG_CRYPTO_STATS) += crypto_user_stat.o obj-$(CONFIG_CRYPTO_CMAC) += cmac.o obj-$(CONFIG_CRYPTO_HMAC) += hmac.o obj-$(CONFIG_CRYPTO_KDF) += kdf.o +obj-$(CONFIG_CRYPTO_HKDF) += hkdf.o obj-$(CONFIG_CRYPTO_VMAC) += vmac.o obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o obj-$(CONFIG_CRYPTO_NULL2) += crypto_null.o diff --git a/crypto/hkdf.c b/crypto/hkdf.c new file mode 100644 index ..35a975ed64a8 --- /dev/null +++ b/crypto/hkdf.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * RFC 5869 Key-derivation function + * + * Copyright (C) 2019, Stephan Mueller + */ + +/* + * The HKDF extract phase is applied with crypto_rng_reset(). + * The HKDF expand phase is applied with crypto_rng_generate(). + * + * NOTE: In-place cipher operations are not supported. + */ + +#include +#include +#include +#include +#include +#include + +struct crypto_hkdf_ctx { + struct crypto_shash *extract_kmd; + struct crypto_shash *expand_kmd; +}; + +#define CRYPTO_HKDF_MAX_DIGESTSIZE 64 + +/* + * HKDF expand phase + */ +static int crypto_hkdf_random(struct crypto_rng *rng, + const u8 *info, unsigned int infolen, + u8 *dst, unsigned int dlen) +{ + struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *expand_kmd = ctx->expand_kmd; + SHASH_DESC_ON_STACK(desc, expand_kmd); + unsigned int h = crypto_shash_digestsize(expand_kmd); + int err = 0; + u8 *dst_orig = dst; + const u8 *prev = NULL; + uint8_t ctr = 0x01; + + if (dlen > h * 255) + return -EINVAL; + + desc->tfm = expand_kmd; + desc->flags = crypto_shash_get_flags(expand_kmd) & + CRYPTO_TFM_REQ_MAY_SLEEP; + + /* T(1) and following */ + while (dlen) { + err = crypto_shash_init(desc); + if (err) + goto out; + + if (prev) { + err = crypto_shash_update(desc, prev, h); + if (err) + goto out; + } + + if (info) { + err = crypto_shash_update(desc, info, infolen); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[CRYPTO_HKDF_MAX_DIGESTSIZE]; + + err = crypto_shash_finup(desc, &ctr, 1, tmpbuffer); + if (err) + goto out; + memcpy(dst, tmpbuffer, dlen); + memzero_explicit(tmpbuffer, h); + goto out; + } else { + err = crypto_shash_finup(desc, &ctr, 1, dst); + if (err) + goto out; + + prev = dst; + dst += h; + dlen -= h; + ctr++; + } + } + +out: + if (err) + memzero_explicit(dst_orig, dlen); + shash_desc_zero(desc); + return err; +} + +/* + * HKDF extract phase. + * + * The seed is defined to be a concatenation of the salt and the IKM. + * The data buffer is pre-pended by an rtattr which provides an u32 value + * with the length of the salt. Thus, the buffer length - salt length is the + * IKM length. + */ +static int crypto_hkdf_seed(struct crypto_rng *rng, + const u8 *seed, unsigned int slen) +{ + struct