| Commit-Queue | +1 |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Commit-Queue | +1 |
Made the linker only construct the shadow text buffer when building with GOFIPS140 set. This removes a ~1mb runtime memory cost (if importing crypto/tls) for builds that don't need FIPS140-3 support.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +1 |
crypto parts LGTM
const nameSections = WebAssembly.Module.customSections(module, "fipsrelocinfo");What happens if the JS passes module but the binary was not built with GOFIPS140?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
const nameSections = WebAssembly.Module.customSections(module, "fipsrelocinfo");What happens if the JS passes module but the binary was not built with GOFIPS140?
There'll be no fipsrelocinfo section, the shadow buffer will consist of a single 0 byte, but the hash will be of all the FIPS text anyway. This will make the POST fail.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Thanks for the CL. Just some high-level comments.
The first problem, we handle by changing how the linker emits the
fipsinfo object when compiling for webassembly. Instead of pointers to a
non-existent text segment, we emit pointers to a buffer that the loader
script fills with the code bytestream. The loader finds this information
via a custom section in the webassembly module. The end effect is that
we perform the test as certified in the 1.0.0 version of the FIPS140-3
module.It seems a little weird that running the Go wasm module depends on the module file itself. What if the user compile the module first (with `WebAssembly.compile`), then instantiate with the compiled module?
Reading the code, the current approach seems to support only wasm/js (not wasm/wasip1), in a specific use mode. Namely, using wasm_exec_node.js mostly as is. I'm not sure this is a major use case for Go Wasm. In the web case, users usually integrate the instantiation of the module into their code. Requiring providing the module bytes at run time seems limits the flexibility. Also, is there a plan to support wasip1? There, users would also compile/instantiate the module in an integrated way.
Do you know if any other language supports FIPS verification with Wasm? What approach do they take?
async run(instance, module, file) {If we change this, GOROOT/misc/wasm/wasm_exec.html needs also change.
This changes only node. What about browser? User will invoke wasm_exec.js in their code. We provide misc/wasm/wasm_exec.html as a sample, but users usually don't use it as is.
// The buffer does have some cost associated with it, so only construct it
// if we're building a binary with GOFIPS140 set. The go tool sets the fipso
// flag, so discover it via that.
if *FlagFipso == "" {
return
}If I recall correctly from the original CLs from Russ, the -fipso flag is mostly a debugging flag, to extract the FIPS part to a separate file for inspection. If we want to make it more than a debugging flag, perhaps document it more clearly in cmd/go code comment.
Do you have an estimate what the cost will be? Like, how much memory usage increase it will incur?
// working in Wasm. For now, to make it possible to test the reast of FIPSrest ?
case runtime.GOARCH == "wasm" && (runtime.GOOS != "js" || fips140wasmentropy.Value() != "bypass"),So this is only supported on wasm/js, not on wasm/wasip1?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
The first problem, we handle by changing how the linker emits the
fipsinfo object when compiling for webassembly. Instead of pointers to a
non-existent text segment, we emit pointers to a buffer that the loader
script fills with the code bytestream. The loader finds this information
via a custom section in the webassembly module. The end effect is that
we perform the test as certified in the 1.0.0 version of the FIPS140-3
module.It seems a little weird that running the Go wasm module depends on the module file itself. What if the user compile the module first (with `WebAssembly.compile`), then instantiate with the compiled module?
Reading the code, the current approach seems to support only wasm/js (not wasm/wasip1), in a specific use mode. Namely, using wasm_exec_node.js mostly as is. I'm not sure this is a major use case for Go Wasm. In the web case, users usually integrate the instantiation of the module into their code. Requiring providing the module bytes at run time seems limits the flexibility. Also, is there a plan to support wasip1? There, users would also compile/instantiate the module in an integrated way.
Do you know if any other language supports FIPS verification with Wasm? What approach do they take?
Since this changes how users integrate/instantiate/run Go Wasm modules, it may be a good idea to start a discussion on an issue. Thanks.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
The first problem, we handle by changing how the linker emits the
fipsinfo object when compiling for webassembly. Instead of pointers to a
non-existent text segment, we emit pointers to a buffer that the loader
script fills with the code bytestream. The loader finds this information
via a custom section in the webassembly module. The end effect is that
we perform the test as certified in the 1.0.0 version of the FIPS140-3
module.Cherry MuiIt seems a little weird that running the Go wasm module depends on the module file itself. What if the user compile the module first (with `WebAssembly.compile`), then instantiate with the compiled module?
Reading the code, the current approach seems to support only wasm/js (not wasm/wasip1), in a specific use mode. Namely, using wasm_exec_node.js mostly as is. I'm not sure this is a major use case for Go Wasm. In the web case, users usually integrate the instantiation of the module into their code. Requiring providing the module bytes at run time seems limits the flexibility. Also, is there a plan to support wasip1? There, users would also compile/instantiate the module in an integrated way.
Do you know if any other language supports FIPS verification with Wasm? What approach do they take?
Since this changes how users integrate/instantiate/run Go Wasm modules, it may be a good idea to start a discussion on an issue. Thanks.
Yes, the FIPS support requires the module bytestream itself, otherwise it wouldn't get the code that it needs to verify during the POST.
For now, no plans to do wasip. The way those modules are loaded doesn't allow for the loader script to write into memory buffers, so our POST trick wouldn't work. We could put a normal copy of the bytestream into the data section, but then we wouldn't be verifying what we're actually running, and I doubt it would pass muster with the verification labs. Arguably, we're not doing that with this current scheme either, but the provenance from text on disk to what the wasm runtime actually does is verifiable.
As for other languages/runtimes, I think we are in the unenviable position of being the first here. I don't think anybody has tried to FIPS validate a webassembly module.
async run(instance, module, file) {If we change this, GOROOT/misc/wasm/wasm_exec.html needs also change.
Those last 2 arguments are optional. This will obviously have to be documented somewhere, but I'm not sure exactly where. For now I've just added a comment.
This changes only node. What about browser? User will invoke wasm_exec.js in their code. We provide misc/wasm/wasm_exec.html as a sample, but users usually don't use it as is.
I don't really see a way that you could run wasm in a browser in a FIPS140-3 compatible way. I am more than willing to admit that running Go wasm as a standalone process on servers is a niche use case, but one that we've had customer enquiries about. I believe their end goal is sandboxing and deployment flexibility.
// The buffer does have some cost associated with it, so only construct it
// if we're building a binary with GOFIPS140 set. The go tool sets the fipso
// flag, so discover it via that.
if *FlagFipso == "" {
return
}If I recall correctly from the original CLs from Russ, the -fipso flag is mostly a debugging flag, to extract the FIPS part to a separate file for inspection. If we want to make it more than a debugging flag, perhaps document it more clearly in cmd/go code comment.
Do you have an estimate what the cost will be? Like, how much memory usage increase it will incur?
Noted, I've added a comment about the linker fipso switch in cmd/go/internal/work.
The shadow buffer reaches a size of ~1mb when importing crypto/tls and that will stick around for the runtime of the program. We could probably avoid it by moving the POST to sometime before malloc is inited, then the buffer could be reused for allocations as they happen, but that would mean a major reorganization of the runtime and mean recertifying the POST.
I could remove the link-time switch here, but I think a 1mb penalty might be too much for support that is rarely ever needed.
// working in Wasm. For now, to make it possible to test the reast of FIPSDaniel Morsingrest ?
Done
case runtime.GOARCH == "wasm" && (runtime.GOOS != "js" || fips140wasmentropy.Value() != "bypass"),So this is only supported on wasm/js, not on wasm/wasip1?
Correct, for now it only supports the JS OS. AFAICT wasip1 doesn't give any mechanisms where the contents of the module bytestream can be loaded separately into a memory buffer.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |