Overview
The Constant-Time Analysis plugin detects timing side-channel vulnerabilities by analyzing compiler output and runtime bytecode for dangerous operations:- Division on secrets - Hardware division timing varies based on operand values
- Secret-dependent branches - Different execution paths have different timing
- Floating-point operations - Variable latency based on inputs
- Non-constant comparisons - Early-exit string/memory comparison
This tool performs static analysis only - it flags potentially dangerous operations but requires manual verification to confirm whether they process secret data.
Supported Languages
Native Compiled Languages
Analyzes assembly output from compilers:- C/C++ - GCC, Clang
- Go - Go compiler
- Rust - Rustc
- Swift - swiftc (iOS/macOS)
VM-Compiled Languages
Analyzes bytecode (JVM/CIL):- Java - JVM bytecode via
javap - Kotlin - JVM bytecode via
kotlinc - C# - CIL bytecode via
ilspycmd
Interpreted/Scripting Languages
Analyzes VM bytecode or opcodes:- PHP - VLD extension or opcache
- JavaScript/TypeScript - V8 bytecode
- Python - CPython bytecode via
dis - Ruby - YARV bytecode
Key Features
Multi-Architecture
Supports x86_64, ARM64, ARM, RISC-V, PowerPC, s390x, i386 for cross-platform analysis
Optimization Testing
Test across O0-O3, Os, Oz to catch optimization-induced vulnerabilities
CI Integration
GitHub Actions annotations and JSON output for automated security checks
Real-World Coverage
Detects vulnerability classes from KyberSlash, Lucky Thirteen, and RSA timing attacks
Installation
Usage
Basic Analysis
Advanced Options
Target architecture: x86_64, arm64, arm, riscv64, ppc64le, s390x, i386
Optimization level: O0, O1, O2, O3, Os, Oz
Include conditional branch warnings
Filter to specific functions by pattern
Output JSON format for CI integration
Cross-Architecture Testing
CI Integration
GitHub Actions
/ct-check Command
The plugin provides a slash command for quick analysis:constant-time-analysis skill with full workflow execution.
Detected Vulnerabilities
Error-Level (Must Fix)
- x86_64
- ARM64
- RISC-V
Integer Division:
DIV, IDIV, DIVQ, IDIVQFP Division: DIVSS, DIVSD, DIVPS, DIVPDSquare Root: SQRTSS, SQRTSD, SQRTPS, SQRTPDWarning-Level (Review Needed)
Conditional branches that may leak timing if condition depends on secret data:- x86:
JE,JNE,JZ,JNZ,JA,JB,JG,JL - ARM:
BEQ,BNE,CBZ,CBNZ,TBZ,TBNZ - RISC-V:
BEQ,BNE,BLT,BGE
Interpreting Results
Example Output
Verifying Results (Critical)
For each flagged violation:- Identify secret inputs - Private keys, plaintext, signatures, tokens
- Trace data flow - Does the flagged instruction process secret-derived values?
- Apply triage questions:
Is the operand a compile-time constant?
Is the operand a compile-time constant?
Likely false positive - Constants don’t leak timing information
Is the operand a public parameter?
Is the operand a public parameter?
Likely false positive - Length/count parameters are usually safe
Is the operand derived from secrets?
Is the operand derived from secrets?
TRUE POSITIVE - Secret-dependent operations leak timing
Can an attacker influence the operand?
Can an attacker influence the operand?
TRUE POSITIVE - Attacker-controlled values enable timing attacks
Fixing Vulnerabilities
Replace Division with Barrett Reduction
Replace Branches with Constant-Time Selection
Replace Comparisons
Language-Specific Detection
PHP Analysis
Detected patterns:- Division:
ZEND_DIV,ZEND_MOD→ Use Barrett reduction - String comparison:
strcmp(),===on secrets → Usehash_equals() - Weak RNG:
rand(),mt_rand()→ Userandom_int()/random_bytes() - Cache timing:
chr(),ord()→ Usepack()/unpack()
JavaScript/TypeScript Analysis
Detected patterns:- Division:
Div,Modbytecodes → Use constant-time multiply-shift - String comparison:
===on secrets → Usecrypto.timingSafeEqual() - Weak RNG:
Math.random()→ Usecrypto.getRandomValues() - Variable latency:
Math.sqrt(),Math.pow()→ Avoid in crypto paths
Python Analysis
Detected patterns:- Division:
BINARY_OP 11 (/),BINARY_OP 6 (%)→ Use Barrett reduction - String comparison:
==on secrets → Usehmac.compare_digest() - Weak RNG:
random.random()→ Usesecrets.token_bytes() - Variable latency:
math.sqrt(),math.pow()→ Avoid in crypto paths
Ruby Analysis
Detected patterns:- Division:
opt_div,opt_mod→ Use constant-time alternatives - String comparison:
==on secrets → UseRack::Utils.secure_compare() - Weak RNG:
rand()→ UseSecureRandom.random_bytes() - Variable latency:
Math.sqrt()→ Avoid in crypto paths
Limitations
Real-World Impact
- KyberSlash (2023) - Division instructions in ML-KEM allowed key recovery
- Lucky Thirteen (2013) - CBC padding timing enabled plaintext recovery
- RSA Timing Attacks - Division timing leaked private key bits
Related Plugins
- Property-Based Testing - Test crypto invariants
- Zeroize Audit - Verify secret cleanup
- Testing Handbook Skills - Security testing techniques
References
Author: Scott Arciszewski (Trail of Bits)Version: 0.1.0