Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 44 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
44
Dung lượng
485,79 KB
Nội dung
can determine the state from the output can run the PRNG backward or forward.This is less of a problem if the RNG is used in blocking mode. 124 125 /* reset states */ 126 pool_len = 32; 127 pool_idx = 0; 128 word_count = 0; 129 } 130 131 unsigned long rng_read(unsigned char *out, 132 unsigned long len, 133 int block) 134 { 135 unsigned long x, y; 136 137 x = 0; 138 while (len) { 139 /* can we read? */ 140 if (pool_len > 0) { 141 /* copy upto pool_len bytes */ 142 for (y = 0; y < pool_len && y < len; y++) { 143 *out++ = pool[pool_idx++]; 144 } 145 pool_len -= y; 146 len -= y; 147 x += y; 148 } else { 149 /* can we churn? (or are non-blocking?) */ 150 if (word_count >= 8 || !block) { 151 rng_churn_data(); 152 } else { 153 /* we can't so lets return */ 154 return x; 155 } 156 } 157 } 158 return x; 159 } The read function rng_read() is what a caller would use to return random bytes from the RNG system. It can operate in one of two modes depending on the block argument. If it is nonzero, the function acts like a RNG and only reads as many bytes as the pool has to offer. Unlike a true blocking function, it will return partial reads instead of waiting to fulfill the read. The caller would have to loop if they required traditional blocking functionality.This flexibility is usually a source of errors, as callers do not check the return value of the function. Unfortunately, even an error code returned to the caller would not be noticed unless you sig- nificantly altered the code flow of the program (e.g., terminate the application). If the block variable is zero, the function behaves like a PRNG and will rechurn the existing state and pool regardless of the amount of additional entropy. Provided the state has www.syngress.com Random Number Generation • Chapter 3 111 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 111 enough entropy in it, running it as a PRNG for a modest amount of time should be for all purposes just like running a proper RNG. WARNING The RNG presented in this chapter is not thread safe, but is at least real-time compatible. This is particularly important to note as it cannot be directly plugged into a kernel without causing havoc. The functions rng_add_byte() and rng_read() require locks to prevent more than one caller from being inside the function. The trivial way to solve this is to use a mutex locking device. However, keep in mind in real-time platforms you may have to drop rng_add_byte() calls if the mutex is locked to keep latency at a minimum. TIP If you ran a RNG event trapping system based on the rng_add_byte() mecha- nism alone, the state could have been fed more than 256 bits of entropy and you would never have a way to get at it. A simple solution is to have a background task that calls rng_read() and buffers the data in a larger buffer from which callers can read from. This allows the system to buffer a useful amount of entropy beyond just 32 bytes. Most cryptographic tasks only require a couple hundred bytes of RNG data at most. A four-kilobyte buffer would be more than enough to keep things moving smoothly. RNG Estimation At this point, we know what to gather, how to process it, and how to produce output. What we need now are sources of entropy trapped and a conservative estimate of their entropy. It is important to understand the model for each source to be able to extract entropy from it efficiently. For all of our sources we will feed the interrupt (or device ID) and the least sig- nificant byte of a high precision timer to the RNG.After those, we will feed a list of other pieces of data depending on the type of interrupt. Let us begin with user input devices. www.syngress.com 112 Chapter 3 • Random Number Generation 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 112 Keyboard and Mouse The keyboard is fairly easy to trap. We simply want the keyboard scan codes and will feed them to the RNG as a whole. For most platforms, we can assume that scan codes are at most 16 bits long. Adjust accordingly to suit your platform. In the PC world, the keyboard con- troller sends one byte if the key pressed was one of the typical alphanumeric characters. When a less frequent key is pressed such as the function keys, arrow keys, or keys on the number pad, the keyboard controller will send two bytes.At the very least, we can assume the least significant byte of the scan code will contain something and upper may not. In English text, the average character has about 1.3 bits of entropy, taking into account key repeats and other “common” sequences; the lower eight bits of the scan code will likely contain at least 0.5 bits of entropy.The upper eight bits is likely to be zero, so its entropy is estimated at a mere 1/16 bits. Similarly, the interrupt code and high-resolution timer source are given 1/16 bits each as well. rng_src.c: 004 /* KEYBOARD */ 005 void rng_keyboard(int INT, unsigned scancode, unsigned hrt) 006 { 007 rng_add_byte(INT, 1); /* 1/16 bits */ 008 rng_add_byte(scancode & 0xFF, 8); /* 1/2 bits */ 009 rng_add_byte((scancode >> 8) & 0xFF, 1); /* 1/16 bits */ 010 rng_add_byte(hrt, 1); /* timer */ 011 } This code is callable from a keyboard, which should pass the interrupt number (or device ID), scancode, and the least significant byte of a high resolution timer. Obviously, where PC AT scan codes are not being used the logic should be changed appropriately. A rough guide is to take the average entropy per character in the host language and divide it by at least two. For the mouse, we basically use the same principle except instead of a scan code we use the mouse position and status. rng_src.c: 013 /* MOUSE */ 014 void rng_mouse(int INT, int x, int y, int z, 015 int buttons, unsigned hrt) 016 { 017 rng_add_byte(INT, 1); /* 1/16 bits */ 018 rng_add_byte(x & 255, 2); /* 1/8 bits */ 019 rng_add_byte(y & 255, 2); /* 1/8 bits */ 020 rng_add_byte(z & 255, 1); /* 1/16 bits */ 021 rng_add_byte(buttons & 255, 1); /* 1/16 bits */ 022 rng_add_byte(hrt, 1); /* timer */ 023 } Here we add the lower eight bits of the mouse x-, y-, and z-coordinates (z being the scroll wheel). We estimate that the x and y will give us 1/8 th of a bit of entropy since it is only really the least significant bit in which we are interested. For example, move your www.syngress.com Random Number Generation • Chapter 3 113 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 113 mouse in a vertical line (pretend you are going to the File menu); it is unlikely that your x- coordinate will vary by any huge amount. It may move slightly left or right of the upward direction, but for the most part it is straight.The entropy would be on when and where the mouse is, and the “error” in the x-coordinate as you try to move the mouse upward. We assume in this function that the mouse buttons (up to eight) are packed as booleans in the lower eight bits of the button argument. In reality, the button’s state contains very little entropy, as most mouse events are the user trying to locate something on which to click. Timer The timer interrupt or system clock can be tapped for entropy as well. Here we are looking for the skew between the two. If your system clock and processor clock are locked (say they are based on one another), you ought to ignore this function. rng_src.c: 025 /* TIMER */ 026 void rng_timer(int INT, unsigned timer, unsigned hrt) 027 { 028 rng_add_byte(INT, 1); /* 1/16 bits */ 029 rng_add_byte(timer^hrt, 1); /* 1/16 bits */ 030 } We estimate that the entropy is 1/16 bits for the XOR of the two timers. Generic Devices This last routine is for generic devices such as storage devices or network devices where trapping all of the user data would be far too costly. Instead, we trap the ID of the device that caused the event and the current high-resolution time. rng_src.c: 032 /* DEVICE */ 033 void rng_device( int INT, unsigned minor, 034 unsigned major, unsigned hrt) 035 { 036 rng_add_byte(INT, 1); /* 1/16 bits */ 037 rng_add_byte(minor, 1); /* 1/16 bits */ 038 rng_add_byte(major, 1); /* 1/16 bits */ 039 rng_add_byte(hrt, 1); /* timer */ 040 } We assume the devices have some form of major:minor identification scheme such as that used by Linux. It could also the USB or PCI device ID if a major/minor is not avail- able, but in that case you would have to update the function to add 16 bits from both major and minor instead of just the lower eight bits. www.syngress.com 114 Chapter 3 • Random Number Generation 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 114 RNG Setup A significant problem most platforms face is a lack of entropy when they first boot up.There is not likely to be many (if at all any) events collected by time the first user space program launches. The Linux solution to this problem is to gather a sizable block of RNG output and write it to a file. On the next bootup, the bits in the file are added to the RNG a rate of one bit per bit. It is important not to use these bits directly as RNG output and to destroy the file as soon as possible. That approach has security risks since the entire entropy of the RNG can possibly be exposed to attackers if they can read the seed file before it is removed. Obviously, the file would have to be marked as owned by root with permissions 0400. On platforms on which storage of a seed would be a problem, it may be more appro- priate to spend a few seconds reading a device like an ADC.At 8 KHz, a five-second recording of audio should have at least 256 bits of entropy if not more. A simple approach to this would be to collect the five seconds, hash the data with SHA-256, and feed the output to the RNG at a rate of one bit of entropy per bit. PRNG Algorithms We now have a good starting point for constructing an RNG if need be. Keep in mind that many platforms such as Windows, the BSDs, and Linux distributions provide kernel level RNG functionality for the user. If possible, use those instead of writing your own. What we need now, though, are fast sources of entropy. Here, we change entropy from a universal concept to an adversarial concept. From our point of view, it is ok if we can pre- dict the output of the generator, as long as our attackers cannot. If our attackers cannot pre- dict bits, then to them, we are effectively producing random bits. PRNG Design From a high-level point of view, a PRNG is much like an RNG. In fact, most popular PRNG algorithms such as Fortuna and the NIST suite are capable of being used as RNGs (when event latency is not a concern). The process diagram (Figure 3.3) for the typical PRNG is much like that of the RNG, except there is no need for a gather stage.Any input entropy is sent directly to the (higher latency) processing stage and made part of the PRNG state immediately. The goal of most PRNGs differs from that of RNGs.The desire for high entropy output, at least from an outsider’s point of view, is still present. When we say “outsider,” we mean those who do not know the internal state of the PRNG algorithm. For PRNGs, they are used in systems where there is a ready demand for entropy; in particular, in systems where there is not much processing power available for the output stage. PRNGs must gen- erate high entropy output and must do so efficiently. www.syngress.com Random Number Generation • Chapter 3 115 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 115 Figure 3.3 PRNG Process Diagram Bit Extractors Formal cryptography calls PRNG algorithms “bit extractors” or “seed lengtheners.”This is because the formal model (Oded Goldreich, Foundations of Cryptography, Basic Tools, Cambridge University Press, 1 st Edition) views them as something that literally takes the seed and stretches it to the length desired. Effectively, you are spreading the entropy over the length of the output.The longer the output, the more likely a distinguisher will be able to detect the bits as coming from an algorithm with a specific seed. Seeding and Lifetime Just like RNGs, a PRNG must be fed seed data to function as desired. While most PRNGs support re-seeding after they have been initialized, not all do, and it is not a requirement for their security threat model. Some PRNGs such as those based on stream ciphers (RC4, SOBER-128, and SEAL for instance) do not directly support re-seeding and would have to be re-initialized to accept the seed data. In most applications, the PRNG usefulness can be broken into one of two classifications depending on the application. For many short runtime applications, such as file encryption tools, the PRNG must live for a short period of time and is not sensitive to the length of the output. For longer runtime applications, such as servers and user daemons, the PRNG has a long life and must be properly maintained. On the short end, we will look at a derivative of the Yarrow PRNG, which is very easy to construct with a block cipher and hash function. It is also relatively quick producing output as fast as the cipher can encrypt blocks. We will also examine the NIST hash based DRBG function, which is more complex but fills the applications where NIST crypto is a must. www.syngress.com 116 Chapter 3 • Random Number Generation Event Process Output Random Bits 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 116 On the longer end, we will look at the Fortuna PRNG. It is more complex and difficult to set up, but better suited to running for a length of time. In particular, we will see how the Fortuna design defends against state discovery attacks. PRNG Attacks Now that we have what we consider a reasonable looking PRNG, can we pull it apart and break it? First, we have to understand what breaking it means.The goal of a PRNG is to emit bits (or bytes), which are in all meaningful statistical ways unpredictable. A PRNG would therefore be broken if attackers were able to predict the output more often then they ought to. More precisely, a break has occurred if an algorithm exists that can distinguish the PRNG from random in some feasible amount of time. A break in a PRNG can occur at one of several spots. We can predict or control the inputs going in as events in an attempt to make sure the entropy in the state is as low as pos- sible.The other way is to backtrack from the output to the internal state and then use low entropy events to trick a user into reading (unblocked) from the PRNG what would be low entropy bytes. Input Control First, let us consider controlling the inputs. Any PRNG will fail if its only inputs are from an attacker. Entropy estimation (as attempted by the Linux kernel) is not a sound solution since an attacker may always use a higher order model to generate what the estimator thinks is random data. For example, consider an estimator that only looks at the 0 th order statistics; that is, the number of one bits and number of zero bits.An attacker could feed a stream of 01010101… to the PRNG and it would be none the wiser. Increasing the model order only means the attacker has to be one step ahead. If we use a 1 st order model (counting pair of bits), the attacker could feed 0001101100011011… and so on. Effectively, if your attacker controls all of your entropy inputs you are going to success- fully be attacked regardless of what PRNG design you choose. This leaves us only to consider the case where the attacker can control some of the inputs.This is easily proven to be thwarted by the following observation. Suppose you send in one bit of entropy (in one bit) to the PRNG and the attacker can successfully send in the appropriate data to the LFSR such that your bit cancels out. By the very definition of entropy, this cannot happen as your bit had uncertainty. If the attacker could predict it, then the entropy was not one for that bit. Effectively, if there truly is any entropy in your inputs, an attacker will not be able to “cancel” them out regardless of the fact a LFSR is used to mix the data. www.syngress.com Random Number Generation • Chapter 3 117 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 117 Malleability Attacks These attacks are like chosen plaintext attacks on ciphers except the goal is to guide the PRNG to given internal state based on chosen inputs. If the PRNG uses any data-depen- dant operations in the process stage, the attacker could use that to control how the algorithm behaves. For example, suppose you only hashed the state if there was not an even balance of zero and one bits.The attacker could take advantage of this and feed inputs that avoided the hash. Backtracking Attacks A backtracking attack occurs when your output data leaks information about the internal state of the PRNG, to the point where an attacker can then step the state backward.The goal would be to find previous outputs. For example, if the PRNG is used to make an RSA key, figuring out the previous output gives the attacker the factors to the RSA key. As an example of the attack, suppose the PRNG was merely an LFSR.The output is a linear combination of the internal state. An attacker could solve for it and then proceed to retrieve any previous or future output of the PRNG. Even if the PRNG is well designed, learning the current state must not reveal the pre- vious state. For example, consider our RNG construction in rng.c; if we removed the XOR near line 122 the state would not really change between invocations when being used as a PRNG.This means, if the attacker learns the state and we had not placed that XOR there, he could run it forward indefinitely and backward partially. Yarrow PRNG The Yarrow design is a PRNG that originally was meant for a long-lived system wide deployment. It achieved some popularity as a PRNG daemon on various UNIX like plat- forms, but mostly with the advent of Fortuna it has been relegated to a quick and dirty PRNG design. Essentially, the design hashes entropy along with the existing pool; this pool is then used a symmetric key for a cipher running in CTR mode (see Chapter 4,“Advanced Encryption Standard”).The cipher running in CTR mode and produces the PRNG output fairly effi- ciently.The actual design for Yarrow specifies how and when reseeding should be issued, how to gather entropy, and so on. For our purposes, we are using it as a PRNG so we do not care where the seed comes from.That is, you should be able to assume the seed has enough entropy to address your threat model. Readers are encouraged to read the design paper “Yarrow-160: Notes on the Design and Analysis of the Yarrow Cryptographic Pseudorandom Number Generator” by John Kelsey, Bruce Schneier, and Niels Ferguson to get the exact details, as our description here is rather simplistic. www.syngress.com 118 Chapter 3 • Random Number Generation 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 118 Design From the block diagram in Figures 3.4 and 3.5, we see that the existing pool and seed are hashed together to form the new pool (or state).The use of the hash avoids backtracking attacks. Suppose the hash of the seed data was simply XOR’ed into the pool; if an attacker knows the pool and can guess the seed data being fed to it, he can backtrack the state. Figure 3.4 Block Diagram of the Simplified Yarrow PRNG Figure 3.5 Algorithm: Yarrow Reseed Input: pool:The current pool seed:The seed to add to the pool Output: pool:The newly updated pool 1. W = pool || seed 2. pool = Hash(W) 3. return pool The hash of both pieces also helps prevent degradation where the existing entropy pool is used far too long.That is, while hashing the pool does not increase the entropy, it does change the key the CTR block uses. Even though the keys would be related (by the hash), it would be infeasible to exploit such a relationship.The CTR block need not refer to a cipher either; it could be a hash in CTR mode. For performance reasons, it is better to use a block cipher for the CTR block. www.syngress.com Random Number Generation • Chapter 3 119 Seed Hash Pool CTROutput 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 119 In the original Yarrow specification, the design called for the SHA-1 hash function and Blowfish block cipher (or only a hash). While these are not bad choices, today it is better to choose SHA-256 and AES, as they are more modern, more efficient, and part of various standards including the FIPS series. In this algorithm (Figure 3.6) we use the pool as a sym- metric key and then proceed to CTR encrypt a zero string to produce output. Figure 3.6 Algorithm: Yarrow Generate Input: pool:The current pool IV:The current IV value. outlen:The number of bytes to read Output: output:The random bytes IV:The new value for the IV 1. K = Schedule pool as a cipher key (see Chapter 4) 2. D = CTR(0x00 outlen , K, IV) 3. Return D, IV. The notation 0x00 outlen indicates a string of length outlen bytes of all zeroes. In step 2, we invoke the CTR routine for our cipher, which has not been defined yet.The parameters are <plaintext, key, IV>, where the IV is initially zeroed and then preserved through every call to the reseed and generate functions. Replaying the IV for the same key is dangerous, which is why it is important to keep updating it.The random bytes are in the string D, which is the output of encrypting the zero string with the CTR block. Reseeding The original Yarrow specification called for system-wide integration with entropy sources to feed the Yarrow PRNG. While not a bad idea, it is not the strong suit of the Yarrow design. As we shall see in the discussion of Fortuna, there are better ways to gather entropy from system events. For most cryptographic tasks that are short lived, it is safe to seed Yarrow once from a system RNG.A safe practical limit is to use a single seed for at most one hour, or for no more than 2 (w/4) CTR blocks where w is the bit size of the cipher (e.g., w=128 for AES). For AES, this limit would be 2 32 blocks, or 64 gigabytes of PRNG output. (On AMD Opteron proces- sors, it is possible to generate 2 32 outputs in far less than one hour (would take roughly 500 sec- onds). So, this limitation is actually of practical importance and should be kept in mind.) www.syngress.com 120 Chapter 3 • Random Number Generation 404_CRYPTO_03.qxd 10/30/06 12:48 PM Page 120 [...]... consists of 1 AddRoundKey(round=0) 2 for round = 1 to Nr-1 (9, 11 or 13 depending on the key size) do 1 SubBytes 2 ShiftRows 3 MixColumns 4 AddRoundKey(round) 3 SubBytes 4 ShiftRows 5 AddRoundKey(Nr) www.syngress.com 143 40 4_CRYPTO_ 04. qxd 144 10/30/06 9 :42 AM Page 144 Chapter 4 • Advanced Encryption Standard Finite Field Math The AES cipher can actually be fully specified as a series of scalar and vector operations... it is irrational.That means that for any finite expansion, there is always a small degree of entropy in the value (Of course, we can always do more calculations to obtain the next decimal place, so such expansions are not suitable for cryptography. ) www.syngress.com 137 40 4_CRYPTO_03.qxd 10/30/06 12 :48 PM Page 138 40 4_CRYPTO_ 04. qxd 10/30/06 9 :42 AM Page 139 Chapter 4 Advanced Encryption Standard Solutions... Length (seedlen) for Hash_DRBG max_personalization_ string_length max_additional_input_length max_number_of_bits_per_request reseed_interval SHA2 24 SHA256 SHA3 84 SHA512 80 80 112 112 128 128 192 192 256 256 160 2 24 256 3 84 512 security_ strength < 235 bits 44 0 44 0 44 0 888 888 < 235 < 235 < 219 < 218 Design The internal state of Hash_DRBG consists of: ■ A value V of seedlen bits that is updated during each... iterate it enough times over the plaintext to make the mapping from the ciphertext back to plaintext difficult without the key For comparison, DES has 16 rounds of the same function, IDEA had 8 rounds, RC5 www.syngress.com 141 40 4_CRYPTO_ 04. qxd 142 10/30/06 9 :42 AM Page 142 Chapter 4 • Advanced Encryption Standard originally had 12 rounds, Blowfish had 16 rounds, and AES had 10 rounds in their respective... itself for the next usage In the design of Fortuna they use an AES candidate cipher; we can just use AES for this (Fortuna was described before the AES algorithm was decided upon).Two www.syngress.com 125 40 4_CRYPTO_03.qxd 126 10/30/06 12 :48 PM Page 126 Chapter 3 • Random Number Generation clocks produce 256 bits, which is the maximally allowed key size.The new key is then scheduled and used for future... www.syngress.com 145 40 4_CRYPTO_ 04. qxd 146 10/30/06 9 :42 AM Page 146 Chapter 4 • Advanced Encryption Standard This polynomial field will be used both in the SubBytes and MixColumn stages In practice, at least in software, we do not implement the multiplication this way, as it would be too slow AddRoundKey This step of the round function adds (in GF(2)) the round key to the state It performs 16 parallel... length(seed) || seed 2 Add W to the pool[pool_idx] www.syngress.com 123 40 4_CRYPTO_03.qxd 1 24 10/30/06 12 :48 PM Page 1 24 Chapter 3 • Random Number Generation 3 If pool_idx = 0 then pool0_cnt = pool0_cnt + length(seed) 4 If pool0_cnt >= 64 call reseed algorithm 5 pool_idx = (pool_idx + 1) mod NUMPOOLS 6 return Figure 3.9 Fortuna Entropy Addition Diagram Seed pool_idx Append Header MUX... Chaining Modes ■ Putting It All Together Summary Solutions Fast Track Frequently Asked Questions 139 40 4_CRYPTO_ 04. qxd 140 10/30/06 9 :42 AM Page 140 Chapter 4 • Advanced Encryption Standard Introduction The Advanced Encryption Standard (AES) began in 1997 with an announcement from NIST seeking a replacement for the aging and insecure Data Encryption Standard (DES) At that point, DES has been repeatedly... get a bit messy for the newcomer with the polynomial representation denoted by GF(2)[x].This is the set of polynomials in x with coefficients from GF(2).This represen- www.syngress.com 40 4_CRYPTO_ 04. qxd 10/30/06 9 :42 AM Page 145 Advanced Encryption Standard • Chapter 4 tation means that we treat the vector of eight bits as coefficients to a seventh degree polynomial (e.g., turns... semi-fast implementations in this text are based off the Rijndael reference code Block Ciphers Before we go ahead into the design of AES, we should discuss what block ciphers are and the role they fill in cryptography www.syngress.com 40 4_CRYPTO_ 04. qxd 10/30/06 9 :42 AM Page 141 Advanced Encryption Standard • Chapter 4 The term block cipher actually arose to distinguish said algorithms from the normal stream . 0; y < pool_len && y < len; y++) { 143 *out++ = pool[pool_idx++]; 144 } 145 pool_len -= y; 146 len -= y; 147 x += y; 148 } else { 149 /* can we churn? (or are non-blocking?) */ 150. strength (min_length) Maximum entropy input length < 2 35 bits (max_length) Seed Length (seedlen) for 44 0 44 0 44 0 888 888 Hash_DRBG max_personalization_ < 2 35 string_length max_additional_input_length. lower eight bits. www.syngress.com 1 14 Chapter 3 • Random Number Generation 40 4_CRYPTO_03.qxd 10/30/06 12 :48 PM Page 1 14 RNG Setup A significant problem most platforms face is a lack of entropy when