(****** Next, here are the new specs of openssl's API functions *************)
(* I have split the two cases for hmac_init. mbedtls separates these situations in its API: mbedtls_md_hmac_reset prepares to authenticate a new message with the same key; mbedtls_md_hmac_starts sets the key and prepares to authenticate a new message. *)
Definition hmac_starts_spec :=
DECLARE _HMAC_Init (*Naphat: you'll probably have DECLARE mbedtls_hmac_starts here, and the
body of your wrapper function is a call to hmac_init with the nonnull key*)
WITH c : val, sh: share, l:Z, key:list byte, b:block, i:ptrofs, shk: share, gv: globals
PRE [ _ctx OF tptr t_struct_hmac_ctx_st,
_key OF tptr tuchar,
_len OF tint ]
PROP (writable_share sh; readable_share shk; has_lengthK l key)
LOCAL (temp _ctx c; temp _key (Vptr b i); temp _len (Vint (Int.repr l));
gvars gv)
SEP (EMPTY sh c; data_block shk key (Vptr b i); K_vector gv)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (REP sh (hABS key nil) c; data_block shk key (Vptr b i); K_vector gv).
Definition hmac_update_spec :=
DECLARE _HMAC_Update
WITH key: list byte, c : val, shc: share, d:val, shd: share, data:list byte, data1:list byte, gv:globals
PRE [ _ctx OF tptr t_struct_hmac_ctx_st,
_data OF tptr tvoid,
_len OF tuint]
PROP (writable_share shc; readable_share shd;
0 <= Zlength data1 <= Int.max_unsigned /\
Zlength data1 + Zlength data + 64 < two_power_pos 61)
LOCAL (temp _ctx c; temp _data d; temp  _len (Vint (Int.repr (Zlength data1)));
gvars gv)
SEP(REP shc (hABS key data) c; data_block shd data1 d; K_vector gv)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP(REP shc (hABS key (data++data1)) c;
data_block shd data1 d; K_vector gv).
Definition hmac_final_spec :=
DECLARE _HMAC_Final
WITH data:list byte, key:list byte, c : val, sh: share, md:val, shmd: share, gv:globals
PRE [ _ctx OF tptr t_struct_hmac_ctx_st,
_md OF tptr tuchar ]
PROP (writable_share sh; writable_share shmd)
LOCAL (temp _md md; temp _ctx c;
gvars gv)
SEP(REP sh (hABS key data) c; K_vector gv;
memory_block shmd 32 md)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP(K_vector gv; FULL sh key c;
data_block shmd (HMAC256 data key) md).
(*Maybe this is not needed in mbedtls?*)
Definition hmac_cleanup_spec :=
DECLARE _HMAC_cleanup
WITH key: list byte, c : val, sh: share
PRE [ _ctx OF tptr t_struct_hmac_ctx_st ]
PROP (writable_share sh)
LOCAL (temp _ctx c)
SEP(FULL sh key c)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP(EMPTY sh c).
Definition hmac_crypto_spec :=
DECLARE _HMAC
WITH md: val, KEY:DATA, shk: share,
msg: val, MSG:DATA, shm: share,
shmd: share, b:block, i:ptrofs, 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 (Vptr b i);
temp _key_len (Vint (Int.repr (LEN KEY)));
temp _d msg; temp _n (Vint (Int.repr (LEN MSG)));
gvars gv)
SEP(data_block shk (CONT KEY) (Vptr b i);
data_block shm (CONT MSG) msg;
memory_block shmd 32 md;
K_vector gv)
POST [ tptr tuchar ]
EX digest:_,
PROP (digest= HMAC256 (CONT MSG) (CONT KEY) /\
ByteBitRelations.bytesToBits digest =
verif_hmac_crypto.bitspec KEY MSG /\
forall A Awf, CRYPTO A Awf)
LOCAL (temp ret_temp md)
SEP(K_vector gv;
data_block shmd digest md;
data_block shm (CONT MSG) msg; data_block shk (CONT KEY) (Vptr b i)).
(* Finally, we have proofs that the openssl implementations satisfy these specs*)
Parameter body_hmac_final: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Final hmac_final_spec.
Parameter body_hmac_update: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Update hmac_update_spec.
Parameter body_hmac_starts: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Init hmac_starts_spec.
Parameter body_hmac_reset: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Init hmac_reset_spec.
Parameter body_hmac_cleanup: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_cleanup hmac_cleanup_spec.
Parameter body_hmac_crypto: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC hmac_crypto_spec.
End HMAC_ABSTRACT_SPEC.

(* Specifications: *)
Lemma haslengthK_simple: forall l, 0 < l <= Int.max_signed -> l * 8 < two_p 64.
intros.