1+ #include <stdlib.h>
2+ #include <stdint.h>
3+ #include <stdbool.h>
4+ #include "DPE.h"
5+ #include "EngineCore.h"
6+
7+ _include_pulse (
8+ $declare (context_t s )
9+ [@@erasable ]
10+ noeq type context_full_data =
11+ | PL_Engine of (Seq .seq UInt8 .t )
12+ | PL_L0 of (Seq .seq UInt8 .t )
13+ | PL_L1 // tbd
14+
15+ let tag_relation ($ (s ): $type (context_t )) (h : context_full_data ) : prop =
16+ match $ (s .tag ) with
17+ | 0u y -> Field__u_context_t__uds ? $ (s .payload ) /\ PL_Engine ? h
18+ | 1u y -> Field__u_context_t__cdi ? $ (s .payload ) /\ PL_L0 ? h
19+ | 2u y -> Field__u_context_t__l1_context ? $ (s .payload ) /\ PL_L1 ? h
20+ | _ -> False
21+ )
22+
23+ _include_pulse (
24+ $declare (context_t s )
25+
26+ let context_full_pred ([@@@mkey ] $ (s ): $type (context_t )) (h : context_full_data ) : slprop =
27+ match $ (s .payload ), h with
28+ | Field__u_context_t__uds uds_ptr , PL_Engine uds_data ->
29+ uds_ptr |- > uds_data * * freeable_array uds_ptr
30+ | Field__u_context_t__cdi cdi_ptr , PL_L0 cdi_data ->
31+ cdi_ptr |- > cdi_data * * freeable_array cdi_ptr
32+ | Field__u_context_t__l1_context _ , PL_L1 ->
33+ emp
34+ | _ -> pure False
35+
36+ let engine_state ($ (s ): $type (context_t )) #x =
37+ observe (context_full_pred $ (s )) #x
38+
39+ ghost fn elim_context_full_pred_uds ($ (s ): $type (context_t )) (#h : context_full_data )
40+ requires with_pure (tag_relation $ (s ) h /\ PL_Engine ? h )
41+ requires context_full_pred $ (s ) h
42+ ensures Pulse .Lib .Array .pts_to $ (s .payload .uds ) (PL_Engine ?._0 h )
43+ ensures freeable_array $ (s .payload .uds )
44+ {
45+ unfold context_full_pred ;
46+ rewrite each $ (s .payload ) as Field__u_context_t__uds $ (s .payload .uds );
47+ rewrite each h as PL_Engine (PL_Engine ?._0 h );
48+ }
49+
50+ ghost fn elim_context_full_pred_cdi ($ (s ): $type (context_t )) (#h : context_full_data )
51+ requires with_pure (tag_relation $ (s ) h /\ PL_L0 ? h )
52+ requires context_full_pred $ (s ) h
53+ ensures Pulse .Lib .Array .pts_to $ (s .payload .cdi ) (PL_L0 ?._0 h )
54+ ensures freeable_array $ (s .payload .cdi )
55+ {
56+ unfold context_full_pred ;
57+ rewrite each $ (s .payload ) as Field__u_context_t__cdi $ (s .payload .cdi );
58+ rewrite each h as PL_L0 (PL_L0 ?._0 h );
59+ }
60+
61+ ghost fn elim_context_full_pred_l1 ($ (s ): $type (context_t )) (#h : context_full_data )
62+ requires with_pure (tag_relation $ (s ) h /\ PL_L1 ? h )
63+ requires context_full_pred $ (s ) h
64+ {
65+ unfold context_full_pred ;
66+ rewrite each $ (s .payload ) as Field__u_context_t__l1_context $ (s .payload .l1_context );
67+ rewrite each h as PL_L1 ;
68+ }
69+
70+ ghost fn intro_context_full_pred_uds ($ (s ): $type (context_t )) #uds
71+ requires with_pure (tag_relation $ (s ) (PL_Engine uds ))
72+ requires Pulse .Lib .Array .pts_to $ (s .payload .uds ) uds
73+ requires freeable_array $ (s .payload .uds )
74+ ensures context_full_pred $ (s ) (PL_Engine uds )
75+ {
76+ rewrite $ (s .payload .uds ) |-> uds * * freeable_array $ (s .payload .uds )
77+ as context_full_pred $ (s ) (PL_Engine uds );
78+ }
79+
80+ ghost fn intro_context_full_pred_cdi ($ (s ): $type (context_t )) #cdi
81+ requires with_pure (tag_relation $ (s ) (PL_L0 cdi ))
82+ requires Pulse .Lib .Array .pts_to $ (s .payload .cdi ) cdi
83+ requires freeable_array $ (s .payload .cdi )
84+ ensures context_full_pred $ (s ) (PL_L0 cdi )
85+ {
86+ rewrite $ (s .payload .cdi ) |-> cdi * * freeable_array $ (s .payload .cdi )
87+ as context_full_pred $ (s ) (PL_L0 cdi );
88+ }
89+ )
90+
91+ void memcpy_ (size_t len , _array const uint8_t * a1 , _array uint8_t * a2 )
92+ _preserves (a1 ._length == len )
93+ _preserves (a2 ._length == len )
94+ _ensures ((_slprop ) _inline_pulse (rewrites_to (value_of $ (a2 )) (value_of $ (a1 ))))
95+ {
96+ _ghost_stmt (admit ());
97+ }
98+
99+ void free_ (_consumes _allocated_array _array uint8_t * arr )
100+ {
101+ _ghost_stmt (admit ());
102+ }
103+
104+ _refine ((_slprop ) _inline_pulse (
105+ exists * state .
106+ pure (tag_relation $ (* this ) state ) * *
107+ context_full_pred $ (* this ) state ))
108+ typedef context_t * context_obj ;
109+
110+ _allocated
111+ typedef context_obj allocated_context_obj ;
112+ allocated_context_obj init_engine_context (const uds_array uds )
113+ _ensures ((bool ) _inline_pulse (engine_state $ (* return ) == PL_Engine (value_of $ (uds ))))
114+ {
115+ uint8_t * uds_buf = (uint8_t * )calloc (UDS_LEN , sizeof (uint8_t ));
116+ memcpy_ (UDS_LEN , uds , uds_buf );
117+ context_t * ctx = (context_t * )malloc (sizeof (context_t ));
118+ * ctx = (context_t ) {
119+ .tag = ENGINE_CONTEXT ,
120+ .payload = (u_context_t ) { .uds = uds_buf },
121+ };
122+ _ghost_stmt (intro_context_full_pred_uds $ (* ctx ));
123+ return ctx ;
124+ }
125+
126+ _include_pulse (
127+ ghost fn elim_maybe_true (p :slprop )
128+ requires maybe _true_ p
129+ ensures p
130+ { unfold maybe ; }
131+ )
132+
133+ void init_l0_context (context_obj ctx , const dice_digest cdi )
134+ _requires ((bool ) _inline_pulse (PL_Engine ? (engine_state $ (* ctx ))))
135+ _ensures ((bool ) _inline_pulse (engine_state $ (* ctx ) == PL_L0 (value_of $ (cdi ))))
136+ {
137+ uint8_t * cdi_buf = (uint8_t * )calloc (DICE_DIGEST_LEN , sizeof (uint8_t ));
138+ memcpy_ (DICE_DIGEST_LEN , cdi , cdi_buf );
139+ _ghost_stmt (elim_context_full_pred_uds $ (* ctx ));
140+ uint8_t * uds_buf = ctx -> payload .uds ;
141+ free_ (uds_buf );
142+ ctx -> tag = 1 ;
143+ ctx -> payload .cdi = cdi_buf ;
144+ _ghost_stmt (intro_context_full_pred_cdi $ (* ctx ));
145+ return ;
146+ }
147+
148+ void destroy_uds_context (_consumes _allocated context_obj ctx )
149+ _requires (ctx -> tag == 0 )
150+ {
151+ _ghost_stmt (elim_context_full_pred_uds $ (* ctx ));
152+ uint8_t * uds_buf = ctx -> payload .uds ;
153+ free_ (uds_buf );
154+ free (ctx );
155+ return ;
156+ }
157+
158+ void mk_l0_context (context_obj ctx , _consumes _allocated_array dice_digest cdi )
159+ _requires (ctx -> tag == 0 )
160+ _ensures ((bool ) _inline_pulse (engine_state $ (* ctx ) == PL_L0 (old (value_of $ (cdi )))))
161+ {
162+ _assert (cdi ._length == DICE_DIGEST_LEN );
163+ _ghost_stmt (elim_context_full_pred_uds $ (* ctx ));
164+ uint8_t * uds_buf = ctx -> payload .uds ;
165+ free_ (uds_buf );
166+ ctx -> tag = 1 ;
167+ ctx -> payload .cdi = cdi ;
168+ _ghost_stmt (intro_context_full_pred_cdi $ (* ctx ));
169+ }
170+
171+ bool derive_child_from_context (context_obj ctx , const engine_record_t * record )
172+ _requires (ctx -> tag == 0 )
173+ _ensures (return == > (bool ) _inline_pulse (PL_L0 ? (engine_state $ (* ctx ))))
174+ _ensures (!return == > (bool ) _inline_pulse (engine_state $ (* ctx ) == old (engine_state $ (* ctx ))))
175+ {
176+ _ghost_stmt (elim_context_full_pred_uds $ (* ctx ));
177+ uint8_t * cdi_buf = (uint8_t * )calloc (DICE_DIGEST_LEN , sizeof (uint8_t ));
178+ // _assert(cdi_buf._length == DICE_DIGEST_LEN);
179+ bool ok = false; // engine_main(cdi_buf, ctx->payload.uds, record);
180+ if (ok ) {
181+ _ghost_stmt (intro_context_full_pred_uds $ (* ctx ));
182+ mk_l0_context (ctx , cdi_buf );
183+ return true;
184+ } else {
185+ _ghost_stmt (intro_context_full_pred_uds $ (* ctx ));
186+ free_ (cdi_buf );
187+ return false;
188+ }
189+ }
0 commit comments