Synthesis Tools for White-box Implementations Aleksei Udovenko SnT, University of Luxembourg WhibOx Workshop May 19, 2019
Introduction Circuit Construction Compilation Attacks Conclusion Plan Introduction Circuit Construction Compilation Attacks Conclusion 0 / 18
Introduction Circuit Construction Compilation Attacks Conclusion This talk: • Python-based framework for practical white-box implementations • Easy to use • For research purposes • ... and the WhibOx contest 1 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Circuit Implementations + simple framework, both – slow (1 bit / register, for synthesis and analysis unless batch execution) + existing literature on – large code size hardware design (storing circuit) + easy to simulate – the power of everywhere Random Access Machine is not fully utilised (though simulation can be obfuscated on top) 2 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Framework for Circuit WB Synthesis • easy implementations (bitwise are simple, for S-boxes a circuit is needed) • easy masking (linear + nonlinear) • starting point for further obfuscation • included: • batch circuit tracing • basic DCA-like analysis (correlation, exact matches, linear algebra attack) 3 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Framework for Circuit WB Synthesis • easy implementations (bitwise are simple, for S-boxes a circuit is needed) • easy masking (linear + nonlinear) • starting point for further obfuscation • included: • batch circuit tracing • basic DCA-like analysis (correlation, exact matches, linear algebra attack) • convenient C code generation for the WhibOx contest contest 3 / 18
Introduction Circuit Construction Compilation Attacks Conclusion A Quick Teaser NR = 10 1 KEY = "MySecretKey!2019" 2 3 pt = Bit.inputs("pt", 128) 4 ct, k10 = BitAES(pt, Bit.consts(str2bin(KEY)), nr=NR) 5 6 prng = LFSR(taps=[0, 2, 5, 18, 39, 100, 127], 7 state=BitAES(pt, pt, nr=2)[0]) 8 rand = Pool(n=128, prng=prng).step 9 10 ct = mask_circuit(ct, MINQ(rand=rand)) 11 ct = mask_circuit(ct, DOM(rand=rand, nshares=2)) 12 13 whibox_generate(ct, "build/submit.c", "Hello, world!") 14 AES circuit with configurable masking (quadratic MINQ + linear DOM-indep) 4 / 18
Introduction Circuit Construction Compilation Attacks Conclusion A Quick Teaser NR = 10 1 KEY = "MySecretKey!2019" 2 3 pt = Bit.inputs("pt", 128) 4 ct, k10 = BitAES(pt, Bit.consts(str2bin(KEY)), nr=NR) 5 6 prng = LFSR(taps=[0, 2, 5, 18, 39, 100, 127], 7 state=BitAES(pt, pt, nr=2)[0]) 8 rand = Pool(n=128, prng=prng).step 9 10 ct = mask_circuit(ct, MINQ(rand=rand)) 11 ct = mask_circuit(ct, DOM(rand=rand, nshares=2)) 12 13 whibox_generate(ct, "build/submit.c", "Hello, world!") 14 AES circuit with configurable masking Whib0x CTF - ready :) (quadratic MINQ + linear DOM-indep) 4 / 18
Introduction Circuit Construction Compilation Attacks Conclusion A Quick Teaser NR = 10 1 KEY = "MySecretKey!2019" 2 3 pt = Bit.inputs("pt", 128) 4 ct, k10 = BitAES(pt, Bit.consts(str2bin(KEY)), nr=NR) 5 6 prng = LFSR(taps=[0, 2, 5, 18, 39, 100, 127], 7 state=BitAES(pt, pt, nr=2)[0]) 8 rand = Pool(n=128, prng=prng).step 9 10 ct = mask_circuit(ct, MINQ(rand=rand)) 11 ct = mask_circuit(ct, DOM(rand=rand, nshares=2)) 12 13 whibox_generate(ct, "build/submit.c", "Hello, world!") 14 AES circuit with configurable masking Whib0x CTF - ready :) (quadratic MINQ + linear DOM-indep) (ouch, no fault protection...) 4 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Plan Introduction Circuit Construction Compilation Attacks Conclusion 4 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Circuit Construction • Bit : a circuit node, operations are overloaded: x = Bit.input("x") 1 y = Bit.input("y") 2 print ~(x & y) ^ y 3 Output: (~(x & y) ^ y) 4 5 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Circuit Construction • Bit : a circuit node, operations are overloaded: x = Bit.input("x") 1 y = Bit.input("y") 2 print ~(x & y) ^ y 3 Output: (~(x & y) ^ y) 4 • Vector : a list that propagates operations to its elements. • (Keyless) Simon: pt = Vector(Bit.inputs("pt", 32)) 1 l, r = pt.split() 2 for round in xrange(32): 3 r ^= (l.rol(1) & l.rol(8)) ^ l.rol(2) 4 l, r = r, l 5 ct = l.concat(r) 6 5 / 18
Introduction Circuit Construction Compilation Attacks Conclusion AES Circuit (1/2) • AES-128 circuit included ( ≈ 31000 gates); based on Canright’s S-Box. key = Bit.consts(str2bin("MySecreyKey!2019")) 1 pt = Bit.inputs("pt", 128) 2 ct, k10 = BitAES(pt, key, nr=10) 3 # k10 is the last subkey 4 6 / 18
Introduction Circuit Construction Compilation Attacks Conclusion AES Circuit (2/2) • Clean and modular internal structure, easy to modify. • Rect : representation of rectangular (AES-like) states. def BitAES(plaintext, key, rounds=10): 1 bx = Vector(plaintext).split(16) 2 bk = Vector(key).split(16) 3 state = Rect(bx, w=4, h=4).transpose() 4 kstate = Rect(bk, w=4, h=4).transpose() 5 for rno in xrange(rounds): 6 state = AK(state, kstate) 7 state = SB(state) 8 state = SR(state) 9 if rno < rounds-1: 10 state = MC(state) 11 kstate = KS(kstate, rno) 12 state = AK(state, kstate) 13 bits = sum( map(list, state.transpose().flatten()), []) 14 kbits = sum( map(list, kstate.transpose().flatten()), []) 15 return bits, kbits 16 7 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Masking (1/3) class DOM(MaskingScheme): 1 def encode(self, s): 2 x = [self.rand() for _ in xrange(self.nshares-1)] 3 x.append(reduce(xor, x) ^ s) 4 return tuple(x) 5 def decode(self, x): 6 return reduce(xor, x) 7 def XOR(self, x, y): 8 return tuple(xx ^ yy for xx, yy in zip(x, y)) 9 def AND(self, x, y): 10 matrix = [[xx & yy for yy in y] for xx in x] 11 for i in xrange(1, self.nshares): 12 for j in xrange(i + 1, self.nshares): 13 r = self.rand() 14 matrix[i][j] ^= r 15 matrix[j][i] ^= r 16 return tuple(reduce(xor, row) for row in matrix) 17 def NOT(self, x): 18 return (~x[0],) + tuple(x[1:]) 19 Hannes Groß, Stefan Mangard, Thomas Korak: (TIS@CCS 2016: 3) Domain-Oriented Masking: Compact Masked Hardware Implementations with Arbitrary Protection Order. 8 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Masking (2/3) Linear Masking: s = x 0 ⊕ x 1 ⊕ . . . ⊕ x r − 1 Minimalist Quadratic Masking: s = x 0 x 1 ⊕ x 2 Alex Biryukov, Aleksei Udovenko (ASIACRYPT 2018) Attacks and Countermeasures for White-box Designs. 9 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Masking (3/3) def mask_circuit(circuit, scheme, encode=True, decode=True): 1 """ Mask a given @circuit with a given masking @scheme. 2 Arguments @encode and @decode specify 3 whether encoding and decoding steps should be added. """ 4 ... 5 pt = Bit.inputs("pt", 128) 6 ct, _ = BitAES(pt, ..., rounds=NR) 7 8 # define a PRNG initialized with plaintext, also a circuit! 9 # here we use 2-round AES for initialization 10 # and LFSR for further generation 11 prng = LFSR(taps=[0, 2, 5, 18, 39, 100, 127], 12 state=BitAES(pt, pt, rounds=2)[0]) 13 rand = Pool(n=128, prng=prng).step 14 15 # nested masking 16 ct = mask_circuit(ct, MINQ(rand=rand)) 17 ct = mask_circuit(ct, DOM(rand=rand, nshares=2)) 18 10 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Plan Introduction Circuit Construction Compilation Attacks Conclusion 10 / 18
Introduction Circuit Construction Compilation Attacks Conclusion typedef uint16_t A; 1 switch (op) { 2 case XOR: 3 a = *((A *)p); pop(); 4 b = *((A *)p); pop(); • C code for simulation 5 ram[dst] = ram[a] ^ ram[b]; 6 • requires some encoding of the break; 7 case AND: 8 circuit a = *((A *)p); pop(); 9 b = *((A *)p); pop(); • easier to encode more compact 10 ram[dst] = ram[a] & ram[b]; 11 than by a compiler break; 12 case OR: 13 • usecase 1: local tracing/analysis a = *((A *)p); pop(); 14 b = *((A *)p); pop(); • usecase 2: PoC generation 15 ram[dst] = ram[a] | ram[b]; 16 break; 17 case NOT: 18 a = *((A *)p); pop(); 19 ram[dst] = ~ram[a]; 20 break; 21 case RANDOM: 22 ram[dst] = rand(); 23 break; 24 default: return; 25 } 26 11 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Compile and Run KEY = "MySecretKey!2019" 1 2 pt = Bit.inputs("pt", 128) 3 ct, k10 = BitAES(pt, Bit.consts(str2bin(KEY)), rounds=10) 4 5 # Encode circuit to file 6 RawSerializer().serialize_to_file(ct, "circuits/aes10.bin") 7 8 # Python API for C simulator 9 C = FastCircuit("circuits/aes10.bin") 10 11 ciphertext = C.compute_one("my_plaintext_abc") 12 13 # Verify correctness 14 from Crypto.Cipher import AES 15 ciphertext2 = AES.new(KEY).encrypt(plaintext) 16 assert ciphertext == ciphertext2 17 12 / 18
Introduction Circuit Construction Compilation Attacks Conclusion Plan Introduction Circuit Construction Compilation Attacks Conclusion 12 / 18
Recommend
More recommend