-
Notifications
You must be signed in to change notification settings - Fork 13
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
OpenSSL bindings for non standard crypto packages #100
Comments
We are also interested on supporting The approach that we were currently pursuing is to fork The problem with using the Luckily, using the If we want to have a common
@xnox, from Canonical, is also interested on this. |
I don't know about go:linkname - will read on that. I do somehow wish for a nice way to consume |
I'll try to summarize what we (@qmuntal and I) wanted to support here and some problems we hit:
Please point out bad assumptions (or if I'm misremembering anything, @qmuntal), and sorry for the wall of text, but I'm hoping it'll be fruitful to share our thought process so far. 🙂
microsoft/go has some infra behind it in https://github.com/microsoft/go-infra that could potentially be reused, and I lean towards submodule-based forks rather than "true" forks for flexibility's sake but I don't know if everyone would be on board with that. For common ground I expect we'd use scheduled GitHub Actions and approve+merge PRs manually between the maintainers to make the process observable. I think it's important here to figure out what we want to (and what we can) support. That might limit figuring out how to branch it and apply backend-interaction fixes across N branches. We can also figure out if we can handle that manually or go deeper into strategies that can simplify the process. |
Experimenting with a toolchain that has openssl with custom things in place, it seems like we can contribute to x/crypto itself to do the right thing. Which might be the best thing to do anyway? it appears that one can do stuff like //go:build goexperiment.opensslcrypto
package sha3
import (
_ "unsafe"
"hash"
)
//go:linkname New384 crypto/internal/backend.NewSHA3_384
func New384() hash.Hash
//go:linkname Sum384 crypto/internal/backend.SHA3_384
func Sum384([]byte) [48]byte Which basically gives access to crypto/internal symbols from external packages. if we add that inside x/crypto/sha3 itself, any external projects need to ensure they update their go.mod as normal and we are done? without need to maintain anything in our golang toolchains to imitate x/crypto? Obviously this doesn't address things that are possible with openssl and do not even exist in neither x/crypto nor in go-lang toolchain but still doable no? It will mean to potentially add more bindings in golang-fips/openssl and add more symbols in crypto/internal/backend as needed which other things will go:linkname to? Or does this all not good to you? |
or do we need more things to expose things? i.e. goexperiment.opensslcrypto.provides-sha3? because i guess linkname will only be resolved at like runtime of the compiled app? or maybe x/crypto itself need extra build flags that people can turn on and off? aka buildflag to attempt to do sha3 via linkname. |
An update from the Microsoft end: we've been working on an automatic module replacement approach. One concern we had earlier was this:
But golang/go#56325 makes this much less concerning:
That means so far, we're comfortable with the idea of maintaining only one version in a fork (based on the latest x/crypto version) and forcing apps to use that. The automatic replacement requires some patches to the toolset and I have a draft at microsoft/go#1043. (And it indeed uses
I'm initially skeptical that upstream would let us add things that are meaningless for "normal" Go, specific to our fork like It would be fantastic to agree on backend API naming and make it into a de facto standard by pushing it to upstream, and I don't want to be dismissive of this approach because it would be much better if possible.
We have a perhaps extreme-sounding goal for Microsoft Go: backend swap-in should be possible without any source changes, not even But: maybe other forks don't care about this and would prefer a simpler approach, even if it means their users need to patch OSS code that depends on x/crypto. We can share the x/crypto fork (or get it into upstream) and leave the automatic module replacement as a patch in only the Microsoft Go fork. I do think we can get our
I think we do need to be capable of implementing x/crypto APIs with OpenSSL even if BoringCrypto doesn't implement them, to meet our FIPS goals. I think we could still try to upstream changes that make this happen, they're just more likely to be rejected (because they can't be tested with ordinary Go toolsets, etc.)
Yeah, I've already done some of this in the prototype/draft with
So far I only think only one "should we replace x/crypto functionality?" build tag/experiment is needed. (I called it |
This project provides OpenSSL bindings for the Go standard crypto library, but there seems to be community interest in using non standard libraries such as x/crypto. Our approach so far with the project has been to provide effectively the same set of supported functionality as upstream Go, because the maintenance costs can be shared with the wider community via the upstream boringcrypto implementation.
Third party ecosystem packages do not have community implementations of boringcrypto, and without community agreement on a common implementation, we as a small community likely do not have the capacity to diverge and maintain our own custom implementation of non standard crypto packages. From time to time, the wider Go community does bring /x/ packages into the standard library, which is likely the best way to support those packages as it eliminates the risks associated with substantial divergence of community efforts (golang/go#61477) as an example of such a proposal). One approach could be to continue to advocate for more commonly used x/crypto packages to be adopted into the Go standard library upstream, or similarly, to advocate for a wider community implementation of boringcrypto bindings in the upstream x/crypto libraries.
Alternatively, for crypto which is not provided by Go standard library, it is technically possible for users to implement their own bindings on top of the internal golang-fips C API. An example in practice would be Grafana in CentOS Stream, which implements a patch to override the default implementation of x/crypto/pbkdf2 with its own calls into OpenSSL. While it's already demonstrably possible to do this, if there were a way to make the process more accessible (eg. API stability, documentation, boilerplate code generation), it might be a somewhat flexible way to accomplish roughly the same thing.
Does anyone have additional thoughts for users who would like to integrate non standard crypto libraries in their applications?
The text was updated successfully, but these errors were encountered: