Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Microsoft Go 1.24 FIPS changes (devblogs.microsoft.com/go)
85 points by ingve on Feb 6, 2025 | hide | past | favorite | 63 comments


The upstream Go 1.24 changes and macOS support using system libraries in Microsoft's Go distribution are really significant for the large ecosystem of startups trying to sell to institutions requiring FIPS 140 certified cryptography.

For a variety of reasons - including "CGo is not Go" (https://dave.cheney.net/2016/01/18/cgo-is-not-go) - using boringcrypto and requiring CGO_ENABLED=1 could be a blocker. Not using system libraries meant that getting all of the software to agree on internal certificate chains was a chore. Go was in a pretty weird place.

Whether FIPS 140 is actually a good target for cryptography is another question. My understanding is that FIPS 140-1 and 140-2 cipher suites were considered by many experts to be outdated when those standards were approved, and that FIPS 140 still doesn't encompass post quantum crypto, and the algorithms chosen don't help mitigate misuse (e.g.: nonce reuse).


Whether FIPS 140 is actually a good target for cryptography is another question

Answer to that question: it is not. It's a thing you only do when you are forced to by some requisitions process.


> It's a thing you only do when you are forced to by some requisitions process.

We're going through a FIPS compliance project right now and it's nothing more than a miserably expensive set of check boxes. Contractor they hired is incompetent so that isn't helping either.


Either projects start shipping FIPS enabled or companies have to rebuild and repackage projects with FIPS enabled.

With OpenSSL installed system wide you can turn on a flag and the library will force it into FIPS mode internally, with Go unless you build your binaries to link against OpenSSL like this Microsoft Go release seems to be doing you don't get that instant on system wide.


I had a hunch you'd reply and say as much!

It's just unfortunate for the many orgs delivering software that eventually customers start demanding this and it was really painful in Go.


Does this mean FIPS-enabled software never runs as such in production (or at all) in environments where it is supposedly mandated?


Most projects that compile against OpenSSL can be forced into FIPS mode by setting a flag that the OpenSSL library uses to force enable FIPS mode when it is loaded.

Golang projects however don't compile against OpenSSL instead using the internal cryptography. In many cases rebuilding and repackaging a Golang based tool is a no-no since now you are accepting ownership of it in an audit, when instead you want to point to an upstream vendor, or source code is not available.

So in many cases in production while the system itself is in FIPS mode (Linux kernel), and applications using system crypto libraries (OpenSSL primarily) are in FIPS mode, Go binaries are not in FIPS mode and may end up using algorithms that are explicitly disallowed by the FIPS standards.


I don't understand the question.

We created software and we wanted it to be secure (by ourselves). When it came to FIPS compliance, we had to pay for certification, but we were already compliant anyway, so it was only procedure.

It's definitely not as strict as the latest developments in crypto would demand, but it does cover the product in its entirety. Like, oh, you have encryption, but you have a backdoor here: not FIPS-2 compliant.

So, yes, plenty of software and products are FIPS compliant. And if it's mandated, then the provider is not chosen.


FIPS and "be secure" aren't necessarily a full overlap: there's plenty of ways to be secure that isn't even allowed in FIPS, so you need to actively disable that set if you run FIPS mode (depending on libraries used, this may e.g. disqualify hardware intrinsics because it was not covered by CMVP, creating potentially material performance consequences).

If you're already compliant (implying you are using FIPS compliant crypto in all situations), the matter is tautological.


Well, I agree that if you are using alternate means to achieve the same effect (or better!) and that's not recognized by the FIPS compliance then that can be painful.

My experience lies mostly in C and embedded applications, where the physical security was also in question and that is where the most of the effort to certify went. Software was relatively easy by using the right versions. So, maybe not just a certification, but non-fretting one.


There are people here better positioned to answer than than I am. We've said "no" to customers who asked for this.


In some cases that's true, but not all. We have customers who require that our software supports running in a FIPS compliant mode, but never actually end up enabling it in production. But they wouldn't have bought our software without the option of enabling FIPS mode.


Author here. The macOS support currently uses cgo, but we are trying to make it cgo-less in Go 1.25, just as already happens on Windows. The goal is to allow pain-free cross-compilations from Linux to macOS.


For those building applications with FIPS 140 crypto the primary concern is compliance rather than security. There are many organizations (e.g., US federal) that have requirements for it.

The latest version is FIPS 140-3 and is more up to date.

Note, binaries made for FIPS 140 with OpenSSL dynamically linked do not run on Alpine. While I've not looked at the Microsoft go/openssl compiler, it's worth testing its output across distros/versions as different distros have different versions of glibc and openssl.


From https://news.ycombinator.com/item?id=28540916#28546930 :

  GOLANG_FIPS=1
From https://news.ycombinator.com/item?id=42265927 :

> Chrome switching to NIST-approved ML-KEM quantum encryption" (2024) https://www.bleepingcomputer.com/news/security/chrome-switch...

From https://news.ycombinator.com/item?id=41535866 :

>> Someday there will probably be a TLS1.4/2.0 with PQ, and also FIPS-140-4?


I had to deal with FIPS compliance while at MS for FedRAMP compliance. It's not a technical problem, but a compliance problem

If you don't need FIPS for compliance you're better off investing in much more useful things for security (more effective linting, test coverage, keeping dependencies up to date, etc)


Is the juice worth the squeeze for FIPS compliance? It sounds absolutely miserable


Uncle Sam wouldn’t even consider purchasing your product if it doesn’t tick some boxes. Now there are ways to get exceptions if you go high enough up the chain.

But it is a miserable exercise all in all. As you’re implementing it, you think “this is making things worse, less robust or secure, but oh well, that’s the only way it will sell”.


Depends on what you mean by juice. Is it worth the money? Yes


TIL there are multiple flavors of Golang including “Microsoft Go”. Wow - I’ve been away from Golang too long. I was initially shocked and then kind of sad that Go is not so simple anymore.


https://github.com/microsoft/go/blob/microsoft/main/patches/...

Upstream Go tricks Windows into enabling long path support by setting an undocumented flag in the PEB. The Microsoft Go fork can't use undocumented APIs, so this commit removes the hack.

There is no documented way to enable long path support from within the process, so this this is a breaking change for the Microsoft Go fork. Note that the Go standard library makes a best effort to support long paths by using the `\\?\` prefix when possible, so this change should only affect long relative paths, which can't be used with the `\\?\`.

lol?


Presumably there's some reason Go can't just use an embedded manifest[1] like everyone else?

Ahh, I'm inferring (from [2]) even with the manifest entry, a system wide registry key is also required to get long paths working:

> I'm working with the Windows security team to find a way to enable long path support without having to modify the registry, just by using the embedded manifest, but the chances of this happening soon are quite low.

[1] https://learn.microsoft.com/en-us/windows/win32/fileio/maxim... [2] https://github.com/golang/go/issues/69853


I have been following Go for a while and didn't know that either.


> I was initially shocked and then kind of sad that Go is not so simple anymore.

Yeah, it's really sad. Go basically became like any other language.

Now even fun stuff like net.IP, and a netip, with netip.Addr. Lots of way to write the same thing. And an even further shift from Go initially being something along the lines of "You shouldn't control or even think of the garbage collector" to now having runtime.AddCleanup) as well as more fun hacks to technically stay compatible.

Now, I am not saying that the changes are bad per se, but more that they simply aren't matching the original design/claims/goals. I remember Rob Pike saying things like "The language likely won't change much" other than generics which have been said to likely come since pre-1.0 basically since Go got a website. The idea clearly was to stay simple, but that seems to have been thrown overboard. I wished Go's predecessors (Limo, Alef, et al) or something similar would have made it out of the more researchy state.

But hey looks like some more stable languages get traction. To my complete surprise Ada is making a comeback with [Alire](https://alire.ada.dev/) and such. Not really a Go competitor, but nice to see it's still being worked on.


Is the fragmentation due to FIPS 140-2 alone? Or are there other differences?

Why couldn't the crypto changes be rolled into mainstream Go?


The crypto changes are being rolled into mainstream Go, just that mainstream Go does not want the openssl/SCOSSL/SymCrypt parts.


Ah, thanks. This reply also had more FIPS details:

https://news.ycombinator.com/item?id=42966945


IIRC, the FIPS-compliant Go crypto project was a Filippo Valsorda joint. I hate it, but I'm glad someone sane managed it.


I'm not involved in the OpenSSL/CNG-based Microsoft Go fork.

I've managed and implemented—along with Daniel McCarney, Roland Shoemaker, and Russ Cox—the native upstream Go validation mentioned in the intro, which is shipping in Go 1.24 and will be certified on Linux (amd64, arm64, ppc64le, s390x), Windows (amd64, arm64), macOS (arm64), and FreeBSD (amd64). The Linux operating environments were funded by various stakeholders, the rest were funded by Geomys for the benefit of the Go community.

There are some details now at https://go.dev/doc/security/fips140, but we're going to write a proper blog post once the module gets on the CMVP In Process list.

tl;dr is that it should soon take a single environment variable to transparently build against a FIPS 140-3 validated module which is just a slightly out of date version of the same Go standard library everyone else is using. (AFAIK this is the first non-JVM memory safe FIPS 140 module!)


Is there going to be a way to turn FIPS on as a requirement without having compiled the binary against the FIPS-140 module?

Even now it has been a lot of trouble trying to get vendors to provide us a way to rebuild/repackage their Golang binaries using the FIPS-140 support from RHEL, and if it is still the case that they need to build one-offs, teams will still need to rebuild/repackage a lot of Golang tools just to be FIPS compliant because it's not as simple as setting a flag like it is for OpenSSL.


Do you anticipate that:

> When GODEBUG=fips140=only is used, in addition to the above, cryptographic algorithms that are not FIPS 140-3 compliant will return an error or panic. Note that this mode is a best effort and can’t guarantee compliance with all FIPS 140-3 requirements.

Will need to be more complete/certain in order to pass certification? My gut says it would based on the requirements, but I don't know how the auditors would respond in practice.


I just wanted to say that we've adopted many of your projects at $DAYJOB, and it has been one of the best technical decisions we've made. So far I've used the Go crypto package, age, and more recently xwing. It all works flawlessly, and at every turn we have happy surprises (smooth cross-compilation, the Age plugin framework, typage, fast xwing revisions, your blog posts).

If we ever meet in person, I own you a beer!


I think that Filippo deserves a bit more than a beer. He has business setup for true sponsorship.

https://words.filippo.io/full-time-maintainer/


I'm so glad this is making its way in to Go properly now, and sort of baffled that this wasn't treated as a priority sooner by Google, given that they're operating within FIPS environments.


When you say "validated module" do you mean Golang module?


https://github.com/golang/go/issues/69536?ref=words.filippo....

https://words.filippo.io/dispatches/fips-hkdf/

Thought one of the Filippo/Go/FIPS posts had a big thread but doesn't look like it and/or can't find it.


> "was a Filippo Valsorda joint"

I like the reference.


I worked on a project about 4-5 years ago that required operating in a FIPS 140-2 environment and this was a huge problem, happy to see there's multiple different investments into doing this right. Same with OpenSSL offering an easy-to-snag FIPS-certified implementation.

We had to buy what felt like bootleg Canonical OpenSSL binaries, and Go looked like building some speculative forks that clearly had not been designed to be released.


> We had to buy what felt like bootleg Canonical OpenSSL binaries

Isn't this the entire FIPS scam? You have to do whatever your auditor says, even if it's ridiculous, and they are getting paid under the table by vendors.


I am glad I am not the only one who thinks FIPS is a scam along with the contractor industry that has spawned up around it. Our VC hired contractor tried the same thing, walk in and hand us his "master plan" without any input from us and collect his 75k. His plan would never work in our environment and when we presented our list of issues he was dismissive and the project has barely progressed. Thank god we meticulously document all of our communications in emails which we have had to show in meetings with the president to explain why we are past our deadline with no concrete plan or hardware ordered. Total mess...


Why under the table? Seems like someone like Canonical could just outright do the auditing itself.


This is interesting, but in this moment it is impossible to take any aspect of the FIPS program seriously. To get FedRAMP contracts you must meet FIPS 140-2 or -3! Or, you can just change your 4chan handle to "BigBalls". That's also acceptable.


There's a few issues here. The dash version, 140-2 or 140-3 is the major version of the standard. You can only certify against -3 right now. Within the standard there are four level, 1 - 4 with 1 being the lowest and 4 being the highest. So a full cert descriptor would be something like "FIPS 140-3 Level 2".

In order to get that you need to hire a certification lab to verify what you did and from there the government processes it. That processing, reading paperwork and asking a couple questions, takes over a year at this point which is where a significant issue is. This is also a prereq to FedRAMP, which is a whole new set of paperwork and checkbox compliance that adds debatable quality.

I can understand the need to prevent unsafe solutions, but the current process is so slow and expensive that it makes selling useful things to customers that require FIPS a huge PITA.


Microsoft Go? I've used Go on windows for years now and this is the first I've heard of this fork. So it only exists because microsoft wants to have a crypto package that complies with an arbitrary regulation? Is there a reason that a better package requires a fork of the entire runtime rather than just, say, a normal Go package? It sounds like it requires cgo to call into third-party libraries, but that's already a common practice in "normal" Go libraries.

One thing I do appreciate is how the relevant issue in the upstream Go repo says: "A number of companies must comply with them, for example as part of a broader FedRAMP compliance posture. (If that's not you, you can ignore this. Run!)" [1]

Apparently I'm just not the target audience. Sounds like I'm correct in assuming it's security theater at best, and an avenue for new backdoors at worst.

[1] https://github.com/golang/go/issues/69536


The comment is accurate that if you don't need this, you can ignore it. It's likely not an avenue for backdoors. I wouldn't say it's security theater but it just isn't meaningful to most.

As for why not a library? Go has a pretty big "batteries included" implementation for networking. For customers demanding FIPS compliance it isn't enough to say, write all of your own application code to use a package that does FIPS-compliant TLS, but you have to make sure all of your libraries also use those algorithms. No rational person is going to vendor their entire dependency tree and maintain forks of the entire universe to swap `crypto/tls` and `net/http`. Well, some of these contracts are big enough to justify it, but whew, what a waste.

The FIPS compliant Go builds from Microsoft and now Go 1.24 make it a lot easier to check that box and unless a package implemented their own TLS stack it's easy to attest that the software uses FIPS validated crypto modules. Without that, good luck trying to sell to gov and highly regulated institutions in financial and health.


Wouldn't declaring the "replace" directive in go.mod once take effect for all the dependencies?


Oh that's an interesting question, I've never tried to build a binary with "replace"-ing one of the builtin packages.

Maybe that works? But many of the standard library packages use linker shenanigans, if I recall, like //go:linkname pragmas. Maybe that's an issue, maybe not?

It would be interesting if the fork was unnecessary and it was possible to implement FIPS via package replacements! That would be a lot simpler.


"replace" is an operation on modules. Networking is part of the standard library, which is a single (very special) module. Even if you could "replace" std, it would not really be less than creating a fork.


"Is there a reason that a better package requires a fork of the entire runtime rather than just, say, a normal Go package?"

I think at the time that would have been the only way to make it so any in-the-wild 3rd party code you want to use would use the FIPS-compliant libraries anytime someone imported "crypto/whatever" from the standard library.

I haven't tested the workspaces functionality [1] to see if it allows you to override standard library functionality, but in principle something either very like that, or slightly tweaked, would be enough that you could just use standard Go with a particular text file dropped into place and some libraries to override the standard library now.

But yeah, if you didn't even know this fork existed, you're not in the target audience. tptacek or someone else who really knows their stuff can Cunningham's Law me if I'm wrong, but my impression is that FIPS has a track record of rigidly demanding very medium levels of security, possibly including some rigidly poor security choices, and if you don't have a need to be in compliance, you can and should do much better by using newer and better options than what it mandates.

[1]: https://go.dev/doc/tutorial/workspaces


How is this different to Red Hat's process of using OpenSSL instead of Go's crypto libraries? That's how they've been doing it for quite a while - https://developers.redhat.com/blog/2019/06/24/go-and-fips-14...


Is this used anywhere outside of Azure?


Please, does this make it possible for me to send an email from Outlook to GMail encrypted using US government PKI?


"We evaluated changing Microsoft Go to use the new Go FIPS module rather than system libraries. However, we ultimately determined that this approach doesn’t align with Microsoft internal cryptography strategy and policies."

Any good modern conspiracy theories about Windows system libraries for cryptography?


Although auditing rules have been loosened up in various respects, ultimately whenever code within the FIPS module boundary changes a new validation and certification process is supposed to be kicked off and tracked. For Microsoft itself it's obviously more convenient to manage 1 module rather than 2. But more importantly, many Microsoft customers depend on Windows providing compliant and certified cryptographic modules; they don't have to worry about it, period, except to keep their Windows installations updated. With built-in Go modules, that now becomes the problem of every individual organization. It's nowhere near as bad as 5+ years ago, when auditors were more strict about only using certified binary modules, which meant you often faced a Sophie's Choice when it came to bug fixes. Today the bar is more that you're using a code base that has been certified (i.e. built some binary that was certified), and when bug fixes are made will quickly be re-certified (in the interim you'll get forbearance). But it's still a greater process and change management burden than when you're just consuming a certified system library from a vendor who takes 100% responsibility for keeping it in a certified state, and which can be updated independently, without having to rebuild all your software.

While rebuilding your fleet of Go apps may be trivial in a technical sense, organizing and tracking deployment across an enterprise is less trivial. Tracking that your nodes are all running updated versions of Windows isn't trivial, either, but much easier.

FIPS is a PITA largely because of the change management burden. But that's precisely one of the biggest gaps in enterprise security. Keeping most of your installations up-to-date is easy; it's the long tail of stragglers and misfits that is the most difficult part. In that light, quibbling about algorithms is almost like bike shedding, though it's difficult to overestimate how much bad crypto is out there (see, e.g., last year's Okta bcrypt issue that is making the rounds again on HN). When people complain about having to use ECDSA P-256 instead Ed25519[1], I want to roll my eyes.

[1] Ed25519 finally became FIPS compliant only last year, there aren't many (any?) certified implementations, and in any event P-256 is just much more widely supported, especially in niches like HSMs, etc.


I've been using Go for about 10 years and this the first time I've heard of "Microsoft Go"


Author here. Microsoft is a soft Go fork mostly for internal Microsoft needs, but some projects outside of Microsoft use it as well due to it's good FIPS 140 story. I expect some of these users to switch back to Google's Go now that it will also ship with a FIPS-140 crypto stack.


Any plans to use it for the managed azure istio so that can be used in FEDRAMP environments?


out of curiosity: what problems do you solve with this fork at Microsoft and why not C# ?


Also not to be confused with Microsoft Surface Go: https://en.m.wikipedia.org/wiki/Surface_Go


"What the heck is Microsoft Go?"

> This repository produces a modified version of Go that can be used to build FIPS 140-2 compliant applications. Our goal is to share this implementation with others in the Go community who have the same requirement, and to merge this capability into upstream Go as soon as possible.

It is also the default 'golang' package on Azure Linux 3.0.

Microsoft Go fork: https://github.com/microsoft/go

Issue discussing FIPS implementation: https://github.com/golang/go/issues/69536


Is Azure Linux 3.0 a rebranding of CBL-mariner



Sort of... AzureLinux is a rebranding from CBL-Mariner.

But 3.0 is an actual new version of the distro with newer packages (like going from Ubuntu 22.04 to 24.04, as an example).




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: