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