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

Implement ExpandHKDFOneShot #224

Merged
merged 2 commits into from
Nov 25, 2024
Merged

Implement ExpandHKDFOneShot #224

merged 2 commits into from
Nov 25, 2024

Conversation

qmuntal
Copy link
Collaborator

@qmuntal qmuntal commented Nov 20, 2024

Go 1.24 will most probably move the golang.org/x/crypto/hkdf package into the standard library: golang/go#61477. The new API will be a little bit simpler, basically hkdf.Expand won't return a io.Reader but a slice of bytes as bis as the keyLength parameter.

Our ExpandHKDF function is not well fitted to implement the new API, as it also returns an io.Reader and internally allocated a buffer that might not have the same size as keyLength, which will end up causing unnecessary allocations.

This PR implements the new ExpandHKDFOneShot function that will be used to implement the new API.

return nil, newOpenSSLError("EVP_KDF_derive")
}
default:
panic(errUnsupportedVersion())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why panic vs. returning the error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is common practice in this repo. The supported version switches should be exhaustive so we know what to update when we start supporting a new version.

Copy link
Collaborator

@dagood dagood Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What difference does return nil, errUnsupportedVersion() vs. panic(errUnsupportedVersion()) make to the switch's exhaustiveness?

FWIW, most uses of errUnsupportedVersion do use panic. Only tls1prf.go and hkdf.go return it, so maybe my confusion is in what situations it makes sense to return it rather than panic. (Maybe a doc comment on errUnsupportedVersion would make sense if it's worth explaining it for the future.)

(examples)

openssl/tls1prf.go

Lines 50 to 57 in 4f0359e

switch vMajor {
case 1:
return tls1PRF1(result, secret, label, seed, md)
case 3:
return tls1PRF3(result, secret, label, seed, md)
default:
return errUnsupportedVersion()
}

openssl/tls1prf.go

Lines 15 to 25 in 4f0359e

func SupportsTLS1PRF() bool {
switch vMajor {
case 1:
return vMinor >= 1
case 3:
_, err := fetchTLS1PRF3()
return err == nil
default:
panic(errUnsupportedVersion())
}
}

openssl/hkdf.go

Lines 17 to 27 in a47a022

func SupportsHKDF() bool {
switch vMajor {
case 1:
return versionAtOrAbove(1, 1, 1)
case 3:
_, err := fetchHKDF3()
return err == nil
default:
panic(errUnsupportedVersion())
}
}

openssl/hkdf.go

Lines 113 to 115 in a47a022

if !SupportsHKDF() {
return nil, errUnsupportedVersion()
}

That said, since this isn't new, going ahead with approval. 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What difference does return nil, errUnsupportedVersion() vs. panic(errUnsupportedVersion()) make to the switch's exhaustiveness?

Go doesn't have exhaustive, so it is idiomatic to panic in the default case to at least get a runtime panic.

Good catch about the inconsistency, will fix in a follow up PR.

return nil, newOpenSSLError("EVP_KDF_derive")
}
default:
panic(errUnsupportedVersion())
Copy link
Collaborator

@dagood dagood Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What difference does return nil, errUnsupportedVersion() vs. panic(errUnsupportedVersion()) make to the switch's exhaustiveness?

FWIW, most uses of errUnsupportedVersion do use panic. Only tls1prf.go and hkdf.go return it, so maybe my confusion is in what situations it makes sense to return it rather than panic. (Maybe a doc comment on errUnsupportedVersion would make sense if it's worth explaining it for the future.)

(examples)

openssl/tls1prf.go

Lines 50 to 57 in 4f0359e

switch vMajor {
case 1:
return tls1PRF1(result, secret, label, seed, md)
case 3:
return tls1PRF3(result, secret, label, seed, md)
default:
return errUnsupportedVersion()
}

openssl/tls1prf.go

Lines 15 to 25 in 4f0359e

func SupportsTLS1PRF() bool {
switch vMajor {
case 1:
return vMinor >= 1
case 3:
_, err := fetchTLS1PRF3()
return err == nil
default:
panic(errUnsupportedVersion())
}
}

openssl/hkdf.go

Lines 17 to 27 in a47a022

func SupportsHKDF() bool {
switch vMajor {
case 1:
return versionAtOrAbove(1, 1, 1)
case 3:
_, err := fetchHKDF3()
return err == nil
default:
panic(errUnsupportedVersion())
}
}

openssl/hkdf.go

Lines 113 to 115 in a47a022

if !SupportsHKDF() {
return nil, errUnsupportedVersion()
}

That said, since this isn't new, going ahead with approval. 😄

@qmuntal qmuntal merged commit 0657d68 into v2 Nov 25, 2024
54 checks passed
@qmuntal qmuntal deleted the hkdfgo1.24 branch November 25, 2024 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants