Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relate bytes to IO specification #216

Merged
merged 39 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0aa5841
manually trigger workflow
mlimbeck Jun 20, 2023
8525b7c
manually trigger workflow
mlimbeck Jun 20, 2023
2eaf7a4
raw byte to spec for segments and hopfields
mlimbeck Jul 4, 2023
e9d31ae
bugfix
mlimbeck Jul 4, 2023
6b77cb6
import fix
mlimbeck Jul 4, 2023
e9631e0
bugfix after gobra update
mlimbeck Jul 10, 2023
bd062dc
spec to pkt (currSeg)
mlimbeck Jul 10, 2023
3246a2b
spec to pkt (left, mid, right)
mlimbeck Jul 11, 2023
35ff392
spec to pkt (termination)
mlimbeck Jul 11, 2023
f925f10
code clean up
mlimbeck Jul 17, 2023
6a19edf
Merge branch 'viperproject:master' into master
mlimbeck Jul 17, 2023
3d90011
clean up
mlimbeck Jul 17, 2023
6e8f884
improvements
mlimbeck Jul 18, 2023
afe9e52
instantiate abstract functions with bodies
mlimbeck Jul 19, 2023
de241b5
progress io spec
mlimbeck Jul 19, 2023
8a0452e
formatting
mlimbeck Jul 24, 2023
4540095
specification fixes
mlimbeck Jul 24, 2023
bf2c331
improve IO-spec
mlimbeck Jul 24, 2023
53cadc9
IO-spec to pkt rewritten
mlimbeck Jul 24, 2023
790e842
clean up
mlimbeck Jul 24, 2023
ca581db
improve readability
mlimbeck Jul 28, 2023
0d3cc57
Merge branch 'master' into master
jcp19 Sep 28, 2023
01eade7
Merge branch 'master' into master
jcp19 Oct 17, 2023
bfd6c2f
rename of function lengthOfCurrSeg
mlimbeck Nov 1, 2023
8c7b6c1
Merge remote-tracking branch 'remotescion/master'
mlimbeck Nov 14, 2023
89997c6
Merge remote-tracking branch 'remotescion/master'
mlimbeck Nov 15, 2023
f1cf0b1
extract asid-seqence from raw pkt
mlimbeck Nov 16, 2023
4343478
missing trigger
mlimbeck Nov 16, 2023
715fa51
quick fix
mlimbeck Nov 16, 2023
b051f09
Update router/dataplane_spec.gobra
mlimbeck Nov 17, 2023
7cbe9d6
Apply suggestions from code review
mlimbeck Nov 22, 2023
689e9da
readability improvements
mlimbeck Nov 22, 2023
24d19e1
further improvements
mlimbeck Nov 22, 2023
e923c40
replace 4 by its constant InfoLen
mlimbeck Nov 22, 2023
45b432e
readability improvement
mlimbeck Nov 22, 2023
8f15113
constant for metaLen in package path
mlimbeck Nov 22, 2023
503b0e0
Update router/io-spec.gobra
mlimbeck Nov 22, 2023
c292a84
minor improvements
mlimbeck Nov 22, 2023
a68a3e7
move validMetaLenInPath() to test file
mlimbeck Nov 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
373 changes: 371 additions & 2 deletions router/dataplane_spec.gobra
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"net"
"hash"
sl "github.com/scionproto/scion/verification/utils/slices"
"github.com/scionproto/scion/verification/io"
jcp19 marked this conversation as resolved.
Show resolved Hide resolved
"github.com/scionproto/scion/verification/dependencies/encoding/binary"
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
"github.com/scionproto/scion/verification/utils/bitwise"
"github.com/scionproto/scion/pkg/scrypto"
"github.com/scionproto/scion/pkg/addr"
)
Expand Down Expand Up @@ -194,7 +197,7 @@ func newOffsetPair(n int) (res seq[offsetPair])
ghost
requires acc(MutexInvariant!<d!>(), _)
ensures acc(&d.internalNextHops, _)
ensures d.internalNextHops != nil ==> acc(AccAddr(d.internalNextHops), _)
ensures d.internalNextHops != nil ==> acc(AccAddr(d.internalNextHops), _)
decreases
func (d *DataPlane) getInternalNextHops() {
unfold acc(MutexInvariant!<d!>(), _)
Expand Down Expand Up @@ -272,7 +275,7 @@ ensures scrypto.ValidKeyForHash(*d.key)
ensures d.macFactory implements MacFactorySpec{d.key}
decreases
func (d *DataPlane) getNewPacketProcessorFootprint() {
unfold acc(MutexInvariant!<d!>(), _)
unfold acc(MutexInvariant!<d!>(), _)
}

/**** End of acessor methods to avoid unfolding the Mem predicate of the dataplane so much ****/
Expand Down Expand Up @@ -343,3 +346,369 @@ func closureSpec2(i uint16, c BatchConn)
requires true
func closureSpec3(c BatchConn)
/** End of closure specs for the Run method **/

/** Start of io-spec helper functions **/
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved

ghost
requires 0 < seg1Len
requires 0 <= seg2Len
requires 0 <= seg3Len
requires currHF < seg1Len + seg2Len + seg3Len
decreases
pure func computeSeqLen(currHF int, seg1Len int, seg2Len int, seg3Len int) int{
return seg1Len > currHF ? seg1Len : ((seg1Len + seg2Len) > currHF ? seg2Len : seg3Len)
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
}

ghost
decreases
pure func infoFieldOffsetSeg(currINF int) int{
return 4 + 8 * currINF
}

ghost
decreases
pure func numInfoFields(seg1Len int, seg2Len int, seg3Len int) int {
return seg3Len > 0 ? 3 : (seg2Len > 0 ? 2 : 1)
}

ghost
requires 0 < seg1Len
requires 0 <= seg2Len
requires 0 <= seg3Len
requires 0 <= currHF
ensures res <= currHF
decreases
pure func computePrevSegLen(currHF int, seg1Len int, seg2Len int, seg3Len int) (res int){
return seg1Len > currHF ? 0 : ((seg1Len + seg2Len) > currHF ? seg1Len : seg1Len + seg2Len)
}

ghost
requires idx + 12 <= len(raw)
requires 0 <= idx
requires acc(&raw[idx+2], _) && acc(&raw[idx+3], _) && acc(&raw[idx+4], _) && acc(&raw[idx+5], _)
ensures len(res.HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_) > 0
decreases
pure func getHopField(raw []byte, idx int, beta set[io.IO_msgterm], asid io.IO_as, ainfo io.IO_ainfo) (res io.IO_HF) {
return let inif2 := binary.BigEndian.Uint16(raw[idx+2:idx+4]) in
let egif2 := binary.BigEndian.Uint16(raw[idx+4:idx+6]) in
let op_inif2 := inif2 == 0 ? none[io.IO_ifs] : some(io.IO_ifs(inif2)) in
let op_egif2 := egif2 == 0 ? none[io.IO_ifs] : some(io.IO_ifs(egif2)) in
let ts := io.IO_msgterm(io.MsgTerm_Num{ainfo}) in
let l := io.IO_msgterm(io.MsgTerm_L{seq[io.IO_msgterm]{ts, io.if2term(op_inif2), io.if2term(op_egif2),
io.IO_msgterm(io.MsgTerm_FS{beta})}}) in
let hvf := io.mac(io.macKey(io.asidToKey(asid)), l) in
io.IO_HF(io.IO_HF_{
InIF2 : op_inif2,
EgIF2 : op_egif2,
HVF : hvf,
})
}

ghost
requires 0 <= offset
requires 0 <= currHFIdx && currHFIdx <= segLen
requires offset + 12 * segLen <= len(raw)
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
ensures len(res) == segLen - currHFIdx
ensures forall k int :: {res[k]} 0 <= k && k < len(res) ==>
len(res[k].HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_) > 0
decreases segLen - currHFIdx
pure func getHopfieldsConsDir(
raw []byte,
offset int,
currHFIdx int,
segLen int,
beta set[io.IO_msgterm],
asid io.IO_as,
ainfo io.IO_ainfo) (res seq[io.IO_HF]){

mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
return currHFIdx == segLen ? seq[io.IO_HF]{} :
let hf := (unfolding acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _) in
getHopField(raw, offset + 12 * currHFIdx, beta, asid, ainfo)) in
seq[io.IO_HF]{hf} ++ getHopfieldsConsDir(raw, offset, currHFIdx + 1, segLen, (beta union set[io.IO_msgterm]{hf.HVF}), asid, ainfo)
}

ghost
requires 0 <= offset
requires -1 <= currHFIdx
requires offset + 12 * currHFIdx + 12 <= len(raw)
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
ensures len(res) == currHFIdx + 1
ensures forall k int :: {res[k]} 0 <= k && k < len(res) ==>
len(res[k].HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_) > 0
decreases currHFIdx + 1
pure func getHopfieldsNotConsDir(
raw []byte,
offset int,
currHFIdx int,
beta set[io.IO_msgterm],
asid io.IO_as,
ainfo io.IO_ainfo) (res seq[io.IO_HF]){

return currHFIdx == -1 ? seq[io.IO_HF]{} :
let hf := (unfolding acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _) in
getHopField(raw, offset + 12 * currHFIdx, beta, asid, ainfo)) in
getHopfieldsNotConsDir(raw, offset, currHFIdx -1, (beta union set[io.IO_msgterm]{hf.HVF}), asid, ainfo) ++ seq[io.IO_HF]{hf}
}

ghost
requires -1 <= currHFIdx && currHFIdx < len(hopfields)
decreases currHFIdx + 1
pure func getSegPast(hopfields seq[io.IO_HF], currHFIdx int) seq[io.IO_HF]{
return currHFIdx == -1 ? seq[io.IO_HF]{} :
seq[io.IO_HF]{hopfields[currHFIdx]} ++ getSegPast(hopfields, currHFIdx - 1)
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
}

ghost
requires 0 <= currHFIdx && currHFIdx <= len(hopfields)
decreases len(hopfields) - currHFIdx
pure func getSegFuture(hopfields seq[io.IO_HF], currHFIdx int) seq[io.IO_HF]{
return currHFIdx == len(hopfields) ? seq[io.IO_HF]{} :
seq[io.IO_HF]{hopfields[currHFIdx]} ++ getSegFuture(hopfields, currHFIdx + 1)
}

ghost
requires -1 <= currHFIdx && currHFIdx < len(hopfields)
decreases currHFIdx + 1
pure func getSegHistory(hopfields seq[io.IO_HF], currHFIdx int) seq[io.IO_ahi]{
return currHFIdx == -1 ? seq[io.IO_ahi]{} :
seq[io.IO_ahi]{hopfields[currHFIdx].Toab()} ++ getSegHistory(hopfields, currHFIdx - 1)

}

ghost
requires 0 <= offset
requires 0 < segLen
requires offset + 12 * segLen <= len(raw)
requires 0 <= currHFIdx && currHFIdx <= segLen
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
decreases
pure func getSegment(raw []byte,
offset int,
currHFIdx int,
segLen int,
asid io.IO_as,
ainfo io.IO_ainfo,
consDir bool,
peer bool) io.IO_seg2{

return let hopfields := consDir ?
getHopfieldsConsDir(raw, offset, 0, segLen, set[io.IO_msgterm]{}, asid, ainfo) :
getHopfieldsNotConsDir(raw, offset, segLen - 1, set[io.IO_msgterm]{}, asid, ainfo) in
let uinfo := getUInfo(hopfields, currHFIdx, consDir) in
io.IO_seg2(io.IO_seg3_{
AInfo :ainfo,
UInfo : uinfo,
ConsDir : consDir,
Peer : peer,
Past : getSegPast(hopfields, currHFIdx - 1),
Future : getSegFuture(hopfields, currHFIdx),
History : getSegHistory(hopfields, currHFIdx - 1),
})
}

ghost
requires 4 + 8 * currINFIdx + 8 <= offset
requires 0 < segLen
requires offset + 12 * segLen <= len(raw)
requires 0 <= currHFIdx && currHFIdx <= segLen
requires 0 <= currINFIdx && currINFIdx < 3
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
decreases
pure func getCurrSeg(raw []byte, offset int, currINFIdx int, currHFIdx int, segLen int, asid io.IO_as) io.IO_seg3 {
return unfolding acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _) in
let ainfo := getTimestamp(raw, currINFIdx) in
let consDir := getConsDir(raw, currINFIdx) in
let peer := getPeer(raw, currINFIdx) in
getSegment(raw, offset, currHFIdx, segLen, asid, ainfo, consDir, peer)
}

ghost
requires 0 < seg1Len
requires 0 <= seg2Len
requires 0 <= seg3Len
requires 4 + 8 * numInfoFields(seg1Len, seg2Len, seg3Len) == offset
requires offset + 12 * (seg1Len + seg2Len + seg3Len) <= len(raw)
requires 1 <= currINFIdx && currINFIdx < 4
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
decreases
pure func getLeftSeg(
raw []byte,
offset int,
currINFIdx int,
seg1Len int,
seg2Len int,
seg3Len int,
asid io.IO_as) option[io.IO_seg3] {

return (currINFIdx == 1 && seg2Len > 0) ?
some(getCurrSeg(raw, offset + 12 * seg1Len, currINFIdx, 0, seg2Len, asid)) :
(currINFIdx == 2 && seg3Len > 0) ?
some(getCurrSeg(raw, offset + 12 * (seg1Len + seg2Len), currINFIdx, 0, seg3Len, asid)) :
none[io.IO_seg3]
}

ghost
requires 0 < seg1Len
requires 0 <= seg2Len
requires 0 <= seg3Len
requires 4 + 8 * numInfoFields(seg1Len, seg2Len, seg3Len) == offset
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
requires offset + 12 * (seg1Len + seg2Len + seg3Len) <= len(raw)
requires -1 <= currINFIdx && currINFIdx < 2
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
decreases
pure func getRightSeg(
raw []byte,
offset int,
currINFIdx int,
seg1Len int,
seg2Len int,
seg3Len int,
asid io.IO_as) option[io.IO_seg3] {

return (currINFIdx == 1 && seg3Len > 0 && seg2Len > 0) ?
some(getCurrSeg(raw, offset + 12 * seg1Len, currINFIdx, seg2Len, seg2Len, asid)) :
(currINFIdx == 0 && seg2Len > 0) ?
some(getCurrSeg(raw, offset, currINFIdx, seg1Len, seg1Len, asid)) :
none[io.IO_seg3]
}

ghost
requires 0 < seg1Len
requires 0 <= seg2Len
requires 0 <= seg3Len
requires 4 + 8 * numInfoFields(seg1Len, seg2Len, seg3Len) == offset
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
requires offset + 12 * (seg1Len + seg2Len + seg3Len) <= len(raw)
requires 2 <= currINFIdx && currINFIdx < 5
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
decreases
pure func getMidSeg(
raw []byte,
offset int,
currINFIdx int,
seg1Len int,
seg2Len int,
seg3Len int,
asid io.IO_as) option[io.IO_seg3] {

return (currINFIdx == 4 && seg3Len > 0) ?
some(getCurrSeg(raw, offset, 0, seg1Len, seg1Len, asid)) :
(currINFIdx == 2 && seg3Len > 0) ?
some(getCurrSeg(raw, offset + 12 * (seg1Len + seg2Len), currINFIdx, 0, seg3Len, asid)) :
none[io.IO_seg3]
}

ghost
requires len(raw) > 4
requires acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _)
requires unfolding acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _) in
let hdr := binary.BigEndian.Uint32(raw[0:4]) in
0 <= getCurrINF(hdr) && getCurrINF(hdr) < 3 &&
getCurrINF(hdr) + 1 <= numInfoFields(int(getSeg1Len(hdr)), int(getSeg2Len(hdr)), int(getSeg3Len(hdr))) &&
0 <= getCurrHF(hdr) && getCurrHF(hdr) < getSeg1Len(hdr) + getSeg2Len(hdr) + getSeg3Len(hdr) &&
0 < getSeg1Len(hdr) &&
0 <= getSeg2Len(hdr) &&
0 <= getSeg3Len(hdr) &&
4 + 8 * numInfoFields(int(getSeg1Len(hdr)), int(getSeg2Len(hdr)), int(getSeg3Len(hdr))) + 12 * (int(getSeg1Len(hdr)) + int(getSeg2Len(hdr)) + int(getSeg3Len(hdr))) == len(raw)
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
decreases
pure func getPkt(raw []byte, asid io.IO_as) io.IO_pkt2{
return let hdr := unfolding acc(sl.AbsSlice_Bytes(raw, 0, len(raw)), _) in binary.BigEndian.Uint32(raw[0:4]) in
let currINFIdx := int(getCurrINF(hdr)) in
let currHFIdx := int(getCurrHF(hdr)) in
let seg1Len := int(getSeg1Len(hdr)) in
let seg2Len := int(getSeg2Len(hdr)) in
let seg3Len := int(getSeg3Len(hdr)) in
let segLen := computeSeqLen(currHFIdx, seg1Len, seg2Len, seg3Len) in
let prevSegLen := computePrevSegLen(currHFIdx, seg1Len, seg2Len, seg3Len) in
let numINF := int(numInfoFields(seg1Len, seg2Len, seg3Len)) in
let offset := 4 + 8 * numINF in
io.IO_pkt2(io.IO_Packet2{
CurrSeg : getCurrSeg(raw, offset+prevSegLen, currINFIdx, currHFIdx-prevSegLen, segLen, asid),
LeftSeg : getLeftSeg(raw, offset, currINFIdx + 1, seg1Len, seg2Len , seg3Len, asid),
MidSeg : getMidSeg(raw, offset, currINFIdx + 2, seg1Len, seg2Len , seg3Len, asid),
RightSeg : getRightSeg(raw, offset, currINFIdx - 1, seg1Len, seg2Len , seg3Len, asid),
})
}

ghost
decreases
pure func getCurrINF(hdr uint32) uint8{
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
return uint8(hdr >> 30)
}

ghost
decreases
pure func getCurrHF(hdr uint32) uint8{
return uint8(hdr >> 24) & 0x3F
}

ghost
decreases
pure func getSeg1Len(hdr uint32) uint8{
return uint8(hdr >> 12) & 0x3F
}

ghost
decreases
pure func getSeg2Len(hdr uint32) uint8{
return uint8(hdr >> 6) & 0x3F
}

ghost
decreases
pure func getSeg3Len(hdr uint32) uint8{
return uint8(hdr) & 0x3F
}
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved

ghost
requires 0 <= offset
requires infoFieldOffsetSeg(offset) < len(raw)
requires acc(&raw[infoFieldOffsetSeg(offset)], _)
decreases
pure func getConsDir(raw []byte, offset int) bool{
return raw[infoFieldOffsetSeg(offset)] & 0x1 == 0x1
}

ghost
requires 0 <= offset
requires infoFieldOffsetSeg(offset) < len(raw)
requires acc(&raw[infoFieldOffsetSeg(offset)], _)
decreases
pure func getPeer(raw []byte, offset int) bool{
return raw[infoFieldOffsetSeg(offset)] & 0x2 == 0x2
}

ghost
requires 0 <= offset
requires infoFieldOffsetSeg(offset) + 8 < len(raw)
requires acc(&raw[infoFieldOffsetSeg(offset) + 4], _)
requires acc(&raw[infoFieldOffsetSeg(offset) + 5], _)
requires acc(&raw[infoFieldOffsetSeg(offset) + 6], _)
requires acc(&raw[infoFieldOffsetSeg(offset) + 7], _)
decreases
pure func getTimestamp(raw []byte, offset int) io.IO_ainfo{
return let idx := infoFieldOffsetSeg(offset) + 4 in
io.IO_ainfo(binary.BigEndian.Uint32(raw[idx : idx + 4]))
}

ghost
requires len(hopfield.HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_) > 0
decreases
pure func getHVFSet(hopfield io.IO_HF) set[io.IO_msgterm]{
return let l := hopfield.HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_ in
l[len(l) - 1].MsgTerm_FS_
}

ghost
requires 0 < len(hopfields)
requires 0 <= currHFIdx && currHFIdx <= len(hopfields)
requires forall idx int :: 0 <= idx && idx < len(hopfields) ==>
len(hopfields[idx].HVF.MsgTerm_Hash_.MsgTerm_MPair_2.MsgTerm_L_) > 0
decreases
pure func getUInfo(hopfields seq[io.IO_HF], currHFIdx int, consDir bool) set[io.IO_msgterm]{
return currHFIdx == len(hopfields) ? getHVFSet(hopfields[currHFIdx-1]) :
currHFIdx == 0 ? getHVFSet(hopfields[currHFIdx]) :
consDir ? getHVFSet(hopfields[currHFIdx]) : getHVFSet(hopfields[currHFIdx-1])
mlimbeck marked this conversation as resolved.
Show resolved Hide resolved
}

/** End of io-spec helper functions **/
Loading