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.

Lemma FULL_isptr: forall sh key c, FULL sh key c |-- !!isptr c.