LIF
Isochronous transformation and taint analysis for side-channel mitigation.
Headers: include/Security/LIF
Implementation: lib/Security/LIF
Build target: CanaryLIF
Overview
The LIF subsystem combines a taint analysis with IR-to-IR transformations
that rewrite code into a more isochronous form. Its goal is mitigation rather
than bug finding: instead of only reporting secret-dependent control flow, it
can transform functions so they execute a uniform set of instructions
regardless of sensitive inputs.
The implementation lives under the unified lib/Security tree alongside the
ConstantTime and Spectre components.
Main Components
TaintAnalysis
Files: Taint.h, Taint.cpp
lotus::lif::analysis::TaintAnalysis traverses the module call graph and
marks values that depend on secret data.
Key properties:
secrets are discovered from
annotate("secret")metadatataint propagates through both data and selected control dependencies
the analysis is aware of later linearization, so it does not blindly taint every control-dependent value
IsochronousPass
Files: Isochronous.h, Isochronous.cpp
lotus::lif::transform::IsochronousPass rewrites functions into an
isochronous form.
An isochronous function is intended to execute the same set of instructions regardless of inputs, which is useful for mitigating side-channel leakage.
Control-Flow Representation
Files:
CCFG.h,CCFG.cppLoop.h,Loop.cppCond.h,Cond.cppFunc.h,Func.cpp
These helpers support the transformation:
CCFGbuilds a collapsed control-flow graph with loops summarized into acyclic nodesLoopWrapperrecords loop headers, latches, exits, and synthetic phi nodes needed for transformationcondition binding computes incoming and outgoing predicates for basic blocks
function rewriting performs partial linearization and instruction rewriting
Transformation Strategy
The implementation follows a control-flow linearization approach inspired by partial linearization work such as Moll and Hack’s PLDI paper.
At a high level, the pass:
runs taint analysis to find secret-dependent values
prepares loop and control-flow metadata
computes block and edge conditions
partially linearizes secret-dependent control flow
rewrites loads, stores, phi nodes, and selected interfaces so execution is more uniform
Public API
Important types and entry points include:
lotus::lif::analysis::TaintAnalysislotus::lif::analysis::TaintedInfolotus::lif::transform::IsochronousPasslotus::lif::transform::FuncWrapperlotus::lif::transform::LoopWrapper
Usage Notes
The transformation expects LLVM IR with enough structure for loop and CFG reasoning. In particular, the isochronous pass assumes functions have unique exit points.
Typical use cases:
mitigating secret-dependent branches in sensitive code
experimenting with constant-time or uniform-execution rewrites
building research prototypes for side-channel-resistant transformations