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-fingroupandcoq-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
RSCinRSC.vfor 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, caseJumpof inductivestep -
Rule
Store(Section 4):Intermediate/CS.v, caseStoreof inductivestep -
Theorem 4.1 (RSP~): Theorem
RSCinRSC.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_compiledWe 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_sizeThe 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 \/ ~ PThe source language SafeP corresponds to Source in the code. The target language Mach corresponds to Intermediate in the code.
- Backtranslation function
↑: functionprocedures_of_traceinSource/Definability.v - Data-flow events
E: inductiveevent_informinCommon/TracesInform.v - Memory projection
proj_P(Mem): implicit in definitionsmem_of_part_executing_rel_original_and_recombinedandmem_of_part_not_executing_rel_original_and_recombined_at_internalinIntermediate/RecompositionRelCommon.v - Value renaming
valren: functionrename_value_template_optioninCommon/RenamingOption.v - The +1 block id renaming: Implemented by instantiating
shift_value_optionwithuniform_shift 0anduniform_shift 1, inCommon/RenamingOption.v - Turn-taking simulation invariant
state_rel_tt: definitionmergeable_internal_statesinIntermediate/RecompositionRelCommon.v - Turn-taking simulation relation
mem_rel_tt: memory part of themergeable_internal_statesdefinition inIntermediate/RecompositionRelCommon.v - Strong memory relation holding at all locations of the executing part
mem_rel_exec: definitionmem_of_part_executing_rel_original_and_recombinedinIntermediate/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_internalinIntermediate/RecompositionRelCommon.v - Function
shared: inductiveaddr_shared_so_farinCommon/RenamingOption.v - Function
private: negation of the inductiveaddr_shared_so_farinCommon/RenamingOption.v - Linking
C ∪ P: functionsprogram_linkinSource/Language.vandIntermediate/Machine.v - Trace relation
~: definitiontraces_shift_each_other_optioninCommon/RenamingOption.v - Compilation function
↓: functioncompile_programinS2I/Compiler.v - Step relation
⇝: definitionskstepinSource/CS.v;step_non_informfor non-data-flow semantics andstepfor data-flow semantics inIntermediate/CS.v - Reflexive transitive closure
^*: inductivestarinCompCert/Smallstep.v - Interaction (non-data-flow) events
e: definitioneventinCompCert/Events.v - Memory
Memormem: ModuleMemoryinCommon/Memory.v - Component memory
cMem: ModuleComponentMemoryinCommon/Memory.v - Source (SafeP) expressions
exp: definitionexprinSource/Language.v - Target (Mach) instructions
instr: definitioninstrinIntermediate/Machine.v - Values
v: definitionvalueinCommon/Values.v - Removal of all internal data-flow events
remove_df: functionproject_non_informinCommon/TracesInform.v - Back-translation
mimicking_stateinvariant: definitionwell_formed_stateinSource/Definability.v - Back-translation of a data-flow event: definition
expr_of_eventinSource/Definability.v - Trace concatenation
++: functionEappinCompCert/Events.v - Border-state relation
state_rel_border: definitionmergeable_border_statesinIntermediate/RecompositionRelCommon.v - "Is executing in" relation:
is_program_componentandis_context_componentinIntermediate/CS.v
- This code is licensed under the Apache License, Version 2.0 (see
LICENSE) - The code in the
CompCertdir is adapted based on files in thecommonandlibdirs 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)