Local Open Scope logic.
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Instance CompSpecs_Preserve: change_composite_env spec_sha.CompSpecs CompSpecs.
make_cs_preserve spec_sha.CompSpecs CompSpecs.
Defined.
Definition Vprog : varspecs.  mk_varspecs prog. Defined.
Record TREP := mkTrep { t: type; v: reptype t}.
Definition tp_of (T:TREP) : type.
destruct T. apply t0.
Defined.
Definition v_of (T:TREP) : reptype (tp_of T).
destruct T. apply v0.
Defined.
Definition memcpy_spec_data_at :=
DECLARE _memcpy
WITH rsh : share, wsh: share, p: val, q: val, T:TREP, n:Z
PRE [ 1%positive OF tptr tvoid, 2%positive OF tptr tvoid, 3%positive OF tuint ]
PROP (readable_share rsh; writable_share wsh;
n= sizeof (tp_of T); 0 <= n <= Int.max_unsigned)
LOCAL (temp 1%positive p; temp 2%positive q;
temp 3%positive (Vint (Int.repr n)))
SEP (data_at rsh (tp_of T) (v_of T) q;
memory_block wsh n p)
POST [ tptr tvoid ]
PROP ()
LOCAL (temp ret_temp p)
SEP (data_at wsh (tp_of T) (v_of T) p;
data_at rsh (tp_of T) (v_of T) q).
(****** Coq-representation of hmac states, and predicates characterizing the incremental functions.  If the corresponding predicates for SHA operations were modeled as functions, the ones here could be, too *)
Inductive hmacabs :=  (* HMAC abstract state *)
HMACabs: forall (ctx iSha oSha: s256abs) (*sha structures for md_ctx, i_ctx, o_ctx*),
hmacabs.
Definition absCtxt (h:hmacabs): s256abs :=
match h with HMACabs ctx _ _ => ctx end.
Definition innerShaInit (k: list byte):s256abs :=
HMAC_SHA256.mkArg k Ipad.
Definition outerShaInit (k: list byte):s256abs :=
HMAC_SHA256.mkArg k Opad.
Definition hmacInit (k:list byte):hmacabs :=
let key := HMAC_SHA256.mkKey k in
let iS := innerShaInit key in
let oS := outerShaInit key in
HMACabs iS iS oS.
Definition hmacUpdate (data: list byte) (h1:hmacabs): hmacabs :=
match h1 with
HMACabs ctx1 iS oS
=> let ctx2 := ctx1 ++ data in
HMACabs ctx2 iS oS
end.
Definition hmacFinalSimple h : list byte :=
match h with
HMACabs ctx iS oS
=> let inner := SHA256.SHA_256 ctx in
SHA256.SHA_256 (oS ++ inner)
end.
Definition hmacFinal h : (hmacabs * list byte) :=
match h with
HMACabs ctx iS oS
=> let inner := SHA256.SHA_256 ctx in
let outerArg := oS ++ inner in
(HMACabs outerArg iS oS, SHA256.SHA_256 outerArg)
end.
(*hmac cleanup not modelled*)
Definition hmacSimple (k:list byte) (data:list byte):list byte:=
hmacFinalSimple (hmacUpdate data (hmacInit k)).
Definition hmac (k:list byte) (data:list byte):(hmacabs * list byte) :=
hmacFinal (hmacUpdate data (hmacInit k)).
(************************ Specifications of HMAC_cleanup *******************************************************)
Definition HMAC_Cleanup_spec :=
DECLARE _HMAC_cleanup
WITH wsh: share, h: hmacabs, c : val
PRE [ _ctx OF tptr t_struct_hmac_ctx_st ]
PROP (writable_share wsh)
LOCAL (temp _ctx c)
SEP(hmacstate_PostFinal wsh h c)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP(data_block wsh (list_repeat (Z.to_nat(sizeof t_struct_hmac_ctx_st)) Byte.zero) c).
Definition HMAC_Cleanup_spec1 :=
DECLARE _HMAC_cleanup
WITH wsh: share, h: hmacabs, c : val
PRE [ _ctx OF tptr t_struct_hmac_ctx_st ]
PROP (writable_share wsh)
LOCAL (temp _ctx c)
SEP(EX key:_, hmacstate_PreInitNull wsh key h c)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP(data_block wsh (list_repeat (Z.to_nat(sizeof t_struct_hmac_ctx_st)) Byte.zero) c).
(************************ Specification of oneshot HMAC *******************************************************)
Record DATA := { LEN:Z; CONT: list byte}.
Definition HMAC_spec :=
DECLARE _HMAC
WITH keyVal: val, KEY:DATA,
msgVal: val, MSG:DATA,
shk: share, shm: share, shmd: share, md: val, gv: globals
PRE [ _key OF tptr tuchar,
_key_len OF tint,
_d OF tptr tuchar,
_n OF tint,
_md OF tptr tuchar ]
PROP (readable_share shk; readable_share shm; writable_share shmd;
has_lengthK (LEN KEY) (CONT KEY);
has_lengthD 512 (LEN MSG) (CONT MSG))
LOCAL (temp _md md; temp _key keyVal;
temp _key_len (Vint (Int.repr (LEN KEY)));
temp _d msgVal;
temp _n (Vint (Int.repr (LEN MSG)));
gvars gv)
SEP(data_block shk (CONT KEY) keyVal;
data_block shm (CONT MSG) msgVal;
K_vector gv;
memory_block shmd 32 md)
POST [ tptr tuchar ] EX digest:_,
PROP (digest= HMAC256 (CONT MSG) (CONT KEY))
LOCAL (temp ret_temp md)
SEP(K_vector gv;
data_block shmd digest md;
initPostKey shk keyVal (CONT KEY);
data_block shm (CONT MSG) msgVal).
(*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 HmacVarSpecs : varspecs :=
[(_m, tarray tuchar 32); (_m__1, tarray tuchar 64); (sha._K256, tarray tuint 64)].
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.
Ltac change_compspecs' cs cs' ::=
match goal with
| |- context [@data_block cs'] => rewrite change_compspecs_data_block
| |- context [@data_at cs' ?sh ?t ?v1] => erewrite (@data_at_change_composite cs' cs _ sh t); [| apply JMeq_refl | reflexivity]
| |- context [@field_at cs' ?sh ?t ?gfs ?v1] => erewrite (@field_at_change_composite cs' cs _ sh t gfs); [| apply JMeq_refl | reflexivity]
| |- context [@data_at_ cs' ?sh ?t] => erewrite (@data_at__change_composite cs' cs _ sh t); [| reflexivity]
| |- context [@field_at_ cs' ?sh ?t ?gfs] => erewrite (@field_at__change_composite cs' cs _ sh t gfs); [| reflexivity]
| |- context [?A cs'] => change (A cs') with (A cs)
| |- context [?A cs' ?B] => change (A cs' B) with (A cs B)
| |- context [?A cs' ?B ?C] => change (A cs' B C) with (A cs B C)
| |- context [?A cs' ?B ?C ?D] => change (A cs' B C D) with (A cs B C D)
| |- context [?A cs' ?B ?C ?D ?E] => change (A cs' B C D E) with (A cs B C D E)
| |- context [?A cs' ?B ?C ?D ?E ?F] => change (A cs' B C D E F) with (A cs B C D E F)
end.

(* TODO: maybe this lemma is not needed any more. *)
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.