assert (l < Int.half_modulus). unfold Int.max_signed in H. omega. clear H.
rewrite Int.half_modulus_power in H0.
assert (Int.zwordsize = 32) by reflexivity. rewrite H in *; clear H. simpl in *.
rewrite two_power_pos_equiv in *.
assert (l * 8 < 2^31 * 8) by omega. clear H0.
eapply Z.lt_trans. eassumption. clear H. cbv; trivial.
Qed.
Module OPENSSL_HMAC_ABSTRACT_SPEC <: HMAC_ABSTRACT_SPEC.
Inductive HABS := hABS: forall (key data:list byte), HABS.
Definition abs_relate (a: HABS) (r: hmacstate) : Prop :=
match a with hABS key data =>
hmac_relate (hmacUpdate data (hmacInit key)) r
end.
Definition REP sh (a: HABS) (c: val) : mpred :=
EX r:hmacstate,
(!!(abs_relate a r) && data_at sh t_struct_hmac_ctx_st r c).
Definition FULL sh key c:mpred :=
(*!!(has_lengthK (Zlength key) key) &&*) EX h:_, hmacstate_PreInitNull sh key h c.  Definition EMPTY sh c : mpred := data_at_ sh t_struct_hmac_ctx_st c. (* Lemma mkEmpty v: field_compatible t_struct_hmac_ctx_st [] v -> memory_block Tsh (sizeof t_struct_hmac_ctx_st) v |-- EMPTY v.  Lemma EmptyDissolve: forall v, EMPTY v |-- memory_block Tsh (sizeof t_struct_hmac_ctx_st) v .  Lemma FULL_EMPTY sh key c: FULL sh key c |-- EMPTY sh c.  Lemma EMPTY_isptr sh c: EMPTY sh c |-- !!isptr c.  Lemma REP_isptr sh key data c: REP sh (hABS key data) c |-- !!isptr c.  (************************ Abstract specifications of HMAC_init *******************************************************)
Definition hmac_reset_spec :=
DECLARE _HMAC_Init
WITH c : val, sh: share, l:Z, key:list byte, gv: globals (*, d:list Z*)
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).
Definition hmac_starts_spec :=
DECLARE _HMAC_Init
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).
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)).

(* Specifications: *)
Lemma body_hmac_crypto: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC hmac_crypto_spec.
Lemma body_hmac_reset: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Init hmac_reset_spec.
Lemma body_hmac_final: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Final hmac_final_spec.
Lemma body_hmac_update: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Update hmac_update_spec.
Lemma body_hmac_starts: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_Init hmac_starts_spec.
Lemma body_hmac_cleanup: semax_body HmacVarSpecs HmacFunSpecs
f_HMAC_cleanup hmac_cleanup_spec.