
Login.gov encryption is badly designed - sdrapkin
https://gist.github.com/sdrapkin/92836da1d82d45df664460361f1fa943
======
sillysaurus3
Scrypt isn't badly designd. It's also difficult to misuse.

This is like saying "bcrypt is badly designed."

Note that you are specifically attacking scrypt with the title -- "login.gov
encryption" can be substituted with "scrypt."

If you were to say it's illegal for them to be using scrypt since scrypt is
not an approved KDF, that would carry more weight.

 _Cryptographic flaws

1\. scrypt is used as password-based KDF, which violates NIST 140-2_

This isn't a cryptographic flaw! The phrase "cryptographic flaw" means
something.

 _5\. hash(E) is stored right next to the ciphertext from (4). Who thought
that storing a hash of the encryption key right next to PII ciphertext
encrypted with that key was a good idea?_

Storing the hash of an encryption key is fine, as long as the hash function is
strong.

It's frustrating that a government website is making solid cryptographic
choices and then being lampooned like this. It would be far more productive to
make scrypt an approved NIST KDF.

~~~
microcolonel
If anything, this is an argument to expand FIPS, not an argument to
deauthorize login.gov.

------
agl
This is mostly complaining about a lack of FIPS 140 compliance. While that
might be a regulatory issue for a .gov site, technically-speaking FIPS
compliance is a hinderance to building a sound system, not an aid.

Putting that aside, there might be some valid points in here: using Hash(IKM +
nonce) to generate a key is probably not ideal, depending on what Hash is.
That's generally a job for HKDF. The post also mentions a "non-approved KDF"
elsewhere, but doesn't say what it is.

On the other hand, storing Hash(key) isn't immediately an issue unless
something else in the scheme depends on Hash(key) being secret, but the post
implies without justification that it's some sort of obvious error.

So there might well be some issues here, but this post doesn't provide
sufficient detail to condemn login.gov out of hand.

~~~
zxcmx
FIPS compliance is honestly THE WORST.

This is a butchered version of my standard write-up for customers who have
customers who ask about FIPS.

FIPS is really an unsuitable way to evaluate the security of large or complex
systems. The major cloud vendors who claim to be FIPS compliant do so by
describing one key part of their system as FIPS compliant (e.g. their VPN
technology, for Azure, and SSL termination for AWS), and then proudly
displaying a compliance badge on their website. It is more or less impossible
to make a modern cloud system completely FIPS compliant, and it is a waste of
time to try. Organizations asking for FIPS compliance seem perfectly happy as
long as one or two key parts are compliant.

Usually, the simplest FIPS compliance goal is to target the transfer of <key
data> over the Internet. That will satisfy most customers.

Actually it is a bit worse than that, because your customers will need to do
some work on their side, and based on a realistic profile of customers who
enquire about FIPs compliance, they are extremely unlikely to undertake that
effort. So the key thing is to be "FIPS ready". More on this shortly.

DEFINITIONS

FIPS - This is actually a broad range of standards. In the context of
security, most people mean FIPS 140-2 - "Security Requirements for
Cryptographic Modules".

* FIPS Certified: If you create cryptographic modules, you can have them certified as compliant by an accredited lab. This costs a lot of money. There is an official list of all FIPS certified cryptographic modules.

* FIPS "Level" \- There are 4 levels. Software can really only ever be level 1. Levels 2+ start talking about features only possible in hardware, such as tamper evident seals.

* FIPS Compliant - If your product uses only FIPS certified cryptographic modules and FIPS approved algorithms for all cryptographic operations, it is FIPS compliant.

* FIPS Ready - This is a "made-up term", but it sounds good. It's a way to express "Our software can be compliant, but you need to do some things which we can't do for you".

FIPS ON THE CLIENT

Windows is only compliant if it is operating in "FIPS mode". Obviously, you
can't turn that on for your customers, they need to do it themselves. See:
Enabling FIPS compliant algorithms in Windows. Note that enabling FIPS mode
will often break a lot of things (e.g. TLS connections to some web sites,
inter-operation between different versions of Windows and so on). Also, it
will actually tend to weaken security. This is because the FIPs approved
algorithm list is several years old which means that the system is forced to
use ciphers which are weaker than modern defaults. Furthermore, FIPS-certified
code can't, if you read carefully, be patched without re-certification.

FIPS MODE, IN GENERAL

Most vendors meet the requirements of FIPS by providing a specific, certified
"mode" in which the system is compliant. Why? Well, when a software
cryptographic module is FIPS certified, the certification just applies to that
exact version. If a single byte changes in that software module, it isn't
certified any more. Naturally, vendors want to keep improving their software.
So they keep the old, certified code around and only activate it in FIPS mode.
Also, in FIPS mode, the software must perform time-consuming self-tests every
boot (ok, that is not that bad).

It is really an untenable situation for software. Here's a great write-up of
the software certification process from a member of the Oracle Solaris team:
Is FIPS 140-2 Actively harmful to software?.

[https://blogs.oracle.com/darren/is-fips-140-2-actively-
harmf...](https://blogs.oracle.com/darren/is-fips-140-2-actively-harmful-to-
software)

The engineer (an architect on the Solaris crypto team) writes:

So should I run Solaris 11 with FIPS 140-2 mode enabled ? - My personal
opinion is that unless you have a very hard requirement to do so I wouldn't
...

And then, regarding patching:

So what we do we do in Solaris ? We make the bug fixes and and new non FIPS
140-2 relevant algorithms (such as Camellia) anyway because most of our
customers don't care about FIPS 140-2 and even many of those that do they only
care to "tick the box" that the vendor has completed the validation.

FIPS IN THE CLOUD

Given the difficulties with FIPS mode for just operating systems vendors, you
can see that operating an entire cloud service using FIPS-certified
cryptographic modules is going to be extremely difficult.

You will need to think about OpenSSL, any database encryption code, OpenSSH,
NSS, PAM, password hashing and all sorts of other services which may or may
not do encryption.

Various compliance schemes often allow you to have unencrypted transfers
within certain trust boundaries. Ironically this can mean that the quickest
path to compliance is logically to turn off any encryption which your
regulators do not strictly force you to use. Because FIPS doesn't say what to
encrypt, it just says how to do it - if you do!

FIPS AND AMAZON

Then you have to ask: Wait, is Amazon itself "FIPS compliant"? For example,
when I send data to and from Amazon S3, will the SSL be protected with FIPS
compliant algorithms and are they using FIPS certified cryptographic modules?

Amazon do claim to have a FIPs mode, but only in Govcloud. As far as I can
tell, they claim to be FIPS 140-2 compliant by virtue of using FIPS-compliant
TLS on their endpoints.

RECOMMENDED COMPLIANCE STATEMENT AND POSITION

The reality is that customers tend to think of "FIPS compliance" as a check in
the box. A binary state - is it compliant or certified, or is it not?

This view makes sense for a chip or a software library. However, when we talk
about a large system with many moving parts, it is not strictly clear what
"FIPS compliant" even means anymore. Different vendors seem to solve this
problem in different ways:

\- Operating systems vendors achieve compliance by having a "special mode"
which no-one in their right mind ever turns on.

\- Amazon claim they achieve compliance by providing "FIPS compliant" SSL on
their endpoints.

\- Azure claim they are FIPs compliant because "Azure uses Microsoft
cryptographic modules in the validated list published by NIST, enabling
customers to configure and use Azure Virtual Network services in a way that
helps meet their information encryption requirements."

\- Rackspace and Google Cloud, as far as I can tell, do not even try.

It is pretty clear that the cloud vendor claims are just pandering to the
"rubber stamp" mentality of customers, and proudly displaying "FIPS
compliance" by ensuring that say, some key aspect of their system is certified
or compliant (not the entire system from end to end).

This mostly works because customers who are looking for rubber stamp
compliance neither care enough nor know enough to question the veracity of
claims.

SUGGESTED COMPLIANCE STATEMENT

The software we deliver to you (XYZ & ABC) is FIPS ready. To achieve FIPS
140-2 Level 1 compliance, you need to operate your systems in FIPs mode via
Windows Group Policy. When systems running ABC SOFT are in FIPs mode, all
<sensitive data for your regulatory domain> transmitted to and from our
systems will be protected using FIPS 140-2 approved encryption algorithms.

<context is operator providing a web service on AWS with mostly windows
clients>

DELIBERATE WEASELINESS

Of course that statement is weaselly. The only thing you can promise is that
you're gonna use FIPS compliant TLS, and even that only really works right if
the customer configures their stuff in the right way and your cloud supports
it.

The minute anyone opens their eyes to the broader scope of things, of course
the system as a whole is not going to be "FIPS compliant" because there is a
ton of crypto required behind the scenes to get software systems to work and
NONE OF THAT IS FIPS COMPLIANT.

~~~
djrogers
Side note - please don’t use a code block for lists like that. It is
unreadable on any screen narrower than the length of the lines, and there are
no line wraps.

------
fivre
This is a rather sensational title for an article that amounts to "Login.gov
does not use FIPS 140-2-compliant cryptography". Its main argument (aside from
point 5) appears to be that scrypt is used in multiple locations, without
passing judgement on scrypt itself.

Given that this is a US government-run system, this is still a compliance
problem, but that's a different issue.

------
zaroth
I opened an issue on their bug tracker a couple days ago because I had more
fundamental questions about how their algorithm was designed.

HN comment:
[https://news.ycombinator.com/item?id=15204989](https://news.ycombinator.com/item?id=15204989)

Github Issue: [https://github.com/18F/identity-
idp/issues/1665](https://github.com/18F/identity-idp/issues/1665)

Now I may be misunderstanding their implementation, but it seems to me
actually worse than "this isn't FIPS 140". I take no issue with their use of
scrypt at all. The complaints in this Gist actually seem to miss the mark to
me.

The problem isn't scrypt, or storing a hash. The real problem is storing _d_
which, seems to me, defeats the purpose of using an HSM in the first place!

Again, with the disclaimer that I'm not 100% certain that's what they're
doing, it's just what the documentation says, and what it seems like is
happening from reading the Ruby code. I don't develop in Ruby, but while the
language is fairly easy to read, with all their variables named
'encryption_code', 'encryption_key', 'encrypted_key', 'encrypted_code', etc.
it's easy to get lost.

EDIT: Can someone please co-validate my analysis please? Or please tell me
what I got wrong! From what I can see, the design is obviously broken. I don't
consider myself qualified to find flaws in other people's crypto so, when I
find obvious flaws in what should be well designed crypto I get a little
freaked out.

~~~
aaronbwebber
EDIT: OK, I think I see what's wrong with this analysis:
[https://github.com/18F/identity-
idp/blob/master/spec/service...](https://github.com/18F/identity-
idp/blob/master/spec/service..). They do include Z1 in the data they pass to
KMS decrypt. This is because they have XORed the ciphertext with Z1 - so now
in order to recover the initial ciphertext back (i.e. the cipher text you can
decrypt with KMS to get R back), you need to XOR with Z1 again. So even if you
get D from the database, you can't decrypt it unless you have Z1, and if you
were trying to brute-force it, you would need to call KMS for every attempt
with the Z1 for this attempt.

Original comment:

I am not any kind of crypto expert. But I agree with you.

I think they should be XORing with "AssignedSecret" (not
"EncryptedAssignedSecret"). Then in order to compare password hashes you would
need to decrypt the "EncryptedAssignedSecret" using KMS. (using the
terminology in the description of the algorithm here:
[https://github.com/18F/identity-
idp/blob/master/docs/encrypt...](https://github.com/18F/identity-
idp/blob/master/docs/encryption-and-key-rotation.md)) (EDIT: you actually
cover this approach in the GH issue, and point out a problem with it).

I think there is another approach like what the OP proposed where they should
be using some portion of the scrypt hash (either Z1 or Z2 or just the whole
thing) as part of the encryption context passed to KMS. But this seems a
little more complicated to me. (EDIT: You also mention this as a possible
solution in the GH issue).

I think there's also an approach using the GenerateDataKey API :
[http://docs.aws.amazon.com/kms/latest/APIReference/API_Gener...](http://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)

Where you get the key and the key's cipher text back from KMS and store _that_
, and then you have to use KMS to decrypt whatever you encrypted with the key.

~~~
zaroth
Yes, you need to know the password to decrypt. That's the basis of their very
interesting PII protection scheme!

My point is you can brute-force the password without the HSM. And their docs
specifically say this should not be possible. Isn't the whole point of the HSM
to prevent that?

'hash' is derived from 'z2' and 'd' \- and they give you 'd'. Password will
produce 'z2'. So that's the brute-force attack.

To say it another way, the 'z1' path is secured. But there is the 'z2' path
and it's wide open.

~~~
dreae
I've left a comment on your github issue, but the tl;dr is that the encryption
document doesn't seem to reflect the code. The comment in the ruby test case
suggests that the actual step is 'E = hash( Z2 + R )' instead of 'E = hash( Z2
+ D )' where 'R' is the user's randomly generated 'AssignedKey' and 'D' is the
masked HSM ciphertext 'KMS(R) ^ Z2'.

Perhaps somewhere during implementation someone realized the document doesn't
make sense as written.

------
justonepost
I don't think "NIST" approved is that compelling of an argument.

If the author wishes to identify known vulnerabilities, that would be
interesting.

FIPS has some various issues that actually increase vulnerability and not
decrease it. Eg, FIPS approved OpenSSL was always an anchor that caused more
problems than it solved.

~~~
alaithea
The OP seems to misunderstand the function of NIST, as well. NIST does not
"approve" other agencies' software systems. NIST is a standards-setting
organization only. They create and publish standards, but do not enforce them.

~~~
sdrapkin
The OP is referring to the OP-linked 18F writeup (you might want to read it),
which says "Based on consultation with NIST we follow these steps..."

------
tptacek
While there is some weird design in Login.gov, this particular report is
mostly generating giggles among crypto engineers I know.

~~~
SAI_Peregrinus
You mean to say that the outdated requirements of FIPS-140-2 aren't the best
practices for designing a crypto system? That the lack of TMTO attack
resistance in PBKDF2 makes it a sub-optimal choice for storing passwords?
Surely not! NIST would never recommend anything but the strongest
cryptography!

------
baoha
What an immature analysis with click-bait title, I was expecting something big
to read and it turns out he was just not happy about the site doesn't comply
to NIST, and using scrypt is a _flaw_? Seriously?

------
microcolonel
Also note: scrypt ends with a PBKDF2 round, so if PBKDF2 is acceptable then
scrypt may not actually be a problem. Legally speaking you might be able to
ignore the use of the SMIX (including Salsa20) and the HMAC entirely as long
as the final PBKDF2 uses a FIPS 140-2 acceptable hash function.

~~~
sdrapkin
"OMG, you're totally right - if only the OP knew that scrypt ends with
pbkdf2.."

Um, no. But thanks for playing. For those who wish to argue that everything
that precedes PBKDF2 in scrypt should be considered as "key extraction", you
should read NIST SP800-56c, also referenced by FIPS-140-2 Annex-D (tldr:
scrypt does not fly). Welcome to USG infosec compliance.

------
surfmike
Can anyone explain why scrypt would be inadequate or flawed?

~~~
tptacek
It's not.

------
patcheudor
Hey, at least their transport security gets an A+ from SSL Labs. Honestly, I
still find a lot of government sites, particularly state governments that get
F's because they are still using SSL and 56 bit ciphers.

[https://www.ssllabs.com/ssltest/analyze.html?d=login.gov&lat...](https://www.ssllabs.com/ssltest/analyze.html?d=login.gov&latest)

------
trapperkeeper74
The construction seems bad, but FIPS isn't anywhere close to being as good as
NACL, and scrypt isn't the enemy. Bad constructions, lack of nuance and faith
in certifications are the enemies.

~~~
technion
It's worth noting the author is elsewhere critical of libsodium.

------
tedunangst
Am I the only person who suspects this is a work of performance art?

------
ondrae
Ouch

------
colejohnson66
Is anyone really surprised?

~~~
smt88
If your implication is that 18F has the same reputation as past Web-related
efforts in the federal government, you may need to look into 18F more closely.

It's only 3 years old and was specifically intended to fix all of those
stereotypes and make the government software production efforts more similar
to those in Silicon Valley.

