Sunday, May 18, 2008

Debian OpenSSL bug

A huge security hole has been discovered in the Debian OpenSSL and OpenSSH packages:
http://it.slashdot.org/article.pl?sid=08/05/13/1533212
Introduction:
Modern-day cryptography relies on computer-generated, random encryption keys. Random keys are used everywhere - from generation of public/private key pairs, signatures and certificates, all way to basic login onto ssl or ssh server, when you enter password - the Diffie-Hellman key exchange is used to negotiate random encryption key.

It is absolutely crucial that the "random numbers" are hard for attacker to guess. Normally, the keys have insanely high number of possibilities, in the billion billion billion billion billion billion possibilities range. But in Debian Linux (and anything Debian-based, e.g. Ubuntu), for almost *2 years*, it had only 32 thousands possible keys (per every architecture). That could be cracked with WW2-era hardware. Enigma machine was more secure than that!

Now, how and why this happened?

Theres original conversation from when the bug was introduced:
http://marc.info/?l=openssl-dev&m=114651085826293&w=2

There was 2 "MD_Update(&m,buf,j);" lines commented out in 2 functions.

static void ssleay_rand_add(const void *buf, int num, double add)
...
MD_Update(&m,buf,j);
...
(which was the only place in the function that made use of "buf")

and

static int ssleay_rand_bytes(unsigned char *buf, int num)
....
#ifndef PURIFY
MD_Update(&m,buf,j); /* purify complains */
#endif
...

The first function, ssleay_rand_add, adds the input data into the "entropy pool". It is used to add bytes from /dev/[u]random and from various events such as mouse motion etc. The buff parameter is input-only, named "const void *buf" . And this MD_Update is the only place where it reads from buff. So commenting out almost entirely disabled the random number genration.

Second function outputs random numbers into buff (its output parameter); nonetheless, it does read content of the buff to enhance randomness. This is not very good thing to do as it confuses some debuggers.
Hence, there is
#ifndef PURIFY
#endif
block around it, allowing you to use -DPURIFY if you want to improve debugging.

Rather than using common sense, "dont mess with other people's code unless you have to" and using -DPURIFY , which is *the official way of dealing with problem* , Kurt comments out that line. And more, he searches for anything similar and comments the other one out too!

He does take the time to ask the SSL team about the change, just posting the line numbers, no context, no even function declarations. Just an overly long blabla text. What kind of manners is that? Developer is supposed to open files, go to those lines, and look? Note that he's *not* submitting proper patch asking for it to be accepted. Keep in mind that Debian is just one distribution out of many.
He doesnt take the time to look at the code (and is not a competent programmer); the const in "const void *buf" means that buf is input, "read-only" parameter, and is obviously here for something useful.

Now the fix. It is still very moronic: rather than simply removing the breaking patch and sticking to official openssl without custom changes (maybe using -DPURIFY when compiling) , only the first line is uncommented. WTF. The original break was moronic, the solution was moronic too.

This is just tip of big iceberg. Linux distro maintainers (read: largely, incompetent programmers and n00bs, wannabe elite hackers) do "fixes" in the code that they absolutely do not understand. Being n00bs, they don't properly submit patches to real developers (not that it would help for those "fixes" which are crap and are not accepted anyway). It also highlights the possibility of planting backdoors into open source code. When simple comment out like this remains undetected for almost 2 years, a cleverly hidden backdoor may remain undetected forever.

The advice is: If security is important to you, *stay away from distro packages*. The OpenSSL package in your distro is not OpenSSL. It is a fork of OpenSSL. Which may contain ANY sort of shit, all way from idiocy to clever, deliberate backdoors.

Also, general comment on OpenSSL code. It is over-complicated, and code quality looks bad. There is a lot of room for hidden backdoors.