Local Open Scope logic.
Module Type HMAC_ABSTRACT_SPEC.
(*"Ordinary" abstract states contain a key and some data*)
Inductive HABS := hABS: forall (key data:list byte), HABS.
(*The mpred REP (hABS k d) c expresses that pointer value c holds a ctx representing the situation where we have hmac-ed data a with key k, and are prepeared to accept additional data.*)
Parameter REP: share -> HABS -> val -> mpred.
(*We have two additional protocol states. FULL k c holds after we return from hmac-final (so we can't hmac-updeate more data into ctx). It's the precondition of calls to hmac_init with argument key==null, ie the case where we want to reuse the key k in the next round of hmac. *)
Parameter FULL: share -> list byte -> val -> mpred.
(*EMPTY c captures the situation where we either haven't provided any key yet, or want to use an old ctx, but reinitialize its key. It occurs explicitly in the precondition of init_call with argument key==Vptr b i*)
Parameter EMPTY: share -> val -> mpred.
(*We can turn a memory block of hmac_ctx size into an EMPTY abstract HMAC REP*)
Parameter mkEmpty: forall sh v, data_at_ sh t_struct_hmac_ctx_st v |-- EMPTY sh v.
(*The reverse operation enables dellocation of stack-allocated hmac contexts at the end of client functions*)
Parameter EmptyDissolve: forall sh v, EMPTY sh v |-- data_at_ sh t_struct_hmac_ctx_st v.
(* We can prematurely terminate sequences of hmac-update by simply declaring an updateable ctx FULL*)
Parameter REP_FULL: forall sh key data c, REP sh (hABS key data) c |-- FULL sh key c.
(*We can also "wipe" a ctx, ie forget/erase any key material from ctx*)
Parameter FULL_EMPTY: forall sh key c, FULL sh key c |-- EMPTY sh c.
Parameter EMPTY_isptr: forall sh c, EMPTY sh c |-- !!isptr c.

(* Specifications: *)
Lemma FULL_isptr: forall sh key c, FULL sh key c |-- !!isptr c.
Lemma REP_isptr: forall sh key data c, REP sh (hABS key data) c |-- !!isptr c.
Definition hmac_reset_spec :=
DECLARE _HMAC_Init (*Naphat: you'll probably have DECLARE mbedtls_hmac_reset here, and the
body of your wrapper function is a call to hmac_init with key==null.*)
WITH c : val, sh: share, l:Z, key:list byte, gv: globals
PRE [ _ctx OF tptr t_struct_hmac_ctx_st,
_key OF tptr tuchar,
_len OF tint ]
PROP (writable_share sh)
LOCAL (temp _ctx c; temp _key nullval; temp _len (Vint (Int.repr l));
gvars gv)
SEP (FULL sh key c; K_vector gv)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (REP sh (hABS key nil) c; K_vector gv).