Behind iPhone's Critical Security Bug, a Single Bad 'Goto'

Like everything else on the iPhone, the critical crypto flaw announced in iOS 7 yesterday turns out to be a study in simplicity and elegant design: a single spurious "goto" in one part of Apple's authentication code that accidentally bypasses the rest of it.
MG7466edit660x440
Photo: Ariel Zambelich/WIRED

Like everything else on the iPhone, the critical crypto flaw announced in iOS 7 yesterday turns out to be a study in simplicity and elegant design: a single spurious "goto" in one part of Apple's authentication code that accidentally bypasses the rest of it.

Apple released iOS 7.0.6 yesterday to patch the bug in its implementation of SSL encryption -- the internet's standard defense against eavesdropping and web hijacking. The bug essentially means that when you're e-mailing, tweeting, using Facebook or checking your bank account from a shared network, like a public Wi-Fi or anything tapped by the NSA, an attacker could be listening in, or even maliciously modifying what goes to your iPhone or iPad.

But the terse description in Apple's announcement yesterday had some of the internet's top crypto experts wondering aloud about the exact nature of the bug. Then, as they began learning the details privately, they retreated into what might be described as stunned silence. "Ok, I know what the Apple bug is," tweeted Matthew Green, a cryptography professor at Johns Hopkins. "And it is bad. Really bad."

By this morning, the details had surfaced on Hacker News, and Adam Langley, a web encryption expert at Google, posted a detailed breakdown of the bug based on his reading of Apple's published source code.

Some software bugs are infinitely subtle and complicated. Others are comprehensible almost at a glance to anyone who dabbled in BASIC as a kid. The iOS 7 bug is in the latter group.
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,                                  uint8_t *signature, UInt16 signatureLen) { 	OSStatus        err; 	...  	if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) 		goto fail; 	if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) 		goto fail; 		goto fail; 	if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) 		goto fail; 	...  fail: 	SSLFreeBuffer(signedHashes); 	SSLFreeBuffer(hashCtx); 	return err; }

Did you see it? This function is called when a iPhone connects to an encrypted site over SSL: it's meant to verify that the encryption key is being vouched for -- digitally signed -- by the operator of the website.

But notice the two "goto fail" lines, one after the other. The first one belongs there. The second is a typo. That extra, duplicative line diverts the program's execution, like a bypass stent, right past a critical authentication check. The part where the digital signature is actually checked is dead code, never reached.

The issue, Langley confirms, is indeed fixed in the new iOS 7.0.6 (which you should install, if you're using iOS 7.) An update to iOS 6 pushed yesterday fixes the bug there as well. Reportedly, OS X 10.9.1 is still affected by the vulnerability.

Using "goto" statements in any form has long been considered a poor programming practice, though everyone does it anyway.

The breathtaking simplicity of what's already being called #gotofail is spawning Snowden Era speculation that the bug was no accident at all. Google's Langley is having none of that.

"I believe that it's just a mistake, he writes, "and I feel very bad for whomever might have slipped in an editor and created it."

You can test if you're vulnerable at GotoFail.com.