def ensure_drbg_state(spec, p, keyp, s): spec.points_to(llvm.field(p, "bytes_used"), cry_f("{s}.bytes_used")) spec.points_to(llvm.field(p, "ctx"), keyp) spec.points_to(keyp, cry_f("split ({s}.ctx.key) : [{keysize}][8]")) spec.points_to(llvm.field(p, "v"), cry_f("split ({s}.v) : [{blocksize}][8]")) mixes = spec.fresh_var(i64, "mixes") spec.points_to(llvm.field(p, "mixes"), mixes)
def specification(self): (sp, keyp, s) = drbg_state(self, "drbg") (outp, datap) = alloc_blob(self, self.n) self.execute_func(sp, outp) res = cry_f("drbg_generate_internal `{{n={self.n}*8}} {s}") # Remove some of the parens here to get really bad error messages c = cry("split (({res}).0) : [{self.n}][8]") self.points_to(datap, c) ensure_drbg_state(self, sp, keyp, cry_f("{res}.1")) self.returns(cry(" 0 : [32] "))
def specification(self): (k, k_p) = ptr_to_fresh(self, LLVMArrayType(i8, 32)) (v, v_p) = ptr_to_fresh(self, LLVMArrayType(i8, 8)) (m, m_p) = ptr_to_fresh(self, LLVMArrayType(i8, self.size)) self.execute_func(k_p, v_p, cry('0 : [32]'), m_p, cry_f('{self.size} : [32]')) self.points_to(m_p, cry_f("Salsa20_encrypt {(k, v, m)}")) self.returns(cry('0 : [32]'))
def specification(self): # the first argument of `EVP_EncryptUpdate` is not `const`, # but it is constant in the DRBG cryptol specification. (key, keyp) = ptr_to_fresh_readonly(self, "key", ctx_type) outp = alloc_bytes(self, self.n) lenp = alloc_init(self, i32, cry_f("{self.n} : [32]")) (msg, msgp) = ptr_to_fresh_readonly(self, "msg", (bytes_type(self.n))) self.execute_func(keyp, outp, lenp, msgp, cry_f("`{blocksize} : [32]")) self.points_to(outp, cry_f("encrypt_128 {key} {msg}")) self.points_to(lenp, cry_f("{self.n} : [32]")) self.returns(cry("1 : [32]"))
def specification(self): (p, datap) = alloc_blob(self, blocksize) v = self.fresh_var(bytes_type(blocksize), "v") self.points_to(datap, v) self.execute_func(p) self.points_to(datap, cry_f("split ((join {v}) +1): [{blocksize}][8]")) self.returns(cry("0:[32]"))
def specification(self): (key, keyp) = ptr_to_fresh_readonly(self, "ctx", ctx_type) (msg, msgp) = ptr_to_fresh_readonly(self, "msg", bytes_type(blocksize)) outp = alloc_bytes(self, blocksize) self.execute_func(keyp, msgp, outp) self.points_to(outp, cry_f("encrypt_128 {key} {msg}")) self.returns(cry("0 : [32]"))
def alloc_blob(spec, n): p = spec.alloc(type=blob_type, read_only=True) datap = alloc_bytes(spec, n) spec.points_to(llvm.field(p, "data"), datap) spec.points_to(llvm.field(p, "size"), cry_f("`{n}:[32]")) spec.points_to(llvm.field(p, "allocated"), cry("0:[32]")) spec.points_to(llvm.field(p, "growable"), cry("0:[8]")) return (p, datap)
def specification(self): ss = self.alloc(alias_ty('struct.s')) z = self.fresh_var(i2, 'z') self.execute_func(ss, cry_f('zext {z} : [8]')) self.points_to_bitfield(ss, 'x2', z) self.returns(void)
def specification(self) -> None: x = self.fresh_var(array_ty(2, i32), "x") p = self.alloc(array_ty(4, i32)) self.points_to(p, x, check_target_type=self.check_x_type) self.execute_func(p) self.points_to(p, cry_f("{x} # {x}")) self.returns(void)
def specification(self): array_t = array_ty(LEN, i64) c_ptr = self.alloc(array_t) (a, a_ptr) = ptr_to_fresh(self, name='a', ty=array_t, read_only=True) (b, b_ptr) = ptr_to_fresh(self, name='b', ty=array_t, read_only=True) self.execute_func(c_ptr, a_ptr, b_ptr) self.points_to(c_ptr, cry_f('zipWith`{{ {LEN} }} (+) {a} {b}')) self.returns(void)
def specification(self) -> None: y0 = self.fresh_var(i32, "y0") y1 = self.fresh_var(i32, "y1") y2 = self.fresh_var(i32, "y2") y3 = self.fresh_var(i32, "y3") y0_p = self.alloc(i32, points_to=y0) y1_p = self.alloc(i32, points_to=y1) y2_p = self.alloc(i32, points_to=y2) y3_p = self.alloc(i32, points_to=y3) self.execute_func(y0_p, y1_p, y2_p, y3_p) res = cry_f("quarterround {[y0, y1, y2, y3]}") self.points_to(y0_p, cry_f("{res}@0")) self.points_to(y1_p, cry_f("{res}@1")) self.points_to(y2_p, cry_f("{res}@2")) self.points_to(y3_p, cry_f("{res}@3")) self.returns(void)
def specification(self): k = self.fresh_var(LLVMArrayType(i8, 32)) n = self.fresh_var(LLVMArrayType(i8, 16)) k_p = self.alloc(LLVMArrayType(i8, 32), read_only=True) n_p = self.alloc(LLVMArrayType(i8, 16), read_only=True) ks_p = self.alloc(LLVMArrayType(i8, 64)) self.points_to(k_p, k) self.points_to(n_p, n) self.execute_func(k_p, n_p, ks_p) self.returns(void) self.points_to(ks_p, cry_f("Salsa20_expansion `{{a=2}} {(k, n)}"))
def drbg_state(spec, n): state = spec.alloc(alias_ty("struct.s2n_drbg")) (key, keyp) = ptr_to_fresh(spec, "key", ctx_type) bytes_used = spec.fresh_var(i64, n + "bytes_used") mixes = spec.fresh_var(i64, n + "mixes") v = spec.fresh_var(bytes_type(blocksize), n + "v") spec.points_to(llvm.field(state, "bytes_used"), bytes_used) spec.points_to(llvm.field(state, "mixes"), mixes) spec.points_to(llvm.field(state, "ctx"), keyp) spec.points_to(llvm.field(state, "v"), v) return ( state, keyp, cry_f( "{{ bytes_used = {bytes_used}, ctx = {{ key = join {key} }}, v = join {v} }}" ))
def alloc_blob_readonly(spec, n): p = spec.alloc(type=blob_type, read_only=True) datap = spec.alloc(array_ty(n, i8), read_only=True) spec.points_to(llvm.field(p, "data"), datap) spec.points_to(llvm.field(p, "size"), cry_f("`{n}: [32]")) return (p, datap)
def specification(self): ctx = self.alloc(ctx_type) self.execute_func(ctx) self.points_to(ctx, cry_f("zero : [{keysize}][8]")) self.returns(cry("1:[32]"))
def specification(self): (sp, keyp, s) = drbg_state(self, "drbg") bytes_used = alloc_init(self, i64, cry("0:[64]")) self.execute_func(sp, bytes_used) self.points_to(bytes_used, cry_f("{s}.bytes_used")) self.returns(cry("0:[32]"))
def specification(self): (p, datap) = alloc_blob(self, self.n) self.execute_func(p) self.points_to(datap, cry_f("zero:[{self.n}][8]")) self.returns(cry("0:[32]"))
def int_to_64_cryptol(length: int): return cry_f("`{length}:[64]")
def post_counter(contract: Contract, counter: GhostVariable, n: CryptolTerm): contract.ghost_value(counter, cry_f("{n} + 1"))