aboutsummaryrefslogtreecommitdiff
path: root/internal/contentenc
diff options
context:
space:
mode:
authordanim72017-04-08 02:09:28 +0200
committerJakob Unterwurzacher2017-04-23 23:11:56 +0200
commitf1945c4daae65074cfca8f0ab5b97ac5a50c24a0 (patch)
treef6a555c9d7fedb0da6f5e21981f4154fa413c8c0 /internal/contentenc
parent9777e4bf7ea2aa75ab443dc6e15c42103eb6b027 (diff)
Add -forcedecode
Force decode of encrypted files even if the integrity check fails, instead of failing with an IO error. Warning messages are still printed to syslog if corrupted files are encountered. It can be useful to recover files from disks with bad sectors or other corrupted media. Closes https://github.com/rfjakob/gocryptfs/pull/102 .
Diffstat (limited to 'internal/contentenc')
-rw-r--r--internal/contentenc/content.go16
-rw-r--r--internal/contentenc/content_test.go12
2 files changed, 19 insertions, 9 deletions
diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go
index a2a263c..9998c06 100644
--- a/internal/contentenc/content.go
+++ b/internal/contentenc/content.go
@@ -9,6 +9,7 @@ import (
"log"
"github.com/rfjakob/gocryptfs/internal/cryptocore"
+ "github.com/rfjakob/gocryptfs/internal/stupidgcm"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@@ -46,10 +47,12 @@ type ContentEnc struct {
allZeroBlock []byte
// All-zero block of size IVBitLen/8, for fast compares
allZeroNonce []byte
+ // Force decode even if integrity check fails (openSSL only)
+ forceDecode bool
}
// New returns an initialized ContentEnc instance.
-func New(cc *cryptocore.CryptoCore, plainBS uint64) *ContentEnc {
+func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEnc {
cipherBS := plainBS + uint64(cc.IVLen) + cryptocore.AuthTagLen
return &ContentEnc{
@@ -58,6 +61,7 @@ func New(cc *cryptocore.CryptoCore, plainBS uint64) *ContentEnc {
cipherBS: cipherBS,
allZeroBlock: make([]byte, cipherBS),
allZeroNonce: make([]byte, cc.IVLen),
+ forceDecode: forceDecode,
}
}
@@ -82,7 +86,9 @@ func (be *ContentEnc) DecryptBlocks(ciphertext []byte, firstBlockNo uint64, file
var pBlock []byte
pBlock, err = be.DecryptBlock(cBlock, firstBlockNo, fileID)
if err != nil {
- break
+ if be.forceDecode == false || (be.forceDecode == true && stupidgcm.AuthError != err) {
+ break
+ }
}
pBuf.Write(pBlock)
firstBlockNo++
@@ -133,7 +139,11 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b
if err != nil {
tlog.Warn.Printf("DecryptBlock: %s, len=%d", err.Error(), len(ciphertextOrig))
tlog.Debug.Println(hex.Dump(ciphertextOrig))
- return nil, err
+ if be.forceDecode == true {
+ return plaintext, err
+ } else {
+ return nil, err
+ }
}
return plaintext, nil
diff --git a/internal/contentenc/content_test.go b/internal/contentenc/content_test.go
index 8ce496d..e4d4a3e 100644
--- a/internal/contentenc/content_test.go
+++ b/internal/contentenc/content_test.go
@@ -23,8 +23,8 @@ func TestSplitRange(t *testing.T) {
testRange{6654, 8945})
key := make([]byte, cryptocore.KeyLen)
- cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true)
- f := New(cc, DefaultBS)
+ cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true, false)
+ f := New(cc, DefaultBS, false)
for _, r := range ranges {
parts := f.ExplodePlainRange(r.offset, r.length)
@@ -51,8 +51,8 @@ func TestCiphertextRange(t *testing.T) {
testRange{6654, 8945})
key := make([]byte, cryptocore.KeyLen)
- cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true)
- f := New(cc, DefaultBS)
+ cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true, false)
+ f := New(cc, DefaultBS, false)
for _, r := range ranges {
@@ -74,8 +74,8 @@ func TestCiphertextRange(t *testing.T) {
func TestBlockNo(t *testing.T) {
key := make([]byte, cryptocore.KeyLen)
- cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true)
- f := New(cc, DefaultBS)
+ cc := cryptocore.New(key, cryptocore.BackendOpenSSL, DefaultIVBits, true, false)
+ f := New(cc, DefaultBS, false)
b := f.CipherOffToBlockNo(788)
if b != 0 {