Skip to content

crypto/internal/fips140/drbg: unnecessary linear memory increase on Wasm with Go 1.26 #78321

@cherrymui

Description

@cherrymui

Build this program on Wasm

package main

import (
    "crypto/hmac"
    "hash"
    "hash/crc32"
)

func main() { my_func() }

//go:wasmexport my_func
func my_func() {
    mac := hmac.New(func() hash.Hash { return crc32.NewIEEE() }, []byte("test"))
    mac.Write([]byte("test"))
}

With Go 1.26,

$ GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o plugin.wasm p.go 
$ wasm-objdump -x plugin.wasm | grep -A1 "^Memory"
Memory[1]:
 - memory[0] pages: initial=550

It uses 550 pages (64 KiB each), which is ~34 MiB.

With Go 1.25,

$ GOOS=wasip1 GOARCH=wasm go1.25 build -buildmode=c-shared -o plugin.wasm p.go 
$ wasm-objdump -x plugin.wasm | grep -A1 "^Memory"
Memory[1]:
 - memory[0] pages: initial=35

It only uses 35 pages of memory.

The memory growth is due to the introduce of a 32 MiB BSS variable in crypto/internal/fips140/drbg https://cs.opensource.google/go/go/+/master:src/crypto/internal/fips140/drbg/rand.go;l=30 . This variable is never used at run time, as FIPS-140 mode is not supported on Wasm. But the toolchain does not know it statically.

Removing that variable brings the memory back to 37 pages.

The BSS memory is usually pretty cheap on regular platforms. But it can be pretty costly on Wasm, due to how the linear memory works. It is important to not increase the linear memory usage unnecessarily.

CL https://go.dev/cl/758361 addresses this by excluding that code statically with a build tag.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.FixPendingIssues that have a fix which has not yet been reviewed or submitted.arch-wasmWebAssembly issuesrelease-blocker

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions