(* Lemma generate_correct: forall should_reseed non_empty_additional s initial_state_abs out_len contents, hmac256drbgabs_reseed_interval initial_state_abs = 10000 -> hmac256drbgabs_entropy_len initial_state_abs = 32 -> out_len >? 1024 = false -> Zlength contents >? 256 = false -> (should_reseed = true -> exists entropy_bytes s', get_entropy 256 (hmac256drbgabs_entropy_len initial_state_abs) (hmac256drbgabs_entropy_len initial_state_abs) (hmac256drbgabs_prediction_resistance initial_state_abs) s = ENTROPY.success entropy_bytes s') -> should_reseed = (hmac256drbgabs_prediction_resistance initial_state_abs || (hmac256drbgabs_reseed_counter initial_state_abs >? hmac256drbgabs_reseed_interval initial_state_abs))%bool -> non_empty_additional = (if should_reseed then false else match contents with | [] => false | _ :: _ => true end) -> mbedtls_HMAC256_DRBG_generate_function s initial_state_abs out_len contents = ENTROPY.success ( (sublist 0 out_len (snd (HMAC_DRBG_generate_helper_Z HMAC256 (hmac256drbgabs_key (if non_empty_additional then hmac256drbgabs_hmac_drbg_update initial_state_abs contents else if should_reseed then hmac256drbgabs_reseed initial_state_abs s contents else initial_state_abs)) (hmac256drbgabs_value (if non_empty_additional then hmac256drbgabs_hmac_drbg_update initial_state_abs contents else if should_reseed then hmac256drbgabs_reseed initial_state_abs s contents else initial_state_abs)) out_len))), (hmac256drbgabs_to_state_handle (hmac256drbgabs_increment_reseed_counter (hmac256drbgabs_hmac_drbg_update (hmac256drbgabs_update_value (if non_empty_additional then hmac256drbgabs_hmac_drbg_update initial_state_abs contents else if should_reseed then hmac256drbgabs_reseed initial_state_abs s contents else initial_state_abs) (fst (HMAC_DRBG_generate_helper_Z HMAC256 (hmac256drbgabs_key (if non_empty_additional then hmac256drbgabs_hmac_drbg_update initial_state_abs contents else if should_reseed then hmac256drbgabs_reseed initial_state_abs s contents else initial_state_abs)) (hmac256drbgabs_value (if non_empty_additional then hmac256drbgabs_hmac_drbg_update initial_state_abs contents else if should_reseed then hmac256drbgabs_reseed initial_state_abs s contents else initial_state_abs)) out_len))) (if should_reseed then [] else contents)))) ) (if should_reseed then get_stream_result (mbedtls_HMAC256_DRBG_reseed_function s initial_state_abs contents) else s). *)(* Require Import hmacdrbg.verif_gen_c1. Declare Module M :Continuation1. *)
(* Definition postReseedCtx s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc1 mc2 mc3 b i: mpred := match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with ENTROPY.success (RSVal, RSKey, aa, bb, cc) s0 => data_at Tsh t_struct_hmac256drbg_context_st (mc1, (mc2, mc3), (map Vint (map Int.repr RSVal), (Vint (Int.repr aa), (Vint (Int.repr entropy_len), (Val.of_bool cc, Vint (Int.repr reseed_interval)))))) (Vptr b i) | _ => FF end. *)
(* Definition postReseedCtx (CTX:reptype t_struct_hmac256drbg_context_st) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents (mc:mdstate): Prop := match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with ENTROPY.success (RSVal, RSKey, aa, bb, cc) s0 => CTX = (mc, (map Vint (map Int.repr RSVal), (Vint (Int.repr aa), (Vint (Int.repr entropy_len), (Val.of_bool cc, Vint (Int.repr reseed_interval)))))) | _ => False end.  Definition postReseedKey s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc1 mc2 mc3: mpred := match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with ENTROPY.success (RSVal, RSKey, aa, bb, cc) s0 => md_full RSKey (mc1, (mc2, mc3)) | _ => FF end.  Definition postReseedStream s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents: mpred := match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with ENTROPY.success (RSVal, RSKey, aa, bb, cc) s0 => Stream s0 | _ => FF end.  Definition mkCTX0 (should_reseed:bool) (initial_state:reptype t_struct_hmac256drbg_context_st) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc p: mpred := EX myctx:reptype t_struct_hmac256drbg_context_st%type, (!!(if should_reseed then postReseedCtx myctx s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc else myctx = initial_state)) && data_at Tsh t_struct_hmac256drbg_context_st myctx p.*)
(*alternative definitions that don't help Definition myMpred0 (should_reseed:bool) initial_state s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc p: mpred := EX myctx:(val * (val * val) * (list val * (val * (val * (val * val)))))%type, (!!(if should_reseed then postReseedCtx myctx s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc else myctx = initial_state)) && data_at Tsh t_struct_hmac256drbg_context_st myctx p. Definition myMpred1 (should_reseed:bool) initial_state s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc p: mpred := EX q1:val, EX q2:val, EX q3:val, EX q4:list val, EX q5:val, EX q6:val, EX q7:val, EX q8:val, (!!(if should_reseed then postReseedCtx (q1, (q2, q3), (q4, (q5, (q6, (q7, q8))))) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc else (q1, (q2, q3), (q4, (q5, (q6, (q7, q8))))) = initial_state)) && data_at Tsh t_struct_hmac256drbg_context_st (q1, (q2, q3), (q4, (q5, (q6, (q7, q8))))) p. *)
(* Definition mkCTX1 (should_reseed:bool) (ctx ctx1:reptype t_struct_hmac256drbg_context_st) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents mc: Prop := if should_reseed then match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with | ENTROPY.success (RSVal, _, aa, _, cc) _ => ctx1 = (mc, (map Vint (map Int.repr RSVal), (Vint (Int.repr aa), (Vint (Int.repr entropy_len), (Val.of_bool cc, Vint (Int.repr reseed_interval)))))) | ENTROPY.error _ _ => False end else ctx1 = ctx.  Definition mkKEY1 (should_reseed:bool) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents key1 : Prop:= if should_reseed then match mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance reseed_interval) (contents_with_add additional (Zlength contents) contents) with | ENTROPY.success (_, RSKey, _, _, _) _ => key1 = RSKey | ENTROPY.error _ _ => False end else key1=key.*)
Definition mkSTREAM1 (should_reseed:bool) s key V reseed_counter entropy_len prediction_resistance reseed_interval additional contents stream1 : Prop :=
if should_reseed
then
match
mbedtls_HMAC256_DRBG_reseed_function s
(HMAC256DRBGabs key V reseed_counter entropy_len prediction_resistance
reseed_interval)
(contents_with_add additional (Zlength contents) contents)
with
| ENTROPY.success (_, _, _, _, _) s0 => stream1 = s0
| ENTROPY.error _ _ => False
end
else stream1 = s.
(* IT'S PATHETIC THAT WE NEED TO INTRDUCE ctx2' AND a predicate CTXeq to wotk around FLOYD'S typechecker!!*)
(*Definition CTXeq (c:reptype t_struct_hmac256drbg_context_st) (c':(val * (val * val) * (list val * (val * (val * (val * val)))))%type) : Prop := c'=c. *)
Definition is_multiple (multiple base: Z) : Prop := exists i, multiple = (i * base)%Z.

(* Specifications: *)
Lemma entailment1: forall (contents : list byte) (additional: val) (sha: share) (output : val) (sho: share)
(out_len : Z) (b : block) (i : ptrofs) (shc: share) (mc1 mc2 mc3 : val) (key V : list byte)
(reseed_counter entropy_len : Z) (prediction_resistance : bool)
(reseed_interval : Z) (gv : globals) (Info : md_info_state)
(s : ENTROPY.stream)
(I := HMAC256DRBGabs key V reseed_counter entropy_len
prediction_resistance reseed_interval : hmac256drbgabs)
(a := (mc1, (mc2, mc3),
(map Vubyte V,
(Vint (Int.repr reseed_counter),
(Vint (Int.repr entropy_len),
(Val.of_bool prediction_resistance,
Vint (Int.repr reseed_interval))))))
: mdstate * (list val * (val * (val * (val * val)))))
(WFI: WF I)
(Hout_lenb : (out_len >? 1024) = false)
(ZLa : (Zlength (contents_with_add additional (Zlength contents) contents) >? 256) =
false)
(Hshould_reseed : (prediction_resistance || (reseed_counter >? reseed_interval))%bool =
true)
(F32 : (32 >? 32) = false)
(return_value : int)
(Hrv : negb (Int.eq return_value (Int.repr 0)) = true)
(Hadd_lenb : (Zlength contents >? 256) = false)
(Hadd_len: 0 <= Zlength contents <= 256)
(EL1: entropy_len + Zlength contents <= 384)