Random number generation Random number generation T
Transcription
Random number generation Random number generation T
T-110.470 Salausjärjestelmät (Cryptosystems) Implementation issues Random number generation 1.11.2004 Sami Vaarala 1 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala 3 T-110.470 Salausjärjestelmät, autumn 2004 Outline • Random number generation • Secure memory handling • Cryptographic libraries http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Random number generation • Random number generation is a critical primitive Cryptographic protocols require good sources of randomness Diffie-Hellman secret, random symmetric keys, RSA key generation, ... Level of required strength in randomness varies A bad random number generator may nullify security completely Just as fatal as a broken protocol design, that's why we cover it Very difficult to test for Common implementation issue that goes wrong (e.g. PGP 2.6) • Some fundamental problems What is randomness and where to get it ? Specific requirements for randomness in cryptographic contexts ? Detecting a bad random number generator ? • What is randomness ? For our purposes, uncertain bits from attacker's perspective 2 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala 4 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Pseudorandom numbers • Cryptographic pseudorandom numbers Good statistical properties, e.g. for simulation and games • Not just statistically random, but unpredictable without key (state) Example: Mersenne Twister http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html • Cryptographic pseudorandom number generator => A small amount of real random bits (e.g. 128) can be extended to a much larger amount using a cryptographic PRNG However, may be completely useless for cryptography Given random bitstream, attacker should be unable to predict backwards or forwards Pseudorandom number stream may reveal random number seed value => Attacker can easily reproduce stream and compute how the stream continues • Typical operation Maintain state (“entropy pool”) with random data from various sources Estimate the amount of entropy in the pool E.g. every event comes with an estimate of # of random bits Feed randomness until a certain threshold (# bits) is reached Then start handing out data, but still keep feeding entropy User data is extracted by hashing over the entropy pool (for example) 5 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala “Real” randomness • Multiple event sources with more or less uncertainty feed data into the generator. Each source estimates amount of entropy in each input (= number of bits unpredictable for an attacker). “Real” randomness – the best kind Does not need to be unbiased, we can use e.g. hashing to make bit probability distribution unbiased Examples: interrupt timing, keyboard and mouse events, CPU temperature and fan rotation speed, disk I/O. Some examples g Background radiation Generator state Lava lamp + webcam (SGI, http://www.lavarnd.org/) g Up to 200 kbits of random data per second ! But who watches the lava lamp, the image source, etc ? • g Less convincing sources Interrupt timing at cycle level, keyboard and mouse input, ... Estimating uncertainty (entropy) of event is difficult T-110.470 Salausjärjestelmät, autumn 2004 f h 6 http://www.tml.hut.fi/Opinnot/T-110.470/ Applications extract pseudorandom bits (e.g. Linux /dev/urandom) Example: 1024-byte buffer which accumulates randomness from events. If more than 1024 bytes available, current buffer is hashed through SHA1 to “compact” the buffer. (Several variants are used: CRCs, XORing, ..) Hard drive seek and read/write characteristics • Sami Vaarala http://www.tml.hut.fi/Opinnot/T-110.470/ Cryptographic pseudorandom numbers Comes from an external source which we assume to be random (difficult to predict) and cannot be affected by attacker • 7 T-110.470 Salausjärjestelmät, autumn 2004 Sami Vaarala 8 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Some typical requirements • Fortuna (Schneier & Ferguson) After initial entropy gathering, unlimited bits available • We don't want applications to hang indefinitely (DoS problem) • Described in Schneier & Ferguson: Practical Cryptography Brute forcing generator state computationally infeasible Improves on their previous design, Yarrow Although doable with enough brute force power (2128 for instance) Has not received extensive review, but it's an interesting design If generator state broken, damage should be minimized • Should not allow attacker to determine previous random numbers (“backward security”) Generator Generates arbitrary amount of pseudorandom data based on a fixed size seed (state) Generator should “escape” from attacker, i.e. re-establish a new state which the attacker cannot trivially determine (“forward security”) • Accumulator Should be resistant to malicious inputs Gathers entropy from various sources and reseeds the generator once in a while E.g. attacker generates network I/O events with little actual entropy E.g. malicious kernel driver feeds events with bogus entropy estimates • Seed file Should not require trustworthy entropy estimates from sources Stores entropy across reboots to avoid slow PRNG startup Driver writers will get it wrong T-110.470 Salausjärjestelmät, autumn 2004 9 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala The “escape” mechanism • A trivial scheme may not be able to “escape” once broken • Fortuna – Generator Generator state Basically AES-256 counter mode with some twists Pseudorandom stream is: EK(C++) | EK(C++) | EK(C++) ... A slightly better mechanism At most 216 blocks (1 megabyte) generated in one request Gather entropy into a separate buffer without feeding to current state In addition to generating the data, a new AES-256 key is generated (from the pseudorandom stream) using the current key Once enough entropy gathered (e.g. 128 bits), feed it all into the current state at once If attacker breaks current key, determining previous key (=> previous pseudorandom stream) is very difficult This forces attacker to try 2128 brute force attack on the new state The counter is not reset to avoid cycles (returning to same key/counter combination) Relies on knowing the amount of entropy in each event This can be improved still Counter mode is statistically biased (blocks don't repeat), which is why a limit on maximum data per key is imposed We'll soon look at Fortuna (Schneier & Ferguson) 10 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Counter (C) (128 bits) Thus requires more careful design T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ AES-256 key (K) (256 bits) Attack: if e.g. 10 bits are fed into state, attacker extracts random bitstream, and brute forces the 210 possible new states • 11 T-110.470 Salausjärjestelmät, autumn 2004 • If a trivial scheme is used, and all bits are fed into entropy pool directly, the requirement is not fulfilled • Basic design • Background Sami Vaarala T-110.470 Salausjärjestelmät, autumn 2004 12 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Fortuna – Accumulator • Reseed primitive (Reseed(s), s is arbitrary data) K SHAd-256(K | s) C C+1 • Fortuna – Accumulator Idea – P0 included in every reseed, P1 every other, P2 every fourth, etc (*) If entropy rate is large enough, P0 contains enough entropy to “escape” (uninitialized PRNG <=> C=0) Used by accumulator to refresh current key • If entropy rate is lower, we need to wait for a reseed with enough entropy pools => entropy rate can be unknown Accumulator basics Because each event goes to a dedicated pool, entropy in each pool is independent Purpose – gather entropy from various sources and reseed PRNG Works without knowing entropy per event – automatic adaptation Each event source is also independent, so malicious sources are OK Uses the Reseed(s) primitive periodically or when enough entropy gathered • P31 is used every 10+ years, so it will gather a lot of entropy • Accumulator state 32 entropy pools, P0, ..., P31 Note clever form of pool hashing – SHAd-256(Pi) Means that data doesn't need to be stored before reseeding, but we can maintain a running SHAd-256 hash Reseed number, r Otherwise P31 could end up with gigabytes of data before reseed... (*) SHAd-256(x) = SHA-256(SHA-256(x)) (double hash) T-110.470 Salausjärjestelmät, autumn 2004 Idea behind reseed operation 13 Sami Vaarala http://www.tml.hut.fi/Opinnot/T-110.470/ 15 T-110.470 Salausjärjestelmät, autumn 2004 Fortuna – Accumulator • Pool management in short • If P0 contains enough bytes (not entropy, just bytes), start reseed op. On system startup Atomic read-and-update function for seed file Read seed file into s, check that it is exactly 64 bytes long Also require that at least 100ms elapses before previous reseed Reseed(s) Reseed operation .... 1101000 r+1 Overwrite seed file with 64 bytes from (reseeded) generator 4 Atomicity tries to ensure that on successive reboots the same seed is not reused if at all possible (tries to prevent e.g. power manipulation) Find first bit set in r (starting from bit 0) Include pools P0, ..., Pk in reseed, where k is first bit set • Compute s = SHAd-256(P0) | ... | SHAd-256(Pk) Periodically, and on shutdown Refresh seed file by writing 64 random bytes from generator Call Reseed(s) • Reset pools P0, ..., Pk to empty strings T-110.470 Salausjärjestelmät, autumn 2004 Seed file contains 64 bytes of randomness Extracted from the generator Randomness from each source is fed in a round-robin fashion to the 32 pools; a certain event goes to exactly one pool r Sami Vaarala Fortuna – Seed file • http://www.tml.hut.fi/Opinnot/T-110.470/ Backups are a problem also for Fortuna seed files Hash in timestamp, restore counter, ... - but just partial fixes Problems with restored backups – systems become identical 14 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala T-110.470 Salausjärjestelmät, autumn 2004 16 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Linux 2.6.8 /dev/[u]random • Linux exposes two userspace devices /dev/random – “true” randomness, entropy not reused /dev/urandom – pseudo randomness, entropy reused if necessary Both are cryptographic pseudorandom number generators • Basic design (partially based on PGP) Maintains an entropy pool + entropy estimate (max pool size) Secure memory handling Input – stir pool using a CRC-32, and rotate+twist bits (ultimately XOR) Input is batched and inputed separately (avoids interrupt latency) Entropy estimates are more or less heuristic Timers: log2 [min(|delta|, |delta2|, |delta3|) / 2], cap to 12 Event data (keyboard scancode, mouse position etc) => also added Output – use SHA1 to extract entropy, update entropy estimate Reads on /dev/random block until (estimated) entropy available • 17 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Resources RFC 1750: Randomness Recommendations for Security • “Secure memory” can mean many things, for example You trust the memory but not the disk Example: storing crypto session keys Schneier & Ferguson: Practical Cryptography 2) Memory is encrypted – main memory never contains unencrypted critical data Existing cryptographic PRNGs More paranoid – counter e.g. memory persistence effects PGP Divide memory resources into trusted and untrusted Linux /dev/[u]random Main memory considered untrusted ... Registers, CPU caches, and/or a special memory considered trusted 18 T-110.470 Salausjärjestelmät, autumn 2004 Sami Vaarala 1) Memory locking – ensure memory is not paged to disk Contains a description of the Fortuna algorithm • http://www.tml.hut.fi/Opinnot/T-110.470/ Secure memory A good introduction to the various issues, but does not contain actual algorithms • 19 T-110.470 Salausjärjestelmät, autumn 2004 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala T-110.470 Salausjärjestelmät, autumn 2004 20 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Implementing memory locking Implementing encrypted memory • Operating system specific; e.g. Linux: mlock(), mlockall() Preferably in “random locations”, just a heuristic Often easiest to lock the entire process, unless it's very large Initialize: K1 = RND() ; K2 = K xor K1 (=> K = K1 xor K2) Interprocess communication complicates matters a lot Periodically (e.g. every 100ms), update K1 and K2 as Does your OS guarantee the path of data when IPC is used ? T = RND() ; K1 = K1 xor T ; K2 = K2 xor T Even if both processes are memory locked, is there a guarantee somewhere that the data never goes to paged memory in-between ? • System shutdown: Wipe K1 and K2 as effectively as possible • Even so, memory locking may be a critical function Read desired encrypted block into registers Example: 3DES hard drive encryption => try all possible consecutive 24-byte choices in swap file as encryption keys (quick attack) Decrypt data in registers, using key K Intermediate results must remain in registers or trusted L1 cache Process data in registers; then discard registers 21 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Implementing encrypted memory • • 23 Sami Vaarala Writing to encrypted memory – similar All in all, extremely difficult with trusted registers only Amount of data that can be processed is quite minimal You need to disable interrupts somehow – otherwise OS may perform a context switch, dumping registers into memory Similar to hard drive encryption, but applied to main memory Although encrypted data “burns” into memory, it's useless • A smaller, trusted memory may be used as aid Alternative – trust the memory for a short period E.g. decrypt data into memory, perform computations quickly, and overwrite with random pattern – all within 100ms (for instance) Or if possible, use CPU data cache – often more difficult to access Most secure variant – plaintext data only in registers Or move plaintext data around periodically, overwriting with PRNG data Very difficult in practice We could keep the encryption key in registers On system shutdown, wipe all critical data We don't want the encryption key in memory – for the same reasons! But keeping the key in registers is very inconvenient and impossible unless the OS supports it 22 http://www.tml.hut.fi/Opinnot/T-110.470/ http://www.tml.hut.fi/Opinnot/T-110.470/ But partial write may require a read-modify-write cycle Solution: keep all critical data in encrypted form in memory T-110.470 Salausjärjestelmät, autumn 2004 T-110.470 Salausjärjestelmät, autumn 2004 • Root cause of problems – memory persistence Recovery of bits can be minimized by changing bit states often (100ms?) • (*) In fact, this works fairly well for any small pieces of data Implementing encrypted memory RAM technology cannot guarantee that bits don't persist after poweroff • Thus, to read encrypted memory Extract key K into registers as K1 xor K2 Especially for decrypted persistent keys, such as in hard drive encryption T-110.470 Salausjärjestelmät, autumn 2004 (“Boojum”, Schneier & Ferguson) (*) Allocate two memory locations, K1 and K2, each the size of the key K It's often difficult to lock only certain portions • Partial solution • Sami Vaarala T-110.470 Salausjärjestelmät, autumn 2004 24 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Implementing encrypted memory • Typical services Any solution is dependent on memory technology • Memory management A hostile memory chip can (easily) overcome them Locking, zeroing, hardware memory interfaces If memory vendor changes memory technology, vulnerability to persistence effects might change This may happen after deployment Low level services Symmetric primitives But using cheap hardware is very attractive in practice Hashing, encryption (+ padding modes), MAC Memory encryption may seem an extreme measure Asymmetric primitives But if we're using strong cryptography, we should be quite paranoid Public key encryption and signatures (+ padding modes) E.g. loss of a corporate root CA private key may be a problem Diffie-Hellman Remember – a cryptographic system should be balanced if possible 25 http://www.tml.hut.fi/Opinnot/T-110.470/ Big number computation • Can be solved using specialized secure memory components T-110.470 Salausjärjestelmät, autumn 2004 Random number generation Maintaining security of big numbers Difficult to detect memory vulnerability when the host is powered on (?) • Approaches such as these are heuristic Very low level services Sami Vaarala 27 T-110.470 Salausjärjestelmät, autumn 2004 • http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Typical services Middle level services File format import and export (e.g. RSA keys) PKI support – certificate parsing, etc. • High level services SSL/TLS encrypted sockets Other protocol specific services Cryptographic libraries 26 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala 28 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala OpenSSL Background • SSLv2 and SSLv3 Full feature open-source library for SSL/TLS and generic cryptography TLSv1 http://www.openssl.org/ • • Implemented in C and assembler Basic paradigm Establish a session context (SSL_CTX) No type safety, no automatic resource management Open a connection and hand it over to the context => Fragile and prone to leaking Event loop uses SSL_read() and SSL_write() for I/O But good performance • Protocol support Based on earlier SSLeay crypto library (Eric A. Young) • OpenSSL – libssl • Several security issues have been found in OpenSSL The API is a bit complicated Some help in Viega et al: Network Security with OpenSSL OpenSSL in active use, so many bugs naturally found Even with its bugs, it's (probably) the best open source available • In wide use, in both open source and commercial software 29 T-110.470 Salausjärjestelmät, autumn 2004 • http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala OpenSSL – libcrypto • • MatrixSSL Small footprint SSL crypto library (about 50 kiB) (GPL + commercial) Certificates • Java SSL libraries ssllib, EspreSSL, ... Hash functions and message authentication codes (MACs) • HMAC, MD2, MD4, MD5, MDC2, RIPEMD-160, SHA-1 • RSA BSAFE Commercial crypto library Public key cryptography and key agreement X.509 (ASN.1) • Sami Vaarala Symmetric ciphers DSA, Diffie-Hellman, RSA • http://www.tml.hut.fi/Opinnot/T-110.470/ Other crypto libraries Blowfish, CAST, DES/3DES, IDEA, RC2, RC4, RC5 • 31 T-110.470 Salausjärjestelmät, autumn 2004 libgcrypt Generic crypto library, based on GnuPG Miscellaneous • Cryptographic random numbers Big number arithmetic ASN.1 encoding and decoding Tons of Java crypto providers Abstractions for I/O and cryptographic primitives PEM, PKCS #7, PKCS #12 T-110.470 Salausjärjestelmät, autumn 2004 30 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala 32 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Big number arithmetic Big number arithmetic makes code more complex • Just trust the library => non-critical applications Big numbers are typically implemented as allocated objects Use two big number libraries and compare => expensive Resources need to be managed more carefully to avoid leaks “Wooping” (Jurjen Bos, Practical Privacy, Ph.D. thesis) Individual big number operations may fail • Typically due to lack of resources For every big number x, also track x' = x (mod t) (x' is the “woop” of x) Example: optimized exponentiation (Montgomery), optimized RSA Shadow all big number computations with woops a = b + c => a' = b' + c' (mod t) More complicated rules for modular addition and multiplication In the end, check results; e.g. result x => check x (mod t) = x' Optionally, check all intermediate values 33 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala “Wooping” for big numbers • Corner cases easy to get wrong – and hard to come across in practice 35 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Why does this help ? If the crypto library fails due to a bug, it's unlikely the woop will match For instance, may occur once in 232 or 264 ... Even if the crypto library is malicious, it doesn't know t, so it's difficult Note that similar problem may occur with memory corruption to fake results Effect may be catastrophic – e.g. may leak RSA private key t changes on every initialization (e.g. host bootup) CRT used for RSA computation, public exponent e=3 Occasional RAM corruption can also be detected Error in RSA signature (mod q) causes computation of (s + kq) instead of s 3 Attacker knows s , the message being signed (assumption) Bad memory, bus problems, cosmic rays, ... • Attacker computes (s + kq)3 – s3 = q (k2qs + ks2 + k3q2) Performance hit ? If computing using big integers (1024+ bits), impact quite small This number is a multiple of q, say (tq) If using crypto hardware, wooping computations can be done in software (in parallel) Attacker computes greates common divisor of (tq) and n • Attacker gets q – and now it's trivial to factor n Is “wooping” used in practice ? Not widely Attacker obtains p and q, and private key is lost Crypto libraries should have built-in “wooping” as internal checks (Example from Practical Cryptography) 34 http://www.tml.hut.fi/Opinnot/T-110.470/ T-110.470 Salausjärjestelmät, autumn 2004 “Wooping” for big numbers What if the big number arithmetic implementation is broken ? T-110.470 Salausjärjestelmät, autumn 2004 t is strictly local, and kept secret from all parties Optimizations complicate algorithms a great deal • “Wooping” in short Generate a small, cryptographically random prime, t, e.g. 64-128 bits Computation failures don't happen with normal integers • Some solutions Programming languages don't often have native big numbers • “Wooping” for big numbers Sami Vaarala T-110.470 Salausjärjestelmät, autumn 2004 36 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala • Test vectors can be used run-time (in addition to testing) Execute a test vector suite for each algorithm during initialization Typically a smaller set than during testing Randomized inputs with lots of iteration can be used during testing Run-time tests must be short and effective • Thank you ! Motivation Catching compile errors Porting or upgrading a compiler; may compile OK but break Questions ? Catching load errors Corrupted bits from hard drive / bus Catching linking errors Dynamic library upgraded, binary compatibility lost but linking OK for some reason 37 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala Summary • Random number generation • Secure memory handling • Cryptographic libraries 38 T-110.470 Salausjärjestelmät, autumn 2004 (Other) Cryptographic self tests http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala 39 T-110.470 Salausjärjestelmät, autumn 2004 http://www.tml.hut.fi/Opinnot/T-110.470/ Sami Vaarala