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

crypto/rand: Legacy RtlGenRandom use on Windows #53192

Closed
tolginator opened this issue Jun 1, 2022 · 11 comments
Closed

crypto/rand: Legacy RtlGenRandom use on Windows #53192

tolginator opened this issue Jun 1, 2022 · 11 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@tolginator
Copy link

What version of Go are you using (go version)? 1.18.3 (Windows)

$ go version
go version go1.18.3 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Windows 10, x64

go env Output
$ go env

set GOARCH=amd64
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVERSION=go1.18.3
set GCCGO=gccgo
set GOAMD64=v1

What did you do?

I identified this issue in a security code review.

What did you expect to see?

Use a recommended Windows random number as specified in https://docs.microsoft.com/en-us/security/sdl/cryptographic-recommendations#random-number-generators.
Id recommend BCryptGenRandom with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag, and remove any calls to the RtlGenRandom API.

What did you see instead?

In file rand_windows.go, random numbers are generated by calling a legacy PRNG API, RtlGenRandom.

@ericlagergren
Copy link
Contributor

Dupe of #33542

@dmitshur
Copy link
Contributor

dmitshur commented Jun 3, 2022

Thanks—it does look like the decision to go with RtlGenRandom over BCryptGenRandom was made fairly recently in #33542.

Unless something significant has changed since #33542 (comment), I think this issue can be closed.

CC @golang/security.

@dmitshur dmitshur added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jun 3, 2022
@dmitshur dmitshur added this to the Backlog milestone Jun 3, 2022
@rolandshoemaker
Copy link
Member

It may be reasonable to revisit this decision. It sounds like Rust (and rust-random/getrandom) switched to BCryptGenRandom after we made our decision.

It sounds like one of the main drivers for BoringSSL sticking with RtlGenRandom was that BCryptGenRandom may require reading information from the registry, which is not viable inside of sandboxes (which makes it non-viable for Chromium.) It also sounds like performance concerns are perhaps unfounded, as both incur similar start-up costs, and then perform basically the same. We don't really have these concerns (we use other Windows APIs that act similarly.)

I'd generally err on the side of using something that is (a) recommended in Windows API documentation, and (b) has it's internals documented, over something which is (a) deprecated and (b) we only know how it works because of reversing. That said, it seems like there is no real pressing concerns for why we should switch away. RtlGenRandom is not broken, nor does it look like Microsoft is going to excise it any time soon. If BCryptGenRandom was noticeably faster that would be a good reason to switch, but it sounds like performance is ~basically the same.

cc @zx2c4, who previously had opinions about this.

@zx2c4
Copy link
Contributor

zx2c4 commented Jun 4, 2022

I haven't seen any thing change on the Windows side of things. I can go on another reverse engineering diving tour and see if there's anything interesting down there. But barring that, I don't see any reason to revisit this decision at the moment.

(b) we only know how it works because of reversing

RtlGenRandom is documented actually.

@dmitshur dmitshur removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jun 4, 2022
@seankhliao seankhliao added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Jun 5, 2022
@rolandshoemaker
Copy link
Member

RtlGenRandom is documented actually.

Oh really, do you have a link? I was under the impression there was only an officially published vague outline of how the algorithm worked (and/or had no guarantee that it would stick to the outline as it was specified at the time.)

@zx2c4
Copy link
Contributor

zx2c4 commented Jun 6, 2022

@qmuntal
Copy link
Contributor

qmuntal commented Oct 24, 2023

CL 536235 just replaced RtlGenRandom with ProcessPrng, which is not deprecated and is what RtlGenRandom uses under the hood.

We can close this issue, as it is about not using a legacy random number generator, which is not the case anymore.

@qmuntal qmuntal closed this as completed Oct 24, 2023
@dmitshur dmitshur modified the milestones: Backlog, Go1.22 Oct 24, 2023
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. labels Oct 24, 2023
@rolandshoemaker
Copy link
Member

@gopherbot please open backport issues, this reduces the impact of a security issue.

@gopherbot
Copy link

Backport issue(s) opened: #64412 (for 1.20), #64413 (for 1.21).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@gopherbot
Copy link

Change https://go.dev/cl/545356 mentions this issue: [release-branch.go1.20] crypto/rand,runtime: switch RtlGenRandom for ProcessPrng

@gopherbot
Copy link

Change https://go.dev/cl/545355 mentions this issue: [release-branch.go1.21 crypto/rand,runtime: switch RtlGenRandom for ProcessPrng

gopherbot pushed a commit that referenced this issue Nov 28, 2023
…ProcessPrng

RtlGenRandom is a semi-undocumented API, also known as
SystemFunction036, which we use to generate random data on Windows.
It's definition, in cryptbase.dll, is an opaque wrapper for the
documented API ProcessPrng. Instead of using RtlGenRandom, switch to
using ProcessPrng, since the former is simply a wrapper for the latter,
there should be no practical change on the user side, other than a minor
change in the DLLs we load.

Updates #53192
Fixes #64413

Change-Id: Ie6891bf97b1d47f5368cccbe92f374dba2c2672a
Reviewed-on: https://go-review.googlesource.com/c/go/+/536235
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
(cherry picked from commit 693def1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/545355
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
gopherbot pushed a commit that referenced this issue Nov 28, 2023
…ProcessPrng

RtlGenRandom is a semi-undocumented API, also known as
SystemFunction036, which we use to generate random data on Windows.
It's definition, in cryptbase.dll, is an opaque wrapper for the
documented API ProcessPrng. Instead of using RtlGenRandom, switch to
using ProcessPrng, since the former is simply a wrapper for the latter,
there should be no practical change on the user side, other than a minor
change in the DLLs we load.

Updates #53192
Fixes #64412

Change-Id: Ie6891bf97b1d47f5368cccbe92f374dba2c2672a
Reviewed-on: https://go-review.googlesource.com/c/go/+/536235
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
(cherry picked from commit 693def1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/545356
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

No branches or pull requests

8 participants