@@ -266,6 +266,8 @@ print([k.hex() for k in solutions])
266266
267267{{< details summary="Full Exploit Code" open=false class="big-detail">}}
268268
269+ #### solve.py
270+
269271``` py
270272from spaes import *
271273import operator
@@ -448,8 +450,169 @@ def pwn():
448450pwn()
449451```
450452
453+ Additionally, we need the implementation of the cipher that includes the decryption routine, which is provided below.
454+
455+ #### spaes.py
456+
457+ ``` py
458+ from Crypto.Util.Padding import pad, unpad
459+
460+ # ##
461+
462+ SBOX = [4 , 14 , 13 , 5 , 0 , 9 , 2 , 15 , 11 , 8 , 12 , 3 , 1 , 6 , 7 , 10 ]
463+
464+ inv_sbox = [0 ] * 16
465+ for i, v in enumerate (SBOX ):
466+ inv_sbox[v] = i
467+
468+ ROUNDS = 6
469+
470+ CONSTS = [' 6d6ab780eb885a101263a3e2f73520c9' , ' f71df57947881932a33a3a0b8732b912' , ' 0aa5df6fadf91c843977d378cc721147' , ' 4a8f29cf09b62619c596465a59fb9827' , ' 29b408cfd4910c80866f5121c6b1cc77' , ' 8589c67a30dbced873b34bd04f40b7cb' , ' 6d64bc8485817ba330fc81b9d2899532' , ' 46495adad2786761ae89e8c26ff1c769' , ' 747470d62b219d12abf9a0816b950639' , ' 4ed2d429061e5d13a2b2ad1df1e63110' ]
471+
472+ def rotr_128 (x , n ):
473+ return ((x >> n) | (x << (128 - n))) & ((1 << 128 ) - 1 )
474+
475+ def rotl_4 (x , n ):
476+ return ((x << n) | (x >> (4 - n))) & ((1 << 4 ) - 1 )
477+
478+ def to_matrix (bts ):
479+ return [
480+ [bts[i] >> 4 for i in range (0 , 16 , 2 )],
481+ [bts[i] & 0x 0F for i in range (0 , 16 , 2 )],
482+ [bts[i] >> 4 for i in range (1 , 16 , 2 )],
483+ [bts[i] & 0x 0F for i in range (1 , 16 , 2 )],
484+ ]
485+
486+ def from_matrix (state ):
487+ return bytes ([state[i][j] << 4 | state[i + 1 ][j] for j in range (8 ) for i in (0 , 2 )])
488+
489+ def shift_rows (state ):
490+ return [
491+ state[0 ],
492+ state[1 ][1 :] + state[1 ][:1 ],
493+ state[2 ][2 :] + state[2 ][:2 ],
494+ state[3 ][3 :] + state[3 ][:3 ]
495+ ]
496+
497+ def inv_shift_rows (state ):
498+ return [
499+ state[0 ],
500+ state[1 ][- 1 :] + state[1 ][:- 1 ],
501+ state[2 ][- 2 :] + state[2 ][:- 2 ],
502+ state[3 ][- 3 :] + state[3 ][:- 3 ],
503+ ]
504+
505+ def mix_columns (state ):
506+ mixed = [[0 for i in range (8 )] for j in range (4 )]
507+ for i in range (8 ):
508+ mixed[0 ][i] = state[1 ][i] ^ rotl_4(state[2 ][i], 1 ) ^ rotl_4(state[3 ][i], 2 )
509+ mixed[1 ][i] = state[2 ][i] ^ rotl_4(state[3 ][i], 1 ) ^ rotl_4(state[0 ][i], 2 )
510+ mixed[2 ][i] = state[3 ][i] ^ rotl_4(state[0 ][i], 1 ) ^ rotl_4(state[1 ][i], 2 )
511+ mixed[3 ][i] = state[0 ][i] ^ rotl_4(state[1 ][i], 1 ) ^ rotl_4(state[2 ][i], 2 )
512+ return mixed
513+
514+ def inv_mix_columns (state ):
515+ unmixed = [[0 for i in range (8 )] for j in range (4 )]
516+ for i in range (8 ):
517+ unmixed[0 ][i] = state[3 ][i] ^ rotl_4(state[1 ][i], 2 ) ^ rotl_4(state[2 ][i], 3 )
518+ unmixed[1 ][i] = state[0 ][i] ^ rotl_4(state[2 ][i], 2 ) ^ rotl_4(state[3 ][i], 3 )
519+ unmixed[2 ][i] = state[1 ][i] ^ rotl_4(state[3 ][i], 2 ) ^ rotl_4(state[0 ][i], 3 )
520+ unmixed[3 ][i] = state[2 ][i] ^ rotl_4(state[0 ][i], 2 ) ^ rotl_4(state[1 ][i], 3 )
521+ return unmixed
522+
523+ def enc (m , k , t ):
524+ assert len (m) == 16
525+ assert len (k) == 16
526+ assert len (t) == 16
527+
528+ RCON = [bytes .fromhex(x) for x in CONSTS ]
529+
530+ final_key = int .from_bytes(k, byteorder = ' big' )
531+ final_key = rotr_128(final_key, 63 ) ^ (final_key >> 1 )
532+ final_key = int .to_bytes(final_key, length = 16 , byteorder = ' big' )
533+
534+ state = to_matrix(m)
535+ key_matrix = to_matrix(k)
536+ tweak_matrix = to_matrix(t)
537+ final_key_matrix = to_matrix(final_key)
538+
539+ state = [[state[i][j] ^ key_matrix[i][j] for j in range (8 )] for i in range (4 )]
540+
541+ for r in range (ROUNDS - 1 ):
542+ state = [[SBOX [state[i][j]] for j in range (8 )] for i in range (4 )]
543+ state = shift_rows(state)
544+ state = mix_columns(state)
545+ round_const_matrix = to_matrix(RCON [r])
546+ state = [[state[i][j] ^ round_const_matrix[i][j] for j in range (8 )] for i in range (4 )]
547+
548+ if r % 2 == 0 :
549+ state = [[state[i][j] ^ key_matrix[i][j] for j in range (8 )] for i in range (4 )]
550+ else :
551+ state = [[state[i][j] ^ tweak_matrix[i][j] for j in range (8 )] for i in range (4 )]
552+
553+ state = [[SBOX [state[i][j]] for j in range (8 )] for i in range (4 )]
554+ state = shift_rows(state)
555+ state = [[state[i][j] ^ final_key_matrix[i][j] for j in range (8 )] for i in range (4 )]
556+
557+ c = from_matrix(state)
558+ return c
559+
560+ def dec (c , k , t ):
561+ assert len (c) == 16
562+ assert len (k) == 16
563+ assert len (t) == 16
564+
565+ RCON = [bytes .fromhex(x) for x in CONSTS ]
566+
567+ final_key = int .from_bytes(k, byteorder = ' big' )
568+ final_key = rotr_128(final_key, 63 ) ^ (final_key >> 1 )
569+ final_key = int .to_bytes(final_key, length = 16 , byteorder = ' big' )
570+
571+ key_matrix = to_matrix(k)
572+ tweak_matrix = to_matrix(t)
573+ final_key_matrix = to_matrix(final_key)
574+ state = to_matrix(c)
575+
576+ state = [[state[i][j] ^ final_key_matrix[i][j] for j in range (8 )] for i in range (4 )]
577+ state = inv_shift_rows(state)
578+ state = [[inv_sbox[state[i][j]] for j in range (8 )] for i in range (4 )]
579+
580+ for r in range (ROUNDS - 2 , - 1 , - 1 ):
581+ if r % 2 == 0 :
582+ state = [[state[i][j] ^ key_matrix[i][j] for j in range (8 )] for i in range (4 )]
583+ else :
584+ state = [[state[i][j] ^ tweak_matrix[i][j] for j in range (8 )] for i in range (4 )]
585+
586+ round_const_matrix = to_matrix(RCON [r])
587+ state = [[state[i][j] ^ round_const_matrix[i][j] for j in range (8 )] for i in range (4 )]
588+ state = inv_mix_columns(state)
589+ state = inv_shift_rows(state)
590+ state = [[inv_sbox[state[i][j]] for j in range (8 )] for i in range (4 )]
591+
592+ state = [[state[i][j] ^ key_matrix[i][j] for j in range (8 )] for i in range (4 )]
593+ return from_matrix(state)
594+
595+ # ##
596+
597+ class spAES :
598+ def __init__ (self , master_key ):
599+ self .master_key = master_key
600+ self .tweak = b " \x00 " * 16
601+
602+ def encrypt_ecb (self , plaintext ):
603+ plaintext = pad(plaintext, 16 )
604+ blocks = [plaintext[i:i+ 16 ] for i in range (0 , len (plaintext), 16 )]
605+ return b " " .join([enc(block, self .master_key, self .tweak) for block in blocks])
606+
607+ def decrypt_ecb (self , chipertext ):
608+ blocks = [chipertext[i:i+ 16 ] for i in range (0 , len (chipertext), 16 )]
609+ return unpad(b " " .join([dec(block, self .master_key, self .tweak) for block in blocks]), 16 )
610+ ```
611+
451612{{</details >}}
452613
614+
615+
453616Below the execution.
454617
455618```
0 commit comments