[go] cmd/link, crypto/internal/fips140: Enable FIPS 140-3 mode for Wasm

6 views
Skip to first unread message

Daniel Morsing (Gerrit)

unread,
May 15, 2026, 1:25:28 PM (4 days ago) May 15
to goph...@pubsubhelper.golang.org, golang...@luci-project-accounts.iam.gserviceaccount.com, Filippo Valsorda, golang-co...@googlegroups.com
Attention needed from Filippo Valsorda

Daniel Morsing voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Filippo Valsorda
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
Gerrit-Change-Number: 758441
Gerrit-PatchSet: 11
Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
Gerrit-Comment-Date: Fri, 15 May 2026 17:25:21 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Daniel Morsing (Gerrit)

unread,
May 16, 2026, 8:25:50 AM (3 days ago) May 16
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Filippo Valsorda

Daniel Morsing uploaded new patchset

Daniel Morsing uploaded patch set #12 to this change.
Following approvals got outdated and were removed:
Open in Gerrit

Related details

Attention is currently required from:
  • Filippo Valsorda
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newpatchset
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
    Gerrit-Change-Number: 758441
    Gerrit-PatchSet: 12
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Daniel Morsing (Gerrit)

    unread,
    May 16, 2026, 8:30:01 AM (3 days ago) May 16
    to goph...@pubsubhelper.golang.org, golang...@luci-project-accounts.iam.gserviceaccount.com, Filippo Valsorda, golang-co...@googlegroups.com
    Attention needed from Filippo Valsorda

    Daniel Morsing voted and added 1 comment

    Votes added by Daniel Morsing

    Commit-Queue+1

    1 comment

    Patchset-level comments
    File-level comment, Patchset 12 (Latest):
    Daniel Morsing . resolved

    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.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Filippo Valsorda
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
    Gerrit-Change-Number: 758441
    Gerrit-PatchSet: 12
    Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
    Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
    Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
    Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
    Gerrit-Comment-Date: Sat, 16 May 2026 12:29:54 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Filippo Valsorda (Gerrit)

    unread,
    May 18, 2026, 6:02:35 AM (yesterday) May 18
    to Daniel Morsing, goph...@pubsubhelper.golang.org, Filippo Valsorda, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com
    Attention needed from Daniel Morsing

    Filippo Valsorda voted and added 2 comments

    Votes added by Filippo Valsorda

    Code-Review+1

    2 comments

    Patchset-level comments
    Filippo Valsorda . resolved

    crypto parts LGTM

    File lib/wasm/wasm_exec.js
    Line 546, Patchset 12 (Latest): const nameSections = WebAssembly.Module.customSections(module, "fipsrelocinfo");
    Filippo Valsorda . unresolved

    What happens if the JS passes module but the binary was not built with GOFIPS140?

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Daniel Morsing
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
      Gerrit-Change-Number: 758441
      Gerrit-PatchSet: 12
      Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
      Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
      Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
      Gerrit-Attention: Daniel Morsing <daniel....@gmail.com>
      Gerrit-Comment-Date: Mon, 18 May 2026 10:02:27 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy

      Daniel Morsing (Gerrit)

      unread,
      May 18, 2026, 6:22:42 AM (yesterday) May 18
      to goph...@pubsubhelper.golang.org, Filippo Valsorda, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com
      Attention needed from Filippo Valsorda

      Daniel Morsing added 1 comment

      File lib/wasm/wasm_exec.js
      Line 546, Patchset 12 (Latest): const nameSections = WebAssembly.Module.customSections(module, "fipsrelocinfo");
      Filippo Valsorda . resolved

      What happens if the JS passes module but the binary was not built with GOFIPS140?

      Daniel Morsing

      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.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Filippo Valsorda
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
        Gerrit-Change-Number: 758441
        Gerrit-PatchSet: 12
        Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
        Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
        Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
        Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
        Gerrit-Comment-Date: Mon, 18 May 2026 10:22:35 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Comment-In-Reply-To: Filippo Valsorda <fil...@golang.org>
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Cherry Mui (Gerrit)

        unread,
        May 18, 2026, 4:24:03 PM (16 hours ago) May 18
        to Daniel Morsing, goph...@pubsubhelper.golang.org, Filippo Valsorda, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com
        Attention needed from Daniel Morsing

        Cherry Mui added 7 comments

        Patchset-level comments
        Cherry Mui . resolved

        Thanks for the CL. Just some high-level comments.

        Commit Message
        Line 17, Patchset 12 (Latest):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 Mui . unresolved

        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?

        File lib/wasm/wasm_exec.js
        Line 479, Patchset 12 (Latest): async run(instance, module, file) {
        Cherry Mui . unresolved

        If we change this, GOROOT/misc/wasm/wasm_exec.html needs also change.

        File lib/wasm/wasm_exec_node.js
        Cherry Mui . unresolved

        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.

        File src/cmd/link/internal/ld/fips140.go
        Line 662, Patchset 12 (Latest):
        // 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
        }
        Cherry Mui . unresolved

        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?

        File src/crypto/internal/fips140/drbg/entropy_wasm.go
        Line 19, Patchset 12 (Latest): // working in Wasm. For now, to make it possible to test the reast of FIPS
        Cherry Mui . unresolved

        rest ?

        File src/crypto/internal/fips140/fips140.go
        Line 59, Patchset 12 (Latest): case runtime.GOARCH == "wasm" && (runtime.GOOS != "js" || fips140wasmentropy.Value() != "bypass"),
        Cherry Mui . unresolved

        So this is only supported on wasm/js, not on wasm/wasip1?

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Daniel Morsing
        Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
          Gerrit-Change-Number: 758441
          Gerrit-PatchSet: 12
          Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
          Gerrit-CC: Cherry Mui <cher...@google.com>
          Gerrit-Attention: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Comment-Date: Mon, 18 May 2026 20:23:58 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          unsatisfied_requirement
          satisfied_requirement
          open
          diffy

          Cherry Mui (Gerrit)

          unread,
          May 18, 2026, 4:26:51 PM (16 hours ago) May 18
          to Daniel Morsing, goph...@pubsubhelper.golang.org, Filippo Valsorda, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com
          Attention needed from Daniel Morsing

          Cherry Mui added 1 comment

          Commit Message
          Line 17, Patchset 12 (Latest):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 Mui . unresolved

          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?

          Cherry Mui

          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.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Daniel Morsing
          Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
          Gerrit-Change-Number: 758441
          Gerrit-PatchSet: 12
          Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
          Gerrit-CC: Cherry Mui <cher...@google.com>
          Gerrit-Attention: Daniel Morsing <daniel....@gmail.com>
          Gerrit-Comment-Date: Mon, 18 May 2026 20:26:47 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          Comment-In-Reply-To: Cherry Mui <cher...@google.com>
          unsatisfied_requirement
          satisfied_requirement
          open
          diffy

          Daniel Morsing (Gerrit)

          unread,
          6:41 AM (1 hour ago) 6:41 AM
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
          Attention needed from Daniel Morsing and Filippo Valsorda

          Daniel Morsing uploaded new patchset

          Daniel Morsing uploaded patch set #13 to this change.
          Following approvals got outdated and were removed:
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Daniel Morsing
          • Filippo Valsorda
          Submit Requirements:
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            • requirement is not satisfiedTryBots-Pass
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: newpatchset
            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
            Gerrit-Change-Number: 758441
            Gerrit-PatchSet: 13
            Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
            Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
            Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
            Gerrit-CC: Cherry Mui <cher...@google.com>
            Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
            Gerrit-Attention: Daniel Morsing <daniel....@gmail.com>
            unsatisfied_requirement
            open
            diffy

            Daniel Morsing (Gerrit)

            unread,
            6:42 AM (1 hour ago) 6:42 AM
            to goph...@pubsubhelper.golang.org, Cherry Mui, Filippo Valsorda, golang...@luci-project-accounts.iam.gserviceaccount.com, golang-co...@googlegroups.com
            Attention needed from Cherry Mui and Filippo Valsorda

            Daniel Morsing added 6 comments

            Commit Message
            Line 17, Patchset 12: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 Mui . unresolved

            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?

            Cherry Mui

            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.

            Daniel Morsing

            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.

            File lib/wasm/wasm_exec.js
            Line 479, Patchset 12: async run(instance, module, file) {
            Cherry Mui . unresolved

            If we change this, GOROOT/misc/wasm/wasm_exec.html needs also change.

            Daniel Morsing

            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.

            File lib/wasm/wasm_exec_node.js
            Cherry Mui . unresolved

            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.

            Daniel Morsing

            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.

            File src/cmd/link/internal/ld/fips140.go

            // 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
            }
            Cherry Mui . unresolved

            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?

            Daniel Morsing

            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.

            File src/crypto/internal/fips140/drbg/entropy_wasm.go
            Line 19, Patchset 12: // working in Wasm. For now, to make it possible to test the reast of FIPS
            Cherry Mui . resolved

            rest ?

            Daniel Morsing

            Done

            File src/crypto/internal/fips140/fips140.go
            Line 59, Patchset 12: case runtime.GOARCH == "wasm" && (runtime.GOOS != "js" || fips140wasmentropy.Value() != "bypass"),
            Cherry Mui . resolved

            So this is only supported on wasm/js, not on wasm/wasip1?

            Daniel Morsing

            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.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Cherry Mui
            • Filippo Valsorda
            Submit Requirements:
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedNo-Unresolved-Comments
            • requirement is not satisfiedReview-Enforcement
            • requirement is not satisfiedTryBots-Pass
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: I1f9176fc681ef8b5ff2f3c0befbbdac76a6a6964
            Gerrit-Change-Number: 758441
            Gerrit-PatchSet: 12
            Gerrit-Owner: Daniel Morsing <daniel....@gmail.com>
            Gerrit-Reviewer: Daniel Morsing <daniel....@gmail.com>
            Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
            Gerrit-CC: Cherry Mui <cher...@google.com>
            Gerrit-Attention: Cherry Mui <cher...@google.com>
            Gerrit-Attention: Filippo Valsorda <fil...@golang.org>
            Gerrit-Comment-Date: Tue, 19 May 2026 10:42:33 +0000
            unsatisfied_requirement
            open
            diffy
            Reply all
            Reply to author
            Forward
            0 new messages