(************Coq counterpart of HMAC_CTX, but for CompCert values (val etc)*********************)
Definition hmacstate: Type :=
  (s256state * (s256state * s256state))%type.Definition mdCtx (h: hmacstate): s256state.Definition iCtx (h: hmacstate): s256state.Definition oCtx (h: hmacstate): s256state.(***************** The next two definitions link abstract states (hmacabs) with Coq
 representations of HMAC_CTX values (hmacstate), and lift
 the relationship to a separation logic predicates*)
Definition hmac_relate (h: hmacabs) (r: hmacstate) : Prop :=
  match h with HMACabs ctx iS oS =>
    s256_relate ctx (mdCtx r) /\
    s256_relate iS (iCtx r) /\
    s256_relate oS (oCtx r) /\
    s256a_len iS = 512 /\ s256a_len oS = 512
  end.Definition t_struct_hmac_ctx_st := Tstruct _hmac_ctx_st noattr.(************************ Specification of HMAC_init ********************************************)

Definition has_lengthK (l:Z) (key:list byte) :=
  l = Zlength key /\ 0 < l <= Int.max_signed.(*requirement 0<l new in new_compcert - previously, it was 0<=l*)

Definition hmac_relate_PreInitNull (key:list byte) (h:hmacabs ) (r: hmacstate) : Prop :=
  match h with HMACabs ctx iS oS =>
    (*no clause for ctx*)
    s256_relate iS (iCtx r) /\
    s256_relate oS (oCtx r) /\
    s256a_len iS = 512 /\ s256a_len oS = 512 /\
    let keyB := HMAC_SHA256.mkKey key in
    innerShaInit keyB = iS /\ outerShaInit keyB = oS
  end.(************************ Specification of HMAC_update *******************************************************)

Definition has_lengthD (k l:Z) (data:list byte) :=
            l = Zlength data /\ 0 <= l <= Int.max_unsigned /\
            l * 8 + k < two_p 64.(************************ Specification of HMAC_final *******************************************************)

Definition hmac_relate_PostFinal (h:hmacabs ) (r: hmacstate) : Prop :=
  match h with HMACabs ctx iS oS =>
    (*no clause for ctx*)
    s256_relate iS (iCtx r) /\
    s256_relate oS (oCtx r) /\
    s256a_len iS = 512 /\ s256a_len oS = 512
  end.(************************ Specification of oneshot HMAC *******************************************************)

Record DATA := { LEN:Z; CONT: list byte}.(************************ Specification of oneshot HMAC *******************************************************)

Record DATA := { LEN:Z; CONT: list byte}.(************************ Specification of oneshot HMAC *******************************************************)

Record DATA := { LEN:Z; CONT: list byte}.(*A stronger spec of oneshot hmac that includes the cryptographic assertion in the postcondition
  is given in the verif_hmac_crpyto.v. This avoids having to Import FCF, hmacfc, and the
  proof of equivalence between HMAC_functional_prog and the functional spec of the
  cryptographic program in the present file.*)

(*Furthermore, verif_hmac_double.v contains the verification of an additional function
  an additional function, hmac2, that we added to the c file in order to exercise the reuse of
  a key for several messages. We call hmac twice, (on the same message, using the same key)
  and put the resulting (identical) digests side by side in a suitably large array*)

(***************** We combine all specifications to a specification context *******)

(*Definition SHA256_spec := (_SHA256, snd spec_sha.SHA256_spec). *)
Definition sha256init_spec := (_SHA256_Init, snd SHA256_Init_spec).Definition sha256update_spec := (_SHA256_Update, snd SHA256_Update_spec).Definition sha256final_spec := (_SHA256_Final, snd SHA256_Final_spec).Definition memset_spec := (_memset, snd spec_sha.memset_spec).Definition memcpy_spec := (_memcpy, snd spec_sha.memcpy_spec).Definition HmacFunSpecs : funspecs :=
  memcpy_spec_data_at:: memset_spec::
  sha256init_spec::sha256update_spec::sha256final_spec::(*SHA256_spec::*)
  HMAC_Init_spec:: HMAC_Update_spec::HMAC_Cleanup_spec::
  HMAC_Final_spec:: HMAC_spec ::nil.Definition HMS : hmacstate := default_val t_struct_hmac_ctx_st.

(* Specifications: *)
Lemma change_compspecs_data_block: forall sh v, @data_block spec_sha.CompSpecs sh v = @data_block CompSpecs sh v.
Lemma change_compspecs_t_struct_SHA256state_st: @data_at spec_sha.CompSpecs Ews t_struct_SHA256state_st = @data_at CompSpecs Ews t_struct_SHA256state_st.