Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: x/crypto: kbkdf #50136

Closed
chrisfenner opened this issue Dec 13, 2021 · 10 comments
Closed

proposal: x/crypto: kbkdf #50136

chrisfenner opened this issue Dec 13, 2021 · 10 comments
Labels
FrozenDueToAge Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Milestone

Comments

@chrisfenner
Copy link

KBKDF aka SP800-108 is a pre-HKDF NIST KDF recommentation using a PRF (e.g. HMAC).

Where used

kbkdf is used (in the HMAC-CTR mode) by TPM 2.0, which calls it KDFa. This leads Go TPM caller code to roll its own implementation of this KDF. Though the KDF is simple, it would be nice to have a cryptographer-reviewed, shared implementation at x/crypto.

openssl has support for HMAC- and CMAC-based, counter- and feedback-mode flavors. It implements the counter-mode KDF as TPM does (i.e., with 32-bit big-endian counter and length fields, and all fields included as recommended in the NIST paper).

I will link a Gerrit code review containing a proposed implementation.

@seankhliao seankhliao added the Proposal-Crypto Proposal related to crypto packages or other security issues label Dec 13, 2021
@seankhliao
Copy link
Member

cc @FiloSottile

@gopherbot gopherbot added this to the Proposal milestone Dec 13, 2021
@chrisfenner
Copy link
Author

I sent a PR containing a proposed implementation at https://go-review.googlesource.com/c/crypto/+/371315

@gopherbot
Copy link

Change https://golang.org/cl/371315 mentions this issue: x/crypto: implement kbkdf

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Dec 15, 2021
@rsc
Copy link
Contributor

rsc commented Dec 15, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals (old) Dec 15, 2021
@rsc
Copy link
Contributor

rsc commented Dec 16, 2021

For what it's worth, looks like the entirety of the public API is

package kbkdf

func HMACCounter(h func() hash.Hash, keyLen int, secret, label, context []byte) []byte

In contrast, x/crypto/pbkdf2 calls the equivalent function just 'Key', and the arguments are in approximately the reverse order. (See https://pkg.go.dev/golang.org/x/crypto/pbkdf2.) It seems like at the least we should try to make kbkdf's API look as close to pbkdf2's as possible. That would mean:

package kbkdf

func Key(secret, label, context []byte, keyLen int, h func() hash.Hash) []byte

unless the existing API is trying to match something else.
And of course I may misunderstand the details of the API here.
Are there other possible kbkdf functions?
Is that why HMACCounter was in the name?

@chrisfenner
Copy link
Author

chrisfenner commented Dec 16, 2021

Thanks, Russ. I agree, we could reorder the parameters to more closely match pbkdf's ordering. The ordering of parameters I've suggested is more based on https://pkg.go.dev/golang.org/x/crypto/hkdf. (hkdf is the newer, better PRF based KDF that TPM missed the boat on by a couple of years, it seems).

KBKDF can be based on HMAC or CMAC (though I don't think the Go crypto libraries support CMAC yet - see https://pkg.go.dev/github.com/aead/cmac for what looks like a reasonable implementation).
KBKDF can also be in one of three modes: Counter (implemented in my Gerrit change), Feedback, and Double-Pipeline Iteration modes. OpenSSL only supports the first two, and TPM only uses the first one.

I wanted to leave room for growth, either CMAC based or other-modes. We could also implement something like

func Counter(h func() hash.Hash, keyLen int, label, context []byte) []byte

but this would require callers to write something like

key := Counter(func() hash.Hash {return hmac.New(sha256.New, "secret")}, 32, []byte("label"), []byte("context"))

and while flexible (supports bring-your-own-CMAC implementation) it seems more finnicky to use. It's also unintuitive, we would be asking for a parameter of a type called Hash but what we mean is HMAC or CMAC (which happen to implement the interface called Hash - though one way to mitigate this would be to duplicate the hash.Hash interface as kbkdf.PRF)

@rsc
Copy link
Contributor

rsc commented Jan 5, 2022

/cc @golang/security

@FiloSottile
Copy link
Contributor

Discussed with @chrisfenner offline and I believe this does not clear the bar for addition to x/crypto:

  • there is no scenario in which a new application would want to choose KBKDF over HKDF, which is more widely adopted and analyzed, and already available in x/crypto
  • KBKDF has a myriad of variants, and we'd have to implement them all to be useful to all users of KBKDF, as the assumption is that they are bound by compatibility and not free to choose the variant we implement
  • the only spec that requires KBKDF that I am aware of is the TPM one, and we had never gotten a request to implement it before, which suggests this belongs in the go-tpm tree
  • the implementation is very simple and unsubtle, and shares no code with x/crypto internals, so I am not worried about it living in a third-party module

@rsc
Copy link
Contributor

rsc commented Jan 12, 2022

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@rsc rsc moved this from Active to Likely Decline in Proposals (old) Jan 12, 2022
@rsc rsc moved this from Likely Decline to Declined in Proposals (old) Jan 19, 2022
@rsc
Copy link
Contributor

rsc commented Jan 19, 2022

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Jan 19, 2022
@golang golang locked and limited conversation to collaborators Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Projects
No open projects
Development

No branches or pull requests

5 participants