{"id":682,"date":"2008-09-15T10:13:04","date_gmt":"2008-09-15T10:13:04","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2008\/09\/15\/modes-of-operation-in-block-cryptography\/"},"modified":"2008-09-15T10:13:04","modified_gmt":"2008-09-15T10:13:04","slug":"modes-of-operation-in-block-cryptography","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2008\/09\/15\/modes-of-operation-in-block-cryptography\/","title":{"rendered":"Modes of Operation in Block Cryptography"},"content":{"rendered":"<p> Sorry for the slow pace of the blog lately. I&#8217;ve been sick with a horrible<br \/>\nsinus infection for the last month, and I&#8217;ve also been particularly busy with work, which have left me with neither the time nor the energy to do the research necessary to put together a decent blog post. After seeing an ENT a couple of days ago, I&#8217;m on a batch of new antibiotics plus some steroids, and together, those <em>should<\/em> knock the infection out.<\/p>\n<p> With that out of the way: we&#8217;re going to look at how to get from simple <a href=\"http:\/\/scientopia.org\/blogs\/goodmath\/2008\/09\/introduction-to-block-ciphers\">block ciphers<\/a> to stream ciphers, using the oh-so-imaginatively named <em>modes of operation<\/em>!<\/p>\n<p> As a quick refresher, block encryption specifies an encryption scheme that operates on fixed-size blocks of bits. In the case of <a href=\"http:\/\/scientopia.org\/blogs\/goodmath\/2008\/09\/des-encryption-part-1-encrypting-the-blocks\">DES<\/a>, that&#8217;s 64 bits. In the<br \/>\nreal world, that&#8217;s not terribly useful on its own. What we want is something called<br \/>\na <em>stream cipher<\/em>: a cipher that&#8217;s usable for messages with arbitrary lengths. The way to get from a block cipher to a stream cipher is by defining<br \/>\nsome mechanism for taking an arbitrary-sized message, and describing how to break it into blocks, and how to connect those blocks together.<\/p>\n<p><p> <em>Modes of operation<\/em> are formal descriptions of the way that you<br \/>\nuse block encryption on a message that&#8217;s larger than a single block. Modes of operation (MOOs) are critical in making effective use of a block cipher. Of course, there&#8217;s always a tradeoff in things like this: you have to choose what properties of your encrypted communication you want to protect. Particularly for DES encryption, the standard MOOs can provide <em>confidentiality<\/em> (making sure that no one can read your encrypted communication), or integrity (making sure that your communication isn&#8217;t altered during transmission), but not both.<\/p>\n<p><!--more--><\/p>\n<p>  To give you a quick and foolishly simple example of that tradeoff, we can consider a real-life example of a simple mode of operation, called the electronic codebook (ECB). In the ECB MoM, you encrypt each block separately, and then just concatenate the results together. Everyone who does crypto knows that ECB is incredibly stupid; no one seriously uses it. The only case I recall hearing of anyone actually using ECB was a multiplayer online role-playing game,<br \/>\nwhere they encrypted the traffic between players and the game server using ECB.<br \/>\nSo every time the player did something, it sent a message to the server, and the server sent back a message telling it how to respond.<\/p>\n<p> For performance reasons, games like this tend to do a lot of stuff on the<br \/>\nplayer&#8217;s computer. So, for example, when a player gets into a fight with a monster,<br \/>\nthe fight was mostly handled on the players computer, and when it was over, it sent<br \/>\na message to the server, either saying &#8220;player died&#8221;, or &#8220;player killed<br \/>\nmonster&#8221;. Since they were using ECB, a player watching network traffic<br \/>\ncould easily notice that whenever he killed a type-A monster, his would sent a particular bag-o-bits to the server. That b-o-b was always exactly the same &#8211; so while they didn&#8217;t know exactly what was in the message, they were able to<br \/>\ntell that the way the game told the server that the player killed a monster was<br \/>\nto send those bits.<\/p>\n<p> This was, naturally, exploited by clever players, who wrote programs sending<br \/>\nthousands of copies of that b-o-b to the server, racking up credits for killing thousands of monsters. Since it was a message that was set up to be one block long, and it was using ECB, that block always encrypted to the same ciphertext block &#8211; so they <em>knew<\/em> how to tell the server that they killed another monster. They<br \/>\nhad no idea of what was actually inside the block &#8211; no idea of what data specifically was being transmitted to say &#8220;Player A killed an Orc&#8221;. But because<br \/>\nof the combination of ECB with the way in which the cipher was being used, they<br \/>\nformed a very effective exploit.<\/p>\n<p> That&#8217;s an example of something called a <em>replay<\/em> attack, where you try<br \/>\nto violate the integrity of the message. Encryption isn&#8217;t only about hiding the<br \/>\nmessage plaintext from prying eyes, but about protecting <em>a communication<br \/>\nchannel<\/em> from interference by intruders. In the case of this MMORPG, the<br \/>\nattackers compromised the communication channel <em>without<\/em> decrypting the<br \/>\nmessage. They had no idea exactly what the batch-o-bits that they were transmitting<br \/>\nsaid, but they had a good idea of what they <em>meant<\/em>, and they were able to<br \/>\nintrude on the communication channel, adding messages that the receiver assumed<br \/>\nwere legitimate, because they matched the expected encryption. This kind of attack<br \/>\nis called a <em>replay<\/em> attack. For this application, the ECB did a decent job<br \/>\nof protecting confidentiality (no one figured out what the specific contents of the<br \/>\nmessage were, but they were able to figure out what it meant, so it didn&#8217;t even do<br \/>\nthat terribly well), but it did a <em>lousy<\/em> job with integrity (it was easy to<br \/>\nintroduce spurious content to the communication channel without being detectable by<br \/>\nthe sender or receiver.)<\/p>\n<p> So, moving on, the way to improve the performance of the block cipher is<br \/>\nto use a mode of operation that doesn&#8217;t just blindly concatenate things.<\/p>\n<h3>The Counter (CTR) MoO<\/h3>\n<p><em> (I&#8217;ve been alerted by a reader that I made a major mistake in my description of the CTR mode of operation. Since I don&#8217;t have time to correct it while I&#8217;m at work, I&#8217;m posting this warning: the information about CTR is incorrect. I&#8217;ll fix it this evening.)<\/em><br \/>\n<strike><\/p>\n<p> The simplest MoO beyond ECB is to just add a counter to the process. So, you<br \/>\nXOR your plaintext block with a counter value, and then send it through the<br \/>\nencryption. For a sequence of blocks, you increment the counter for each block. So<br \/>\na single block encoded multiple times will encode once exclusive-OR&#8217;ed with<br \/>\n&#8220;1&#8221;, once with &#8220;2&#8221;, etc. Repeated blocks won&#8217;t look repeated in the ciphertext.<\/p>\n<p> Below is a very simple fragment of pseudo-python that demonstrates<br \/>\nthe basic idea of this; next to it is a data-flow diagram illustrating<br \/>\nthe same thing. For each of the modes of operation I describe below, I&#8217;ll provide similar pseudo-code and diagrams.<\/p>\n<pre>\ndef EncryptWithCTR(blocks, ctr, key):\nfor b in blocks:\nencrypted = encrypt(key, b ^ ctr)\nctr = ctr + 1\noutput(encrypted)\n<\/pre>\n<p> Of course, just using integers that way isn&#8217;t ideal. It&#8217;s hard to detect,<br \/>\nbut it&#8217;s a natural thing to try. What&#8217;s better is to use a <em>counter function<\/em>. A counter function is a function F from the natural numbers<br \/>\nto a stream of bits the size of one block. So instead of exclusive-ORing<br \/>\ncleartext block #I with &#8220;I&#8221;, you XOR it with F(I). If your counter function<br \/>\nis pseudo-random, this can be very effective. Despite the fact that this is<br \/>\npotentially a significant benefit, most implementations that I&#8217;ve seen using<br \/>\nCTR just use a plain counter &#8211; the only variation is that it often doesn&#8217;t start the counter at 0 or 1.<\/p>\n<p><\/strike><\/p>\n<p> Consider how the replay attack would play out with CTR (or any of the others<br \/>\nbelow). People monitoring the network would be able to detect that <em>a<\/em> single encoded block would be sent each time a player killed a monster. But they wouldn&#8217;t know what the specific payload of the message was, and they wouldn&#8217;t be able to guess how to encode a copy of the block in a way that would work.<\/p>\n<p> One of the nice properties of CTR is that it&#8217;s easy to parallelize: if you know the counter function, then you can encrypt\/decrypt blocks in isolation without<br \/>\nneeding any information from a previous block. So you can encrypt\/decrypt blocks<br \/>\n3, 4, 5, and 6 at the same time: you know that the key for block 5 is just the<br \/>\nbasic key XOR counter(5).<\/p>\n<p> Of course, that parallelization is a curse as well as a blessing. Someone<br \/>\ntrying to crack your system can also parallelize, and try decrypting multiple blocks at the same time. Once you&#8217;ve got a few blocks broken, getting the rest<br \/>\nbecomes relatively easy, and you&#8217;ve got lots of different blocks, some of which may (by chance) be easy to break by brute-force methods.<\/p>\n<h3>Feedback Modes of Operation<\/h3>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"cbc.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_327.png?resize=214%2C195\" width=\"214\" height=\"195\" class=\"inset right\" \/><\/p>\n<p> Most of the common modes of operation are based on some form of feedback. You<br \/>\nstart with an initial block of random bits called an <em>initialization vector<\/em><br \/>\n(IV), and you encrypt the block XORing the IV somewhere in the process of<br \/>\ngenerating the ciphertext of the first block. Then for each successive block, you<br \/>\nreplace the IV with some kind of output from the previous block.<\/p>\n<p> Cipher-block chaining is a simple feedback-based MoO. Basically, you start<br \/>\nwith your agreed-upon block of bits in the initialization vector (IV). For the<br \/>\nfirst block, you exclusive-OR the plaintext with the IV, and then perform the<br \/>\nblock encryption. The output ciphertext of the first block is then used as the<br \/>\nIV for the second block; the IV of the third block is the output ciphertext of the second, and so on. So each block is scrambled by mixing it with the ciphertext of the previous blocks. This also avoids the problem of the game, because the same plain text message encrypts to different ciphertext each time.<\/p>\n<pre>\ndef EncryptWithCBC(blocks, iv, key):\nfeedback = iv\nfor b in blocks:\ninblock = b ^ feedback\nencrypted = encrypt(key, inblock)\nfeedback = encrypted\noutput(encrypted)\n<\/pre>\n<p> The big problem with CBC is that it&#8217;s weak against many kinds of brute-force<br \/>\nattacks. You <em>can&#8217;t<\/em> parallelize encryption using CBC: you need to finish encrypting each block before you can encrypt the next; but for decrypting, you can<br \/>\ntry to decrypt multiple blocks; and once you&#8217;ve broken two adjacent blocks,<br \/>\nyou&#8217;re pretty much wide-open. <\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"cfb.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_328.png?resize=204%2C172\" width=\"204\" height=\"172\" class=\"inset right\" \/><\/p>\n<p>  A slight variation is CFB; it&#8217;s just a minor reshuffle of the<br \/>\norder of things. In CBC, we XORed the plaintext of the message with an IV,<br \/>\nand then did block encryption on that to produce the ciphertext. In CFB,<br \/>\nto produce the ciphertext, \twe do the block encryption on the IV, and then XOR the result with the plaintext. The ciphertext of block N is then exclusive-or&#8217;ed<br \/>\nwith the previous IV to create the IV for block 5.<\/p>\n<pre>\ndef EncryptWithCFB(blocks, iv, key):\nfeedback = iv\nfor b in blocks:\nencrypted = encrypt(key, feedback)\nout = encrypted ^ b\nfeedback = out\noutput(out)\n<\/pre>\n<p> CFB has pretty much the same vulnerabilities as CBC.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"ofb.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_329.png?resize=211%2C170\" width=\"211\" height=\"170\" \/><\/p>\n<p> Output feedback (OFB) is yet another variation on the same theme. The only difference is that the input to block N+1 is the output of the block cipher<br \/>\nfrom step N, <em>before<\/em> it&#8217;s exclusive-OR&#8217;ed with the plaintext for step N.<br \/>\nThe interesting thing about OFB is that the plaintext doesn&#8217;t affect the output of the block cipher itself: the block cipher encrypts the combination of the key and<br \/>\nsome feedback from the previous block &#8211; the plaintext gets exclusive-OR&#8217;ed afterwards.<\/p>\n<pre>\ndef EncryptWithCFB(blocks, iv, key):\nfeedback = iv\nfor b in blocks:\nencrypted = encrypt(key, feedback)\nfeedback = encrypted\nout = encrypted ^ b\noutput(out)\n<\/pre>\n<p> These are all modes that focus on confidentiality rather than integrity. Integrity protection is more recent innovation, and it&#8217;s more complicated. In<br \/>\nlater posts, I&#8217;m going to talk a bit about the cryptanalysis and attacks that are used against block ciphers, and how they interact with different modes of operation. From there, we&#8217;ll be able to see why these modes don&#8217;t protect integrity, and show how we can build modes that focus on integrity.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sorry for the slow pace of the blog lately. I&#8217;ve been sick with a horrible sinus infection for the last month, and I&#8217;ve also been particularly busy with work, which have left me with neither the time nor the energy to do the research necessary to put together a decent blog post. After seeing an [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[84],"tags":[],"class_list":["post-682","post","type-post","status-publish","format-standard","hentry","category-encryption"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-b0","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/682","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=682"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/682\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=682"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=682"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}