aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-09-03 18:57:28 +0200
committerJakob Unterwurzacher2015-09-03 19:09:11 +0200
commitf8fddff7694b2cb9487fd4b5cbe9f97a136600b0 (patch)
treec592e59683165d9af1116e65fa16ffddff1bb7c5
parent4e93fdf820695c6afb38d525b5cf1dcc64080305 (diff)
Split into FS and File
-rw-r--r--backend.go42
-rw-r--r--cryptfs/file.go (renamed from backend_content.go)28
-rw-r--r--cryptfs/fs.go (renamed from backend_metadata.go)70
-rw-r--r--cryptfs/log.go (renamed from log.go)2
-rw-r--r--cryptfs/nonce.go (renamed from backend_nonce.go)2
5 files changed, 78 insertions, 66 deletions
diff --git a/backend.go b/backend.go
deleted file mode 100644
index ad80b9a..0000000
--- a/backend.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package gocryptfs
-
-import (
- "crypto/cipher"
- "crypto/aes"
-)
-
-const (
- NONCE_LEN = 12
- AUTH_TAG_LEN = 16
- DEFAULT_PLAINBS = 4096
-
- ENCRYPT = true
- DECRYPT = false
-)
-
-type Backend struct {
- blockCipher cipher.Block
- gcm cipher.AEAD
- plainBS int64
- cipherBS int64
-}
-
-func New(key [16]byte) *Backend {
-
- b, err := aes.NewCipher(key[:])
- if err != nil {
- panic(err)
- }
-
- g, err := cipher.NewGCM(b)
- if err != nil {
- panic(err)
- }
-
- return &Backend{
- blockCipher: b,
- gcm: g,
- plainBS: DEFAULT_PLAINBS,
- cipherBS: DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN,
- }
-}
diff --git a/backend_content.go b/cryptfs/file.go
index 3cf2a87..77262d4 100644
--- a/backend_content.go
+++ b/cryptfs/file.go
@@ -1,19 +1,27 @@
-package gocryptfs
+package cryptfs
import (
"fmt"
"os"
"io"
"errors"
+ "crypto/cipher"
)
+type File struct {
+ file *os.File
+ gcm cipher.AEAD
+ plainBS int64
+ cipherBS int64
+}
+
// readCipherBlock - Read ciphertext block number "blockNo", decrypt,
// return plaintext
-func (be *Backend) readCipherBlock(blockNo int64, f *os.File) ([]byte, error) {
+func (be *File) readCipherBlock(blockNo int64) ([]byte, error) {
off := blockNo * int64(be.cipherBS)
buf := make([]byte, be.cipherBS)
- readN, err := f.ReadAt(buf, off)
+ readN, err := be.file.ReadAt(buf, off)
if err != nil && err != io.EOF {
return nil, err
@@ -56,7 +64,7 @@ type intraBlock struct {
}
// Split a plaintext byte range into (possible partial) blocks
-func (be *Backend) splitRange(offset int64, length int64, f *os.File) []intraBlock {
+func (be *File) splitRange(offset int64, length int64) []intraBlock {
var b intraBlock
var parts []intraBlock
@@ -71,7 +79,7 @@ func (be *Backend) splitRange(offset int64, length int64, f *os.File) []intraBlo
return parts
}
-func (be *Backend) min64(x int64, y int64) int64 {
+func (be *File) min64(x int64, y int64) int64 {
if x < y {
return x
}
@@ -79,7 +87,7 @@ func (be *Backend) min64(x int64, y int64) int64 {
}
// writeCipherBlock - Encrypt plaintext and write it to file block "blockNo"
-func (be *Backend) writeCipherBlock(blockNo int64, plain []byte, f *os.File) error {
+func (be *File) writeCipherBlock(blockNo int64, plain []byte) error {
if int64(len(plain)) > be.plainBS {
panic("writeCipherBlock: Cannot write block that is larger than plainBS")
@@ -91,7 +99,7 @@ func (be *Backend) writeCipherBlock(blockNo int64, plain []byte, f *os.File) err
cipherBuf := be.gcm.Seal(nonce, nonce, plain, nil)
// WriteAt retries short writes autmatically
- written, err := f.WriteAt(cipherBuf, blockNo * be.cipherBS)
+ written, err := be.file.WriteAt(cipherBuf, blockNo * be.cipherBS)
debug.Printf("writeCipherBlock: wrote %d ciphertext bytes to block %d\n",
written, blockNo)
@@ -101,12 +109,12 @@ func (be *Backend) writeCipherBlock(blockNo int64, plain []byte, f *os.File) err
// Perform RMW cycle on block
// Write "data" into file location specified in "b"
-func (be *Backend) rmwWrite(b intraBlock, data []byte, f *os.File) error {
+func (be *File) rmwWrite(b intraBlock, data []byte, f *os.File) error {
if b.length != int64(len(data)) {
panic("Length mismatch")
}
- oldBlock, err := be.readCipherBlock(b.blockNo, f)
+ oldBlock, err := be.readCipherBlock(b.blockNo)
if err != nil {
return err
}
@@ -128,7 +136,7 @@ func (be *Backend) rmwWrite(b intraBlock, data []byte, f *os.File) error {
copy(newBlock[b.offset:b.offset + b.length], data)
// Actual write
- err = be.writeCipherBlock(b.blockNo, newBlock, f)
+ err = be.writeCipherBlock(b.blockNo, newBlock)
if err != nil {
// An incomplete write to a ciphertext block means that the whole block
diff --git a/backend_metadata.go b/cryptfs/fs.go
index 9d2e556..b40dcf3 100644
--- a/backend_metadata.go
+++ b/cryptfs/fs.go
@@ -1,16 +1,62 @@
-package gocryptfs
+package cryptfs
import (
- "errors"
+ "crypto/cipher"
+ "crypto/aes"
"fmt"
"strings"
"encoding/base64"
- "crypto/cipher"
- "crypto/aes"
+ "errors"
+ "os"
)
+const (
+ NONCE_LEN = 12
+ AUTH_TAG_LEN = 16
+ DEFAULT_PLAINBS = 4096
+
+ ENCRYPT = true
+ DECRYPT = false
+)
+
+type FS struct {
+ blockCipher cipher.Block
+ gcm cipher.AEAD
+ plainBS int64
+ cipherBS int64
+}
+
+func New(key [16]byte) *FS {
+
+ b, err := aes.NewCipher(key[:])
+ if err != nil {
+ panic(err)
+ }
+
+ g, err := cipher.NewGCM(b)
+ if err != nil {
+ panic(err)
+ }
+
+ return &FS{
+ blockCipher: b,
+ gcm: g,
+ plainBS: DEFAULT_PLAINBS,
+ cipherBS: DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN,
+ }
+}
+
+func (fs *FS) NewFile(f *os.File) *File {
+ return &File {
+ file: f,
+ gcm: fs.gcm,
+ plainBS: fs.plainBS,
+ cipherBS: fs.cipherBS,
+ }
+}
+
// DecryptName - decrypt filename
-func (be *Backend) decryptName(cipherName string) (string, error) {
+func (be *FS) decryptName(cipherName string) (string, error) {
bin, err := base64.URLEncoding.DecodeString(cipherName)
if err != nil {
@@ -35,7 +81,7 @@ func (be *Backend) decryptName(cipherName string) (string, error) {
}
// EncryptName - encrypt filename
-func (be *Backend) encryptName(plainName string) string {
+func (be *FS) encryptName(plainName string) string {
bin := []byte(plainName)
bin = be.pad16(bin)
@@ -51,7 +97,7 @@ func (be *Backend) encryptName(plainName string) string {
// TranslatePath - encrypt or decrypt path. Just splits the string on "/"
// and hands the parts to EncryptName() / DecryptName()
-func (be *Backend) translatePath(path string, op bool) (string, error) {
+func (be *FS) translatePath(path string, op bool) (string, error) {
var err error
// Empty string means root directory
@@ -79,18 +125,18 @@ func (be *Backend) translatePath(path string, op bool) (string, error) {
}
// EncryptPath - encrypt filename or path. Just hands it to TranslatePath().
-func (be *Backend) EncryptPath(path string) string {
+func (be *FS) EncryptPath(path string) string {
newPath, _ := be.translatePath(path, ENCRYPT)
return newPath
}
// DecryptPath - decrypt filename or path. Just hands it to TranslatePath().
-func (be *Backend) DecryptPath(path string) (string, error) {
+func (be *FS) DecryptPath(path string) (string, error) {
return be.translatePath(path, DECRYPT)
}
// plainSize - calculate plaintext size from ciphertext size
-func (be *Backend) PlainSize(s int64) int64 {
+func (be *FS) PlainSize(s int64) int64 {
// Zero sized files stay zero-sized
if s > 0 {
// Number of blocks
@@ -103,7 +149,7 @@ func (be *Backend) PlainSize(s int64) int64 {
// pad16 - pad filename to 16 byte blocks using standard PKCS#7 padding
// https://tools.ietf.org/html/rfc5652#section-6.3
-func (be *Backend) pad16(orig []byte) (padded []byte) {
+func (be *FS) pad16(orig []byte) (padded []byte) {
oldLen := len(orig)
if oldLen == 0 {
panic("Padding zero-length string makes no sense")
@@ -123,7 +169,7 @@ func (be *Backend) pad16(orig []byte) (padded []byte) {
}
// unPad16 - remove padding
-func (be *Backend) unPad16(orig []byte) ([]byte, error) {
+func (be *FS) unPad16(orig []byte) ([]byte, error) {
oldLen := len(orig)
if oldLen % aes.BlockSize != 0 {
return nil, errors.New("Unaligned size")
diff --git a/log.go b/cryptfs/log.go
index a6c65b8..947b1c3 100644
--- a/log.go
+++ b/cryptfs/log.go
@@ -1,4 +1,4 @@
-package gocryptfs
+package cryptfs
import (
"fmt"
diff --git a/backend_nonce.go b/cryptfs/nonce.go
index 835a80f..3803b8c 100644
--- a/backend_nonce.go
+++ b/cryptfs/nonce.go
@@ -1,4 +1,4 @@
-package gocryptfs
+package cryptfs
import (
"encoding/binary"