Local Open Scope logic.
Require hmacdrbg.verif_hmac_drbg_WF.
Opaque HMAC256.
Opaque hmac256drbgabs_generate.
Opaque HMAC256_DRBG_generate_function.
Opaque mbedtls_HMAC256_DRBG_generate_function.
(* Lemma while_loop_post_incremental_snd: forall key0 V0 n out_len, 0 <= (n * 32)%Z <= out_len -> (n * 32)%Z <> out_len -> snd (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32)%Z) ++ fst (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 ((n * 32)%Z + Z.min 32 (out_len - (n * 32)%Z))) = snd (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 ((n * 32)%Z + Z.min 32 (out_len - (n * 32)%Z))).  Lemma while_loop_post_incremental_fst: forall key0 V0 n out_len, 0 <= (n * 32)%Z <= out_len -> (n * 32)%Z <> out_len -> fst (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 ((n * 32)%Z + Z.min 32 (out_len - (n * 32)%Z))) = HMAC256 (fst (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32)%Z)) key0.  Lemma while_loop_post_sublist_app: forall key0 V0 n out_len, 0 <= (n * 32)%Z <= out_len -> Zlength V0 = 32 -> sublist 0 (n * 32) (snd (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32))) ++ sublist 0 (Z.min 32 (out_len - n * 32)) (fst (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32 + Z.min 32 (out_len - n * 32)))) = sublist 0 (n * 32 + Z.min 32 (out_len - n * 32)) (snd (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32)) ++ fst (HMAC_DRBG_generate_helper_Z HMAC256 key0 V0 (n * 32 + Z.min 32 (out_len - n * 32)))).  (* 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_contents : md_info_state)
(s : ENTROPY.stream)
(initial_state_abs := HMAC256DRBGabs key V reseed_counter entropy_len
prediction_resistance reseed_interval : hmac256drbgabs)
(initial_state := (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)))))
(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)