The un-fun work of making Postgres FIPS compliant

In today’s episode 94 of “5mins of Postgres”, we’ll walk through Postgres and FIPS. We’ll explain what the FIPS mode is, where it is required, how the MD5 algorithm presents issues, and more.

Share this episode: Click here to share this episode on LinkedIn or on twitter. Feel free to sign up for our newsletter and subscribe to our YouTube channel.


Postgres and FIPS mode

This is a blog post by Peter Eisentraut. In it, he talks about the work that he's done in Postgres upstream to make sure that Postgres is FIPS compatible.

What is FIPS mode?

What do we mean when we say FIPS or F I P S? It's the Federal Information Processing Standard that's defined by the NIST Standards Institute in the US. This is a very US centric term that you will need if you are supplying services to the US government where they might have requirements that say "needs to be FIPS compliant" so that you can actually operate particular software.

One of the most common things that FIPS contains is that you can't use outdated cryptographic algorithms like MD5. The idea is that when you have software that's FIPS compliant, that software is not allowed to use any of the outdated algorithms so that end users, for example imagine somebody using Postgres as part of some government system, can't accidentally use an MD5 algorithm as part of their logic.

Postgres is not FIPS compliant by default

First of all, as Peter notes, Postgres itself is not really a cryptographic module. It's not itself in scope of what FIPS is trying to do.

But Postgres has cryptographic routines where it will be impacted by what FIPS tries to control. For example, for transport security, you might have SSL or TLS requirements. You might have requirements like using TLS 1.2 or 1.3. Things like that would be powered by a library like OpenSSL when you're using Postgres. There's also other cryptographic operations Postgres does during authentication. For example, for the longest time, Postgres was relying on MD5 for hashing its passwords. Only in the last couple of years we've seen the advancement of SCRAM SHA 256, which is a much more secure password hashing and authentication mechanism.

Additionally, the pgcrypto extension, which is bundled as part of contrib in the main Postgres repository, has cryptographic routines for the use by the application. You can use SQL to call MD5 as a function, for example, so you can imagine that, as mentioned earlier, you might have end users that then rely on this functionality, ultimately causing a problem by violating these standard requirements.

Download Free eBook: How To Get 3x Faster Postgres

OpenSSL and MD5 authentication

First of all, in SSL and TLS, that's mainly a solved problem because you can essentially say: just require new enough TLS versions. On the second note of authentication mechanism, what's interesting here is that starting in Postgres 14, if you build Postgres with OpenSSL, which is the most typical way of building Postgres, then you can actually rely on Postgres to not allow you to use the outdated mechanism, because if you have an OpenSSL that's in FIPS mode and you use OpenSSL with Postgres, then it'll actually prevent MD5 authentication.

MD5 authentication will just fail if you're using your OpenSSL in FIPS mode. Of course, generally speaking, you should migrate to SCRAM SHA 256. That's a much more secure algorithm and clients these days do support that across the board. So there's really no good reason to still be using MD5.


pgcrypto on the other hand is a little bit of an edge case. pgcrypto has a lot of user callable functions and so one of the challenges here is that you could be breaking applications if you're preventing applications from suddenly calling the MD5 method. What Postgres has done historically is that some of pgcrypto was relying on OpenSSL and some of it was using built in logic.

Some of the work that Peter has been doing is to move more of the things in pgcrypto to rely on OpenSSL when building with OpenSSL and then also have functions fail if OpenSSL is in FIPS mode. If you build Postgres with OpenSSL in FIPS mode then pgcrypto MD5 will just fail and not work. Which is good, right? That's what you want!

Passing the Postgres 17 test suite in FIPS mode

The last thing that Peter mentions in his blog post, is that he’s been working on making the internal test suites of Postgres pass when you use OpenSSL in FIPS mode. This helps to validate that Postgres can actually operate in this way, which then makes Postgres more appealing to be used in these kinds of government use cases.

What he's done in the Postgres 17 cycle is to go through a couple of uses of the md5 function in the Postgres source and replace that with sha256. Just making sure that outdated function is no longer used. The good news is that the current Postgres 17 branch has all the remaining changes that allow you to build the Postgres test suite in FIPS mode successfully, which is a great step to making sure that going forward Postgres will remain FIPS compatible.

As Peter notes though, this doesn't necessarily prove anything about the security of Postgres or its implementation. Really, it's just a compliance check mark item.


I was curious also what other people had to say about this, and I think the gist of this is what a Hacker News commenter said here. This is the un-fun work that you need to do to get open source software into different parts of the enterprise and government. It's not fun. It's not even difficult necessarily. It's just the kind of thing that just takes time. Thanks to Peter Eisentraut for making sure that Postgres is FIPS compliant!

If you liked episode 94 of 5mins of Postgres, why not subscribe to our YouTube channel, sign up for our newsletter or follow us on LinkedIn and Twitter to get updates about new episodes?

What we have discussed in this episode of 5mins of Postgres

Enjoy blog posts like this?

Get them once a month to your inbox