Rob Turner, Qualcomm Technologies
Almost three decades since the Morris worm and we're still plagued by memory corruption vulnerabilities in C and C++ software. Exploit mitigations aim to make the exploitation of these vulnerabilities impossible or prohibitively expensive. However, modern exploits demonstrate that currently deployed countermeasures are insufficient.
In ARMv8.3, ARM introduces a new hardware security feature, pointer authentication. With ARM and ARM partners, including Microsoft, we helped to design this feature. Designing a processor extension is challenging. Among other requirements, changes should be transparent to developers (except compiler developers), support both system and application code, interoperate with legacy software, and provide binary backward compatibility. This talk discusses the processor extension and explores the design trade-offs, such as the decision to prefer authentication over encryption and the consequences of small tags.
Also, this talk provides a security analysis, and examines how these new instructions can robustly and efficiently implement countermeasures.
18. 18
The Key Idea
• Use the unused bits in pointers to store an authentication code. Verify the authentication code
before dereferencing the pointer.
• Two Operations:
◦ Compute an authentication code and tag a pointer.
◦ Verify a pointer by recomputing the authentication code and comparing it with the pointer’s
tag.
23. 23
Scope and Design Criteria
• AARCH64 Only
• Minimally Invasive
• Compatible and Interoperable
24. 24
Instructions
• PAC*
◦ PACIA, PACIB, PACDA, PACDB, …
◦ Compute an authentication code and tag a pointer.
• AUTH*
◦ AUTHIA, AUTHIB, AUTHDA, AUTHDB, …
◦ Verify a pointer by recomputing the authentication code and comparing it with the pointer’s
tag.
25. 25
Some Details
• The authentication code is computed based on only the virtual address bits.
38. 38
Instructions
• PAC*
◦ PACIA, PACIB, PACDA, PACDB, …
◦ Compute an authentication code and tag a pointer.
• AUTH*
◦ AUTHIA, AUTHIB, AUTHDA, AUTHDB, …
◦ Verify a pointer by recomputing the authentication code and comparing it with the pointer’s
tag.
• PACGA
◦ Compute an authentication code.
• XPACI, XPACD
◦ Strip an authentication code from a pointer without verification.
40. 40
Context
• Contexts are an additional, public input to the authentication algorithm, specified explicitly as
an input register or implicitly by the instruction variant.
• Contexts mitigate pointer substitution attacks: maliciously overwriting a tagged pointer with a
different tagged pointer.
• Contexts can “emulate” the granularity of other control-flow integrity schemes.
◦ Microsoft’s Control-Flow Guard
◦ LLVM’s Cross-DSO Control-Flow Integrity
◦ Abadi Control-Flow Integrity
◦ Cryptographically-Enforced Control-Flow Integrity
42. 42
QARMA
• We need a fast, lightweight algorithm.
◦ Cryptographically strong when truncated for short authentication codes.
◦ Two 64-bit inputs, a 128-bit key, and a 64-bit output.
• Enter QARMA.
◦ A new family of lightweight, tweakable ciphers.
• Block Cipher:
◦ f(secret key, plaintext) -> ciphertext
• Tweakable Block Cipher:
◦ f(secret key, plaintext, tweak) -> ciphertext
43. 43
Key Management
• Five 128-Bit Keys
◦ Two keys for pointers to instructions
◦ Two keys for pointers to data
◦ One key for the generic MAC instruction
◦ One key to rule them all and in the darkness bind them
• Keys are not banked per Exception Level.
• System register controls for keys and instructions:
◦ Trap key use to Exception Level 2 or Exception Level 3.
◦ Trap instruction use to Exception Level 2 or Exception Level 3.
◦ Disable instructions for individual keys for backwards compatibility.
48. 48
Expected Usage
• TrustZone / Secure Execution Environments
◦ Address Space can be reduced to allow longer authentication codes.
• Compiler Instrumentation
◦ Stack-Smashing Protection (SSP)
◦ Control-Flow Integrity (CFI)
• Compiler Built-ins
• Type and Variable Attributes
49. 49
Stack-Smashing Protection (SSP)
• Without SSP • With Software SSP • With PA SSP
ldr x1, [x3, #SSP]
ldr x2, [sp, #0x38]
cmp x1, x2
b.ne __stack_chk_fail
ldp x29, x30, [sp, #0x40]
add sp, sp, #0x50
ret
ldp x29, x30, [sp, #0x30]
add sp, sp, #0x40
retaa
ldp x29,x30,[sp,#0x30]
add sp,sp,#0x40
ret
sub sp, sp, #0x50
stp x29, x30, [sp, #0x40]
add x29, sp, #0x40
adrp x3, {pc}
ldr x4, [x3, #SSP]
str x4, [sp, #0x38]
paciasp
sub sp,sp,#0x40
stp x29, x30, [sp, #0x30]
add x29, sp, #0x30
sub sp, sp, #0x40
stp x29, x30, [sp,#0x30]
add x29, sp, #0x30
• Tag the saved return address. The context is the stack pointer.
insert canary into the stack
increased
frame size
the global canary
verify lr with sp as context
tag lr using
sp as context
50. 50
C Runtime Protections
• Linker and loader data structures
◦ Import Address Table (IAT) addresses
• C Standard Library (msvcrt.dll)
◦ struct jmp_buf pointers
◦ atexit() callback
• APIs
◦ Microsoft’s Encode*Pointer and Decode*Pointer and glibc’s PTR_MANGLE
• Tag all the things! (CFI)
51. 51
Coming Soon to a Processor Near You!
Conclusion
• Pointer authentication
◦ provides a new software security primitive, with good code size properties.
◦ can implement generic countermeasures.
• Stack-Smashing Protection (SSP) and Control-Flow Integrity (CFI)
◦ complements and improves existing mitigations.
• Best results will come from domain-specific hardening.
◦ Identifying and protecting sensitive pointers and data structures.
• Socialize ideas as widely as possible.