val region : s: MiTLS.AEADProvider.state i rw -> MiTLS.Mem.tls_rgn
let region #i #rw (s:state i rw) = tls_region
module MiTLS.AEADProvider
open MiTLS

open FStar.Heap
open FStar.HyperStack
open FStar.HyperStack.ST
open FStar.Seq
open FStar.Bytes

open MiTLS.Mem
open MiTLS.TLSConstants
module TInfo = MiTLS.TLSInfo
open FStar.UInt32

module HS = FStar.HyperStack
module U8 = FStar.UInt8
module U32 = FStar.UInt32
module E = MiTLS.EverCrypt
module LB = LowStar.Buffer
module CI = MiTLS.Crypto.Indexing
module Plain = MiTLS.Crypto.Plain
module CB = MiTLS.Crypto.Symmetric.Bytes

let discard (b:bool) : ST unit (requires (fun _ -> True)) (ensures (fun h0 _ h1 -> h0 == h1)) = ()
let print (s:string) : ST unit (requires fun _ -> True) (ensures (fun h0 _ h1 -> h0 == h1)) =
  discard (IO.debug_print_string ("AEP| "^s^"\n"))
unfold let dbg : string -> ST unit (requires (fun _ -> True)) (ensures (fun h0 _ h1 -> h0 == h1)) =
  if DebugFlags.debug_AEP then print else (fun _ -> ())

(***********************************************************************)

type id = i:TInfo.id{~(TInfo.PlaintextID? i) /\ AEAD? (TInfo.aeAlg_of_id i)}
let alg (i:id): aeadAlg = let AEAD aead _ = TInfo.aeAlg_of_id i in aead

//18-09-04  unclear what's shadowing alg below
let alg' (i:id): aeadAlg = let AEAD aead _ = TInfo.aeAlg_of_id i in aead

let evercrypt_aeadAlg_option_of_aead_cipher : aeadAlg -> option EverCrypt.aead_alg =
  let open MiTLS.EverCrypt in 
  function
  | AES128_GCM        -> Some AES128_GCM
  | AES256_GCM        -> Some AES256_GCM
  | CHACHA20_POLY1305 -> Some CHACHA20_POLY1305
  | _                 -> None
let aeadAlg_for_evercrypt (a:aeadAlg{Some? (evercrypt_aeadAlg_option_of_aead_cipher a)})
  : EverCrypt.aead_alg
  = Some?.v (evercrypt_aeadAlg_option_of_aead_cipher a)

// Real IVs must be created with the internal
// salting function below.
let iv_length i = 12 // CC.aeadRealIVSize (alg i)
val iv (i:id) : Type0
let key_length i = UInt32.v (EverCrypt.aead_keyLen(alg i))

// Salt is the static part of IVs
let salt_length (i:id) =
  match TInfo.pv_of_id i with
  | TLS_1p3 -> iv_length i
  | _ ->
    let open MiTLS.EverCrypt in 
    match alg' i with
    | AES128_GCM
    | AES128_CCM
    | AES128_CCM8
    | AES256_GCM
    | AES256_CCM
    | AES256_CCM8       ->  4
    | CHACHA20_POLY1305 -> 12

// Length of the explicit (sent on wire) IV
let explicit_iv_length (i:id) =
  match TInfo.pv_of_id i with
  | TLS_1p3 -> 0
  | _ ->
    let open MiTLS.EverCrypt in 
    match alg' i with
    | AES128_GCM  
    | AES128_CCM  
    | AES128_CCM8 
    | AES256_GCM  
    | AES256_CCM  
    | AES256_CCM8       -> 8
    | CHACHA20_POLY1305 -> 0

type key  (i:id) = lbytes (key_length i)
type salt (i:id) = lbytes (salt_length i)

let state (i:id) (r:rw) =
    EverCrypt.aead_state * (key i * salt i)

let salt_of_state #i #r (s:state i r) : salt i = snd (snd s)
let key_of_state #i #r (s:state i r) : key i = fst (snd s)

type writer i = s:state i Writer
type reader i = s:state i Reader
/
prims.fst.checked MiTLS.TLSInfo.fst.checked MiTLS.TLSConstants.fsti.checked MiTLS.Random.fst.checked MiTLS.Mem.fst.checked MiTLS.Flag.fst.checked MiTLS.EverCrypt.Specs.fsti.checked MiTLS.EverCrypt.fsti.checked MiTLS.DebugFlags.fst.checked MiTLS.Crypto.Symmetric.Bytes.fst.checked MiTLS.Crypto.Plain.fsti.checked MiTLS.Crypto.Indexing.fst.checked LowStar.Modifies.fst.checked LowStar.Buffer.fst.checked FStar.UInt8.fsti.checked FStar.UInt32.fsti.checked FStar.UInt.fsti.checked FStar.Seq.fst.checked FStar.Pervasives.Native.fst.checked FStar.Pervasives.fsti.checked FStar.IO.fst.checked FStar.HyperStack.ST.fsti.checked FStar.HyperStack.fst.checked FStar.Heap.fst.checked FStar.Bytes.fsti.checked EverCrypt.Helpers.fsti.checked
MiTLS.AEADProvider.fsti
s: MiTLS.AEADProvider.state i rw -> MiTLS.Mem.tls_rgn
MiTLS.AEADProvider.id MiTLS.TLSConstants.rw MiTLS.AEADProvider.state MiTLS.Mem.tls_region MiTLS.Mem.tls_rgn
let region #i #rw (s: state i rw) =
  
tls_region