This branch contains the Coq development of the paper:
- SecurePtrs: Proving Secure Compilation Using Data-Flow Back-Translation nd Turn-Taking Simulation. Akram El-Korashy, Roberto Blanco, Jérémy Thibault, Adrien Durier, Deepak Garg, and Catalin Hritcu. arXiv:2110.01439. October 2021.
This development has been built with the following combinations of Coq releases and versioned libraries:
Coq 8.12.2
- Mathematical Components 1.11.0
- Extensional Structures 0.2.2
- Equations 1.2.4
Coq 8.13.2
- Mathematical Components 1.13.0
- Extensional Structures 0.3.1
- Equations 1.3
Coq 8.14.1
- Mathematical Components 1.13.0
- Extensional Structures 0.3.1
- Equations 1.3
Dependencies can be installed through the OCaml package manager, OPAM.
- Coq (package
coq
) is available through the official Ocaml OPAM repository. - Stable releases of Mathematical Components (packages
coq-mathcomp-ssreflect
,coq-mathcomp-fingroup
andcoq-mathcomp-algebra
), Extensional Structures (packagecoq-extructures
), and Equations (packagecoq-equations
) are available through the Coq OPAM repository.
Run make
at the root to build the development.
The following list maps the definitions and statements in the paper to their mechanized counterparts in Coq.
-
Definition 2.1 (RSP~): see statement of Theorem
RSC
inRSC.v
for an instance of this definition -
Assumption 2.3 (FCC):
S2I/Compiler.v
, Axiomforward_simulation_star
-
Lemma 2.4 (recomposition):
Intermediate/RecompositionRel.v
, Theoremrecombination_trace_rel
-
Assumption 2.5 (BCC):
S2I/Compiler.v
, Axiombackward_simulation_star
-
Definition 2.6 (interaction-trace events):
CompCert/Events.v
, Inductive typeevent
-
Definition 3.2 (data-flow events)
Common/TracesInform.v
, Inductive typeevent_inform
-
Lemma 3.4 (enrichment):
Intermediate/CS.v
, Lemmastar_sem_non_inform_star_sem_inform
-
Lemma 3.5 (data-flow back-translation):
Source/Definability.v
, Lemmadefinability
-
Definition 3.9 (turn-taking memory relation):
Intermediate/RecompositionRelCommon.v
, Inductive propositionmergeable_internal_states
-
Definition 3.10 (relation on interaction traces):
Common/RenamingOption.v
, Inductive propositiontraces_shift_each_other_option
-
Rule
Jump
(Section 4):Intermediate/CS.v
, caseJump
of inductivestep
-
Rule
Store
(Section 4):Intermediate/CS.v
, caseStore
of inductivestep
-
Theorem 4.1 (RSP~): Theorem
RSC
inRSC.v
-
Lemma 5.1 (trace prefix mimicking):
Source/Definability.v
, Lemmadefinability_gen_rel_right
-
Definition 5.2 (memory relation at interaction events):
Intermediate/RecompositionRelCommon.v
, Inductive propositionmergeable_border_states
-
Lemma 5.3 (strengthening at interaction events):
Intermediate/RecompositionRelStrengthening.v
, Theoremthreeway_multisem_event_lockstep_program_step
-
Lemma 5.4 (option simulation):
Intermediate/RecompositionRelOptionSim.v
, Lemmamerge_states_silent_star
-
Lemma 5.5 (lockstep simulation):
Intermediate/RecompositionRelLockstepSim.v
, Theoremthreeway_multisem_star_E0
-
Lemma 5.6 (symmetry of the turn-taking state simulation relation):
Intermediate/RecompositionRelCommon.v
, Lemmamergeable_internal_states_sym
All our results are admit-free and only rely, at most, on some of the axioms specified below. Any other axioms or admitted theorems found in the development are not used in our proofs.
To verify this, use the Coq command Print Assumptions
to examine the axioms
that apply to the theorems of interest. An index of the above definitions and
theorems is given at the end of the top-level file RSC.v
.
We leave some standard statements about the correct compilation of whole programs as axioms because they are not really the focus of our novel secure compilation proof techniques.
Proving these kind of correctness results is typically laborious and we do not expect the proof to be particularly insightful for our chosen pair of languages.
In fact, one of the key goals of the proof technique for the main secure compilation theorem is to demonstrate that standard results about correct compilation can be reused by (rather than implicitly reproved as part of) the secure compilation proof, since proving these theorems is typically a big manual effort that one would wish to avoid duplicating.
We assume that every well-formed source program can be successfully compiled
(well_formed_compilable
),
and that compiling preserves certain well-formedness conditions
(Compiler.compilation_preserves_well_formedness
,
compilation_preserves_main
, compilation_has_matching_mains
).
Compiler.well_formed_compilable
: forall (p : Source.program) (psz : {fmap Component.id -> nat}),
Source.well_formed_program p ->
exists pc : Intermediate.program, compile_program p psz = Some pc
Compiler.compilation_preserves_well_formedness
: forall (p : Source.program) (psz : {fmap Component.id -> nat})
(p_compiled : Intermediate.program),
Source.well_formed_program p ->
compile_program p psz = Some p_compiled ->
Intermediate.well_formed_program p_compiled
compilation_preserves_main
: forall (p : Source.program) (pstksize : {fmap Component.id -> nat})
(p_compiled : Intermediate.program),
Source.well_formed_program p ->
compile_program p pstksize = Some p_compiled ->
(exists main : expr, Source.prog_main p = Some main) <->
Intermediate.prog_main p_compiled
compilation_has_matching_mains
: forall (p : Source.program) (psz : {fmap Component.id -> nat})
(p_compiled : Intermediate.program),
Source.well_formed_program p ->
compile_program p psz = Some p_compiled -> matching_mains p p_compiled
We assume that the compiler satisfies separate_compilation
:
compilation and linking commute.
separate_compilation
: forall (p : Source.program) (psz : {fmap Component.id -> nat})
(c : Source.program) (csz : {fmap Component.id -> nat})
(p_comp c_comp : Intermediate.program),
Source.well_formed_program p ->
Source.well_formed_program c ->
linkable (Source.prog_interface p) (Source.prog_interface c) ->
compile_program p psz = Some p_comp ->
compile_program c csz = Some c_comp ->
compile_program (Source.program_link p c) (unionm psz csz) =
Some (Intermediate.program_link p_comp c_comp)
We also assume CompCert-style compiler correctness, in the form of a
forward simulation forward_simulation_star
and a backward simulation backward_simulation_star
:
Compiler.forward_simulation_star
: forall (p : Source.program) (t : Events.trace Events.event)
(s : state (S.CS.sem p)) (metasize : Component.id -> nat),
Source.closed_program p ->
Source.well_formed_program p ->
disciplined_program p ->
NoLeak.good_Elocal_usage_program p ->
Star (S.CS.sem p) (S.CS.initial_machine_state p) t s ->
exists
(s' : I.CS.state) (t' : Events.trace Events.event)
(psz : {fmap nat_ordType -> nat}) (p_compiled : Intermediate.program),
domm (T:=nat_ordType) (S:=nat) psz =
domm (T:=nat_ordType) (S:=Component.interface)
(Source.prog_interface p) /\
compile_program p psz = Some p_compiled /\
Star (I.CS.sem_non_inform p_compiled)
(I.CS.initial_machine_state p_compiled) t' s' /\
traces_shift_each_other_option metasize metasize t t'
Compiler.backward_simulation_star
: forall (p : Source.program) (psz : {fmap Component.id -> nat})
(p_compiled : Intermediate.program) (t : Events.trace Events.event)
(s : state (I.CS.sem_non_inform p_compiled))
(metasize : Component.id -> nat),
Source.closed_program p ->
Source.well_formed_program p ->
disciplined_program p ->
NoLeak.good_Elocal_usage_program p ->
compile_program p psz = Some p_compiled ->
Star (I.CS.sem_non_inform p_compiled)
(I.CS.initial_machine_state p_compiled) t s ->
exists (s' : state (S.CS.sem p)) (t' : Events.trace Events.event),
Star (S.CS.sem p) (S.CS.initial_machine_state p) t' s' /\
traces_shift_each_other_option metasize metasize t t'
Finally, we assume Compiler.compiler_preserves_non_leakage_of_private_pointers
,
which states that our compiler preserves the privacy of the local buffer.
Such a result can likely be proved by using the fine-grained simulation invariants
in an actual compiler correctness proof.
Compiler.compiler_preserves_non_leakage_of_private_pointers
: forall (p : Source.program) (psz : {fmap Component.id -> nat})
(p_compiled : Intermediate.program)
(metadata_size : Component.id -> nat),
Source.closed_program p ->
Source.well_formed_program p ->
compile_program p psz = Some p_compiled ->
S.CS.private_pointers_never_leak_S p metadata_size ->
private_pointers_never_leak_I p_compiled metadata_size
The following standard axioms are used occasionally in our proofs.
ProofIrrelevance.proof_irrelevance : forall (P : Prop) (p1 p2 : P), p1 = p2
FunctionalExtensionality.functional_extensionality_dep
: forall (A : Type) (B : A -> Type) (f g : forall x : A, B x),
(forall x : A, f x = g x) -> f = g
Classical_Prop.classic : forall P : Prop, P \/ ~ P
The source language SafeP
corresponds to Source
in the code. The target language Mach
corresponds to Intermediate
in the code.
- Backtranslation function
↑
: functionprocedures_of_trace
inSource/Definability.v
- Data-flow events
E
: inductiveevent_inform
inCommon/TracesInform.v
- Memory projection
proj_P(Mem)
: implicit in definitionsmem_of_part_executing_rel_original_and_recombined
andmem_of_part_not_executing_rel_original_and_recombined_at_internal
inIntermediate/RecompositionRelCommon.v
- Value renaming
valren
: functionrename_value_template_option
inCommon/RenamingOption.v
- The +1 block id renaming: Implemented by instantiating
shift_value_option
withuniform_shift 0
anduniform_shift 1
, inCommon/RenamingOption.v
- Turn-taking simulation invariant
state_rel_tt
: definitionmergeable_internal_states
inIntermediate/RecompositionRelCommon.v
- Turn-taking simulation relation
mem_rel_tt
: memory part of themergeable_internal_states
definition inIntermediate/RecompositionRelCommon.v
- Strong memory relation holding at all locations of the executing part
mem_rel_exec
: definitionmem_of_part_executing_rel_original_and_recombined
inIntermediate/RecompositionRelCommon.v
- Memory relation holding only at private locations of the non-executing part
mem_rel_not_exec
: definitionmem_of_part_not_executing_rel_original_and_recombined_at_internal
inIntermediate/RecompositionRelCommon.v
- Function
shared
: inductiveaddr_shared_so_far
inCommon/RenamingOption.v
- Function
private
: negation of the inductiveaddr_shared_so_far
inCommon/RenamingOption.v
- Linking
C ∪ P
: functionsprogram_link
inSource/Language.v
andIntermediate/Machine.v
- Trace relation
~
: definitiontraces_shift_each_other_option
inCommon/RenamingOption.v
- Compilation function
↓
: functioncompile_program
inS2I/Compiler.v
- Step relation
⇝
: definitionskstep
inSource/CS.v
;step_non_inform
for non-data-flow semantics andstep
for data-flow semantics inIntermediate/CS.v
- Reflexive transitive closure
^*
: inductivestar
inCompCert/Smallstep.v
- Interaction (non-data-flow) events
e
: definitionevent
inCompCert/Events.v
- Memory
Mem
ormem
: ModuleMemory
inCommon/Memory.v
- Component memory
cMem
: ModuleComponentMemory
inCommon/Memory.v
- Source (SafeP) expressions
exp
: definitionexpr
inSource/Language.v
- Target (Mach) instructions
instr
: definitioninstr
inIntermediate/Machine.v
- Values
v
: definitionvalue
inCommon/Values.v
- Removal of all internal data-flow events
remove_df
: functionproject_non_inform
inCommon/TracesInform.v
- Back-translation
mimicking_state
invariant: definitionwell_formed_state
inSource/Definability.v
- Back-translation of a data-flow event: definition
expr_of_event
inSource/Definability.v
- Trace concatenation
++
: functionEapp
inCompCert/Events.v
- Border-state relation
state_rel_border
: definitionmergeable_border_states
inIntermediate/RecompositionRelCommon.v
- "Is executing in" relation:
is_program_component
andis_context_component
inIntermediate/CS.v
- This code is licensed under the Apache License, Version 2.0 (see
LICENSE
) - The code in the
CompCert
dir is adapted based on files in thecommon
andlib
dirs of CompCert and is thus dual-licensed under the INRIA Non-Commercial License Agreement and the GNU General Public License version 2 or later (seeCompCert/LICENSE
)