diff options
Diffstat (limited to '')
-rw-r--r-- | cmd/verify.go | 155 | ||||
-rw-r--r-- | config/config.go | 6 | ||||
-rw-r--r-- | core/storage.go | 17 | ||||
-rw-r--r-- | core/verification.go | 21 | ||||
-rw-r--r-- | fsverify-paper.md | 4 | ||||
-rw-r--r-- | verifysetup/cmd/setup.go | 16 | ||||
-rw-r--r-- | verifysetup/core/storage.go | 5 |
7 files changed, 148 insertions, 76 deletions
diff --git a/cmd/verify.go b/cmd/verify.go index 1d18e41..0cafe5b 100644 --- a/cmd/verify.go +++ b/cmd/verify.go @@ -1,13 +1,19 @@ package cmd import ( - "bufio" + "bytes" "fmt" + "math" + "os" + "sync" + + "github.com/axtloss/fsverify/config" "github.com/axtloss/fsverify/core" "github.com/spf13/cobra" - "os" ) +var validateFailed bool + func NewVerifyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "verify", @@ -19,37 +25,71 @@ func NewVerifyCommand() *cobra.Command { return cmd } -func ValidateCommand(_ *cobra.Command, args []string) error { +func validateThread(blockStart int, blockEnd int, bundleSize int, diskBytes []byte, n int, dbfile string, waitGroup *sync.WaitGroup, errChan chan error) { + defer waitGroup.Done() + defer close(errChan) + var reader *bytes.Reader + blockCount := math.Floor(float64(bundleSize / 2000)) + totalReadBlocks := 0 - /*entrynode := core.Node{ - BlockStart: 0, - BlockEnd: 4000, - BlockSum: "32fd1c42b66cbf1b2f0f1a65a3cb08f3d7845eac7f43e13b2b5b5f9f837e3346", - PrevNodeSum: "Entrypoint", + fmt.Println("DBFILE: ", dbfile) + db, err := core.OpenDB(dbfile, true) + if err != nil { + errChan <- err } - err := core.AddNode(entrynode, nil) + reader = bytes.NewReader(diskBytes) + + node, err := core.GetNode(fmt.Sprintf("Entrypoint%d", n), db) if err != nil { - return err + errChan <- err } + block, i, err := core.ReadBlock(node, reader, totalReadBlocks) + totalReadBlocks = i - entryHash, err := entrynode.GetHash() + err = core.VerifyBlock(block, node) if err != nil { - return err + fmt.Println("fail") + errChan <- err } - nextNode := core.Node{ - BlockStart: 4000, - BlockEnd: 8000, - BlockSum: "3d73ff8cb154dcfe8cdae426021f679e541b47dbe14e8426e6b1cd3f2c57017c", - PrevNodeSum: entryHash, + + for int64(totalReadBlocks) < int64(blockCount) { + if validateFailed { + return + } + nodeSum, err := node.GetHash() + if err != nil { + fmt.Println("Using node ", nodeSum) + errChan <- err + } + node, err := core.GetNode(nodeSum, db) + if err != nil { + errChan <- err + } + fmt.Println("----") + fmt.Println(node) + part, i, err := core.ReadBlock(node, reader, totalReadBlocks) + totalReadBlocks = i + if err != nil { + errChan <- err + validateFailed = true + return + } + err = core.VerifyBlock(part, node) + if err != nil { + fmt.Println("fail") + errChan <- err + validateFailed = true + return + //fmt.Printf("Block '%s' ranging from %d to %d matches!\n", node.PrevNodeSum, node.BlockStart, node.BlockEnd) + } + } - err = core.AddNode(nextNode, nil) - if err != nil { - return err - }*/ +} - header, err := core.ReadHeader("/dev/sda") +func ValidateCommand(_ *cobra.Command, args []string) error { + header, err := core.ReadHeader("./part.fsverify") fmt.Printf("Magic Number: %d\n", header.MagicNumber) fmt.Printf("Signature: %s", header.Signature) fmt.Printf("FsSize: %d\n", header.FilesystemSize) @@ -59,23 +99,17 @@ func ValidateCommand(_ *cobra.Command, args []string) error { if err != nil { return err } - dbfile, err := core.ReadDB("/dev/sda") + fmt.Println("Reading DB") + //dbfile, err := core.ReadDB("/dev/sda") + dbfile, err := core.ReadDB("./part.fsverify") if err != nil { return err } fmt.Println("DBFILE: ", dbfile) - db, err := core.OpenDB(dbfile, true) - if err != nil { - return err - } - - getnode, err := core.GetNode("Entrypoint", db) - if err != nil { - return err - } - fmt.Println(getnode) - - fmt.Println("----") + /* db, err := core.OpenDB(dbfile, true) + if err != nil { + return err + }*/ key, err := core.ReadKey() if err != nil { @@ -86,39 +120,58 @@ func ValidateCommand(_ *cobra.Command, args []string) error { if err != nil { return err } else if !verified { - return fmt.Errorf("Signature verification failed\n") + //return fmt.Errorf("Signature verification failed\n") + fmt.Println("Signature verification failedw") } else { fmt.Println("Signature verification success!") } fmt.Println("----") - - disk, err := os.Open("./partition.raw") - reader := bufio.NewReader(disk) - part, err := core.ReadBlock(getnode, reader) + disk, err := os.Open(args[0]) if err != nil { return err } + defer disk.Close() diskInfo, err := disk.Stat() - node, err := core.GetNode("Entrypoint", db) if err != nil { return err } - hash, err := core.CalculateBlockHash(part) - fmt.Println(hash) + diskSize := diskInfo.Size() + + bundleSize := math.Floor(float64(diskSize / int64(config.ProcCount))) + // blockCount := math.Ceil(float64(bundleSize / 2000)) + // lastBlockSize := int(diskSize) - int(diskSize)*config.ProcCount + diskBytes := make([]byte, diskSize) + _, err = disk.Read(diskBytes) if err != nil { return err } + reader := bytes.NewReader(diskBytes) + var waitGroup sync.WaitGroup + errChan := make(chan error) + validateFailed = false + for i := 0; i < config.ProcCount; i++ { + diskBytes, err := core.CopyByteArea(i*(int(bundleSize)), (i+1)*(int(bundleSize)), reader) + if err != nil { + fmt.Println("Failed to copy byte area ", i*int(bundleSize), " ", (i+1)+int(bundleSize)) + return err + } + waitGroup.Add(1) + go validateThread(i*int(bundleSize), (i+1)*int(bundleSize), int(bundleSize), diskBytes, i, dbfile, &waitGroup, errChan) + } - err = core.VerifyBlock(part, getnode) - if err != nil { - fmt.Println("fail") - return err + go func() { + waitGroup.Wait() + close(errChan) + }() + + for err := range errChan { + if err != nil { + return err + } } - fmt.Printf("Block '%s' ranging from %d to %d matches!\n", getnode.PrevNodeSum, getnode.BlockStart, getnode.BlockEnd) - fmt.Println(node) - for int64(core.TotalReadBlocks) < diskInfo.Size() { + /*for int64(core.TotalReadBlocks) < diskInfo.Size() { nodeSum, err := node.GetHash() if err != nil { return err @@ -145,7 +198,7 @@ func ValidateCommand(_ *cobra.Command, args []string) error { } fmt.Printf("Block '%s' ranging from %d to %d matches!\n", node.PrevNodeSum, node.BlockStart, node.BlockEnd) - } + }*/ return nil } diff --git a/config/config.go b/config/config.go index f8e61e4..0a71847 100644 --- a/config/config.go +++ b/config/config.go @@ -4,5 +4,9 @@ package config // 0: external file, 1: external storage device, 2: tpm2, 3: usb serial var KeyStore = 3 -// Where the public key is stored, only applies for 0, 1 and 3 +// Where the public key is stored, only applies for KeyStore = 0, 1 and 3 var KeyLocation = "/dev/ttyACM1" + +// The amount of threads the DB was created with, has to be the amount of processes +// verifysetup was set to use +var ProcCount = 12 diff --git a/core/storage.go b/core/storage.go index 8334271..d3dc3da 100644 --- a/core/storage.go +++ b/core/storage.go @@ -2,13 +2,13 @@ package core import ( "bufio" + "bytes" "encoding/binary" "encoding/json" "fmt" + bolt "go.etcd.io/bbolt" "io" "os" - - bolt "go.etcd.io/bbolt" ) type Header struct { @@ -141,6 +141,8 @@ func ReadDB(partition string) (string, error) { db := make([]byte, header.TableSize*header.TableUnit) n, err := io.ReadFull(reader, db) if err != nil { + fmt.Println("failed reading db") + fmt.Println(header.TableSize * header.TableUnit) return "", err } if n != header.TableSize*header.TableUnit { @@ -195,3 +197,14 @@ func GetNode(checksum string, db *bolt.DB) (Node, error) { } return node, err } + +func CopyByteArea(start int, end int, reader *bytes.Reader) ([]byte, error) { + bytes := make([]byte, end-start) + n, err := reader.ReadAt(bytes, int64(start)) + if err != nil { + return nil, err + } else if n != end-start { + return nil, fmt.Errorf("Unable to read requested size. Got %d, expected %d", n, end-start) + } + return bytes, nil +} diff --git a/core/verification.go b/core/verification.go index b0ce367..1193664 100644 --- a/core/verification.go +++ b/core/verification.go @@ -2,6 +2,7 @@ package core import ( "bufio" + "bytes" "fmt" "os" "strings" @@ -11,7 +12,7 @@ import ( "github.com/tarm/serial" ) -var TotalReadBlocks int = 0 +//var TotalReadBlocks int = 0 func fileReadKey() (string, error) { if _, err := os.Stat(config.KeyLocation); os.IsNotExist(err) { @@ -92,16 +93,20 @@ func ReadKey() (string, error) { return "", nil } -func ReadBlock(node Node, part *bufio.Reader) ([]byte, error) { +func ReadBlock(node Node, part *bytes.Reader, totalReadBlocks int) ([]byte, int, error) { block := make([]byte, node.BlockEnd-node.BlockStart) blockSize := node.BlockEnd - node.BlockStart - _, err := part.Discard(node.BlockStart) + _, err := part.Seek(int64(node.BlockStart), 0) if err != nil { - return []byte{}, err + return []byte{}, -1, err } - block, err = part.Peek(blockSize) - TotalReadBlocks = TotalReadBlocks + blockSize - return block, err + n, err := part.Read(block) + if err != nil { + return block, -1, err + } else if n != blockSize { + return block, -1, fmt.Errorf("Did not read correct amount of bytes. Expected: %d, Got: %d", blockSize, n) + } + return block, totalReadBlocks + 1, err } func VerifySignature(key string, signature string, database string) (bool, error) { @@ -127,7 +132,7 @@ func VerifyBlock(block []byte, node Node) error { if strings.Compare(calculatedBlockHash, strings.TrimSpace(wantedBlockHash)) == 0 { return nil } - return fmt.Errorf("Error: Node %s ranging from %d to %d does not match block", node.PrevNodeSum, node.BlockStart, node.BlockEnd) + return fmt.Errorf("Error: Node %s ranging from %d to %d does not match block. Expected %s, got %s.", node.PrevNodeSum, node.BlockStart, node.BlockEnd, wantedBlockHash, calculatedBlockHash) } func VerifyNode(node Node, nextNode Node) error { diff --git a/fsverify-paper.md b/fsverify-paper.md index b68728f..1bba029 100644 --- a/fsverify-paper.md +++ b/fsverify-paper.md @@ -119,8 +119,8 @@ An (unsafe) example using an arduino can look like this: // fsverify-serial.ino void setup() { - Serial.setup(9600) // set up a serial tty with the baud rate 9600 - Serial.print("\tpublic key\t") // Write the public key to the tty + Serial.begin(9600); // set up a serial tty with the baud rate 9600 + Serial.print("\tpublic key\t"); // Write the public key to the tty } void loop() {} diff --git a/verifysetup/cmd/setup.go b/verifysetup/cmd/setup.go index 149f41a..81c4dff 100644 --- a/verifysetup/cmd/setup.go +++ b/verifysetup/cmd/setup.go @@ -58,17 +58,6 @@ func checksumBlock(blockStart int, blockEnd int, bundleSize int, diskBytes []byt fmt.Printf("Node from %d to %d finished.\n", blockStart, blockEnd) } -func copyByteArea(start int, end int, reader *bytes.Reader) ([]byte, error) { - bytes := make([]byte, end-start) - n, err := reader.ReadAt(bytes, int64(start)) - if err != nil { - return nil, err - } else if n != end-start { - return nil, fmt.Errorf("Unable to read requested size. Got %d, expected %d", n, end-start) - } - return bytes, nil -} - func SetupCommand(_ *cobra.Command, args []string) error { if len(args) != 2 { return fmt.Errorf("Usage: verifysetup setup [partition] [procCount]") @@ -104,7 +93,7 @@ func SetupCommand(_ *cobra.Command, args []string) error { var waitGroup sync.WaitGroup nodeChannels := make([]chan verify.Node, procCount+1) for i := 0; i < procCount; i++ { - diskBytesCopy, err := copyByteArea(i*(int(bundleSize)), (i+1)*(int(bundleSize)), reader) + diskBytesCopy, err := verify.CopyByteArea(i*(int(bundleSize)), (i+1)*(int(bundleSize)), reader) if err != nil { return err } @@ -141,5 +130,8 @@ func SetupCommand(_ *cobra.Command, args []string) error { return err } fmt.Println(string(signature)) + + //header, err := core. + return nil } diff --git a/verifysetup/core/storage.go b/verifysetup/core/storage.go index 56d32af..48a31d9 100644 --- a/verifysetup/core/storage.go +++ b/verifysetup/core/storage.go @@ -63,3 +63,8 @@ func AddNode(node verify.Node, tx *bolt.Tx) error { } return nil } + +func CreateHeader(unsignedHash string, signedHash string, diskSize int, tableSize int) ([]byte, error) { + header := make([]byte, 200) + +} |