{"id":572,"date":"2006-09-11T08:29:09","date_gmt":"2006-09-11T16:29:09","guid":{"rendered":"\/?p=572"},"modified":"2006-09-11T08:29:09","modified_gmt":"2006-09-11T16:29:09","slug":"openssl-vulnerability","status":"publish","type":"post","link":"https:\/\/www.identityblog.com\/?p=572","title":{"rendered":"Openssl vulnerability"},"content":{"rendered":"<p><a href=\"http:\/\/www.links.org\/?p=139\">Ben Laurie<\/a> and <a href=\"http:\/\/www.matasano.com\/log\/469\/many-rsa-signatures-may-be-forgeable-in-openssl-and-elsewhere\/\" class=\"broken_link\">Matasano Chargen<\/a> describe a significant&nbsp;attack on RSA signature implementation (not the algorithm itself).&nbsp; Quoting from Matasano:<\/p>\n<blockquote><p>Bell Labs crypto shaolin <a href=\"http:\/\/www.bell-labs.com\/user\/bleichen\/bib.html\" class=\"broken_link\"><font color=\"#ff7800\">Daniel Bleichenbacher<\/font><\/a> disclosed a freaky attack on RSA signature implementations that may, under some common circumstances, break SSL\/TLS.<\/p>\n<p>Do I have your attention? Good, because this involves PKCS padding, which is not exciting. Bear with me.<\/p>\n<p>RSA signatures use a public signing keypair with a message digest (like SHA1) to stamp a document or protocol message. In RSA, signing and verification are analogs of decryption and encryption. To sign a message, you:<\/p>\n<ol>\n<li>Hash it<\/li>\n<li>Expand the (<em>short<\/em>) hash to the (<em>long<\/em>) size of the RSA modulus<\/li>\n<li>Convert that expansion to a number<\/li>\n<li>RSA <em>decrypt<\/em> the number<\/li>\n<li>Convert that to a series of bytes, which is your signature.<\/li>\n<\/ol>\n<p>It\u00e2\u20ac\u2122s step 2 we care about here. It\u00e2\u20ac\u2122s called \u00e2\u20ac\u0153padding\u00e2\u20ac\u009d. You need it because RSA wants to encrypt or decrypt something that is the same size as the RSA key modulus.<\/p>\n<p>There are a bunch of different ways to pad data before operating on it, but the one everyone uses is called PKCS#1 v1.5 (<em>technically, <a href=\"http:\/\/tools.ietf.org\/html\/rfc3447\"><font color=\"#ff7800\">EMSA-PKCS1-V1_5-ENCODE<\/font><\/a><\/em>). It involves tacking a bunch of data in front of your hash, enough to pad it out to the size of the modulus:<\/p>\n<p><img id=\"image472\" alt=\"pkcs-s.png\" src=\"\/wp-content\/images\/2006\/09\/pkcs-s.png\" \/><\/p>\n<p>Note the order and placement of those boxes. They\u00e2\u20ac\u2122re all variable length. Let\u00e2\u20ac\u2122s call that out:<\/p>\n<p><img id=\"image471\" alt=\"pkcs-b.png\" src=\"\/wp-content\/images\/2006\/09\/pkcs-b.png\" \/><\/p>\n<p>The two big goals of a padding scheme are (a) expanding messages to the modulus length and (b) making it easy to <em>correctly<\/em> recover the message bytes later, regardless of what they are. This padding scheme is designed to make that straightforward. The padding bytes are clearly marked (<em>\u00e2\u20ac\u015300 01\u00e2\u20ac\u009d, which tells you that PKCS#1 v1.5 is in use<\/em>), terminated (<em>with a 00, which cannot occur in the padding<\/em>), and followed by a blob of data with a length field. This whole bundle of data is what RSA works on.<\/p>\n<p>The problem is, despite all the flexiblity PKCS#1 v1.5 gives you, nobody expects you to ever <em>use<\/em> any of it. In fact, a lot of software apparently depends on data being laid out basically like the picture above. But all the metadata in that message gives you other options. For instance:<\/p>\n<p><img id=\"image470\" alt=\"pkcs-a.png\" src=\"\/wp-content\/images\/2006\/09\/pkcs-a.png\" \/><\/p>\n<p>For some RSA implementations, this could be an acceptable message layout. It\u00e2\u20ac\u2122s <em>semantically<\/em> invalid, but can appear <em>syntactically<\/em> valid. And if you don\u00e2\u20ac\u2122t completely unpack and check all the metadata in the signature, well, this can happen:<\/p>\n<ol>\n<li>Determine the padding from the fixed header bytes.<\/li>\n<li>Scan until the terminator.<\/li>\n<li>Scoop out the hash information.<\/li>\n<li>Use the hash to confirm you\u00e2\u20ac\u2122re looking at the same message that the \u00e2\u20ac\u0153signer\u00e2\u20ac\u009d signed.<\/li>\n<li>Use the signature to confirm that a real \u00e2\u20ac\u0153signer\u00e2\u20ac\u009d signed it.<\/li>\n<\/ol>\n<p>The problem is that this attack breaks the connection between (4) and (5). The hash, now \u00e2\u20ac\u0153centered\u00e2\u20ac\u009d instead of \u00e2\u20ac\u0153right-justified\u00e2\u20ac\u009d, doesn\u00e2\u20ac\u2122t really mean anything, because the signature covers a bunch more bits.<\/p>\n<p>This is all trivia without some value for \u00e2\u20ac\u0153evil\u00e2\u20ac\u009d that lets you substitute an arbitrary message hash (and thus an arbitrary message) into an otherwise valid-looking signature. Enter Bleichenbacher\u00e2\u20ac\u2122s attack.<\/p>\n<p>RSA takes parameters, one of which is a \u00e2\u20ac\u0153public exponent\u00e2\u20ac\u009d, which is part of the public key. If that exponent is \u00e2\u20ac\u01533\u00e2\u20ac\u009d, which it often is, an attacker can exploit broken signature validation code to forge messages. The math here, which Bleichenbacher claims is simple enough to do with a pencil and paper, gets a bit hairy for me (I lose it at polynomials). Dino explains it better than I do. The <a href=\"http:\/\/www.cacr.math.uwaterloo.ca\/hac\/\"><font color=\"#ff7800\">long and the short of it is<\/font><\/a>, you validate an RSA signature by computing:<\/p>\n<div style=\"font-size: 1em; background-color: yellow\">s ^ e = m (mod n)<\/div>\n<p>(where \u00e2\u20ac\u0153e\u00e2\u20ac\u009d is the public exponent, \u00e2\u20ac\u0153n\u00e2\u20ac\u009d is the public modulus, and \u00e2\u20ac\u0153s\u00e2\u20ac\u009d is the signature) and verifying that you get the same result as applying steps (1) and (2) from the signature process yourself. But:<\/p>\n<ol>\n<li>If the public exponent is \u00e2\u20ac\u01533\u00e2\u20ac\u009d, and<\/li>\n<li>you inject the right \u00e2\u20ac\u0153evil\u00e2\u20ac\u009d bits into the PKCS data to make it a perfect cube, then<\/li>\n<li><strong>you can create a something that broken RSA will validate.<\/strong><\/li>\n<\/ol>\n<p>Good technical details in <a href=\"http:\/\/www.imc.org\/ietf-openpgp\/mail-archive\/msg14307.html\" class=\"broken_link\"><font color=\"#ff7800\">Hal Finney\u00e2\u20ac\u2122s OpenPGP post<\/font><\/a> (OpenPGP is not vulnerable). And a security <a href=\"http:\/\/www.openssl.org\/news\/secadv_20060905.txt\"><font color=\"#ff7800\">advisory for OpenSSL<\/font><\/a> (<strong>OpenSSL is vulnerable, through 0.9.8b<\/strong>).<\/p>\n<p>Two things have gone wrong here:<\/p>\n<ol>\n<li>Implementations misparse signatures, assuming that a syntactically valid-looking hash is semantically operative.<\/li>\n<li>For the common RSA exponent parameter \u00e2\u20ac\u01533\u00e2\u20ac\u009d, there\u00e2\u20ac\u2122s a straightforward way to manipulate a bogus signature to make it look valid.<\/li>\n<\/ol>\n<p>My understanding is, the demonstrated attack sticks the evil bits outside of the DigestInfo (the hash data). The way I see the bug being described, broken implementations are just scanning the buffer without \u00e2\u20ac\u0153fully decoding it\u00e2\u20ac\u009d, implying that if they just validated the ASN.1 metadata against the signature buffer they\u00e2\u20ac\u2122d be OK. That may be true, but it seems possible that a blind \u00e2\u20ac\u0153memcmp\u00e2\u20ac\u009d on an over-long SHA1 octet string, which would be ASN.1-valid and leave the Digest at the end of the buffer, could also trigger the same bug.<\/p>\n<p>This is only a problem if:<\/p>\n<ol>\n<li>You\u00e2\u20ac\u2122re running broken code<\/li>\n<li>You\u00e2\u20ac\u2122re relying on certificate validation<\/li>\n<li>The certificates you\u00e2\u20ac\u2122re validating use an exponent of \u00e2\u20ac\u01533\u00e2\u20ac\u009d<\/li>\n<\/ol>\n<p>Unfortunately, although the default for OpenSSL is \u00e2\u20ac\u015365537\u00e2\u20ac\u009d (no practical attack known for that), \u00e2\u20ac\u01533\u00e2\u20ac\u009d is common alternative: it\u00e2\u20ac\u2122s faster, especially in embedded environments. Ferguson and Schneier recommend it in <a href=\"http:\/\/www.schneier.com\/book-practical.html\"><font color=\"#ff7800\">Practical Cryptography<\/font><\/a>. Checking the CA bundle for \u00e2\u20ac\u0153curl\u00e2\u20ac\u009d:<\/p>\n<div style=\"font-size: 1em; background-color: yellow\">cat curl-ca-bundle.crt | grep Exponent | grep &#8220;: 3&#8221; | wc -l<\/div>\n<p>gives 6 hits, from Digital Signature Trust Co. and Entrust.net. Those same certs are in Firefox. Firefox doesn\u00e2\u20ac\u2122t use OpenSSL; it uses NSS, and I don\u00e2\u20ac\u2122t know if NSS is vulnerable. <a href=\"http:\/\/cvs.mozilla.org\/security\/src\/security\/nss\/lib\/cryptohi\/sevfy.c#42\" class=\"broken_link\"><font color=\"#ff7800\">Here\u00e2\u20ac\u2122s the code<\/font><\/a>. I see it extracting a SHA1 hash\u00e2\u20ac\u2122s worth of data, and don\u00e2\u20ac\u2122t see it checking to make sure that date exhausts the buffer, but I don\u00e2\u20ac\u2122t know the code well. Safari also depends on OpenSSL.<\/p>\n<p><strong>Correct me on any of these points and I\u00e2\u20ac\u2122ll amend the post<\/strong>. I haven\u00e2\u20ac\u2122t tested this (although Google Security did a proof of concept against OpenSSL that precipitated the advisory).<\/p>\n<p>You should upgrade to the most recent OpenSSL. Bleichenbacher also recommended people stop using signing keys with a \u00e2\u20ac\u01533\u00e2\u20ac\u009d exponent.<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Freaky attack on RSA signature implementations that may, under some common circumstances, break SSL\/TLS.<\/p>\n","protected":false},"author":68,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,13],"tags":[],"_links":{"self":[{"href":"https:\/\/www.identityblog.com\/index.php?rest_route=\/wp\/v2\/posts\/572"}],"collection":[{"href":"https:\/\/www.identityblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.identityblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.identityblog.com\/index.php?rest_route=\/wp\/v2\/users\/68"}],"replies":[{"embeddable":true,"href":"https:\/\/www.identityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=572"}],"version-history":[{"count":0,"href":"https:\/\/www.identityblog.com\/index.php?rest_route=\/wp\/v2\/posts\/572\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.identityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.identityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.identityblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}