Module Instantiate_eq.
Definition OptionalNonce: option (list byte) := None. (*The implementation takes nonce from entropy, using the el*3/2 calculation*)
(*NIST, Section 10.1: highest supported sec strength is given by the hash function's security strength for preimage resistance. For SHA256, this is (according to NIST SP 800-107, Table 1, page 11) 256 bits. See also Appendix B2 of NIST SP 800-90A. *)
Definition highest_supported_security_strength := 32. (* in bytes -- see comment for reseed*)
(*Q: should we use the sec strength of HMAC, calculated according to Section 5.3.4 of NIST SP 800-107 instead?*)
Definition requested_security_strength:= 32.  (*same as in reseed*)
Definition prediction_resistance_supported:bool:=true.
Definition mbedtls_HMAC256_DRBG_instantiate_function (entropy_stream: ENTROPY.stream)
entropy_len pr_flag (personalization_string: list byte): ENTROPY.result DRBG_state_handle :=
HMAC256_DRBG_instantiate_function entropy_len entropy_len OptionalNonce
highest_supported_security_strength max_personalization_string_length
prediction_resistance_supported entropy_stream
requested_security_strength pr_flag personalization_string.
Definition entlen:Z := 32.
Parameter Entropy_addSuccess1: forall n m s s1 l1 s2 l2,
ENTROPY.get_bytes n s = ENTROPY.success l1 s1 ->
ENTROPY.get_bytes m s1 = ENTROPY.success l2 s2 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.success (l1++l2) s2.
Parameter Entropy_addSuccess2: forall n m s s1 l1 s2 e,
ENTROPY.get_bytes n s = ENTROPY.success l1 s1 ->
ENTROPY.get_bytes m s1 = ENTROPY.error e s2 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.error e s2.
Parameter Entropy_addError: forall n m s s1 e, ENTROPY.get_bytes n s = ENTROPY.error e s1 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.error e s1.
Definition preseed_relate V rc pr ri (r : hmac256drbgstate):mpred:=
match r with
(md_ctx', (V', (reseed_counter', (entropy_len', (prediction_resistance', reseed_interval'))))) =>
md_empty md_ctx' &&
!! (map Vubyte V = V' /\
Zlength V = 32 /\
Vint (Int.repr rc) = reseed_counter'(* /\
Vint (Int.repr entropy_len) = entropy_len'*) /\
Vint (Int.repr ri) = reseed_interval' /\
Val.of_bool pr = prediction_resistance')
end.
Definition hmac_drbg_seed_spec :=
DECLARE _mbedtls_hmac_drbg_seed
WITH ctx: val, info:val, len: Z, data:val, Data: list byte,
Ctx: hmac256drbgstate,
(*CTX: hmac256drbgabs,*)
Info: md_info_state, s:ENTROPY.stream, rc:Z, pr:bool, ri:Z, VV:list byte, gv: globals
PRE [_ctx OF tptr (Tstruct _mbedtls_hmac_drbg_context noattr),
_md_info OF tptr (Tstruct _mbedtls_md_info_t noattr),
_custom OF tptr tuchar, _len OF tuint ]
PROP ( (len = Zlength Data) /\
0 <= len (*<= 336 Int.max_unsigned*) /\
48 + len < Int.modulus /\
0 < 48 + Zlength (contents_with_add data len Data) < Int.modulus)
LOCAL (temp _ctx ctx; temp _md_info info;
temp _len (Vint (Int.repr len)); temp _custom data; gvars gv)
SEP (
data_at Ews t_struct_hmac256drbg_context_st Ctx ctx;
preseed_relate VV rc pr ri Ctx;
(*hmac256drbg_relate CTX Ctx;*)
data_at Ews t_struct_mbedtls_md_info Info info;
da_emp Ews (tarray tuchar (Zlength Data)) (map Vubyte Data) data;
K_vector gv; Stream s; mem_mgr gv)
POST [ tint ]
EX ret_value:_,
PROP ()
LOCAL (temp ret_temp (Vint ret_value))
SEP (data_at Ews t_struct_mbedtls_md_info Info info;
da_emp Ews (tarray tuchar (Zlength Data)) (map Vubyte Data) data;
K_vector gv;
if Int.eq ret_value (Int.repr (-20864))
then data_at Ews t_struct_hmac256drbg_context_st Ctx ctx *
(*hmac256drbg_relate CTX Ctx *) preseed_relate VV rc pr ri Ctx * Stream s else md_empty (fst Ctx) * EX p:val, (* malloc_token Tsh (Tstruct _hmac_ctx_st noattr) p * *)
match (fst Ctx) with (M1, (M2, M3)) =>
if (zlt 256 (Zlength Data) || (zlt 384 ((*hmac256drbgabs_entropy_len initial_state_abs*)48 + Zlength Data)))%bool
then !!(ret_value = Int.repr (-5)) &&
(Stream s *
( let CtxFinal:= ((info, (M2, p)), (list_repeat 32 (Vint Int.one), (Vint (Int.repr rc),
(Vint (Int.repr 48), (Val.of_bool pr, Vint (Int.repr 10000)))))) in
let CTXFinal:= HMAC256DRBGabs VV (list_repeat 32 Byte.one) rc 48 pr 10000 in
data_at Ews t_struct_hmac256drbg_context_st CtxFinal ctx *
hmac256drbg_relate CTXFinal CtxFinal))
else let myABS := HMAC256DRBGabs VV (list_repeat 32 Byte.one) rc 48 pr 10000
in match mbedtls_HMAC256_DRBG_reseed_function s myABS
(contents_with_add data (Zlength Data) Data)
with
| ENTROPY.error e ss =>
(!!(match e with
| ENTROPY.generic_error => Vint ret_value = Vint (Int.repr ENT_GenErr)
| ENTROPY.catastrophic_error => Vint ret_value = Vint (Int.repr (-9))
end) && (Stream ss *
let CtxFinal:= ((info, (M2, p)), (list_repeat 32 (Vint Int.one), (Vint (Int.repr rc),
(Vint (Int.repr 48), (Val.of_bool pr, Vint (Int.repr 10000)))))) in
let CTXFinal:= HMAC256DRBGabs VV (list_repeat 32 Byte.one) rc 48 pr 10000 in
data_at Ews t_struct_hmac256drbg_context_st CtxFinal ctx *
hmac256drbg_relate CTXFinal CtxFinal))
| ENTROPY.success handle ss => !!(ret_value = Int.zero) &&
match handle with ((((newV, newK), newRC), newEL), newPR) =>
let CtxFinal := ((info, (M2, p)), (map Vubyte newV, (Vint (Int.repr newRC), (Vint (Int.repr 32), (Val.of_bool newPR, Vint (Int.repr 10000)))))) in
let CTXFinal := HMAC256DRBGabs newK newV newRC 32 newPR 10000 in
data_at Ews t_struct_hmac256drbg_context_st CtxFinal ctx *
hmac256drbg_relate CTXFinal CtxFinal *
Stream ss end
end
end;
mem_mgr gv).
Opaque mbedtls_HMAC256_DRBG_reseed_function.

Lemma body_hmac_drbg_seed: semax_body HmacDrbgVarSpecs HmacDrbgFunSpecs
f_mbedtls_hmac_drbg_seed hmac_drbg_seed_spec.