summaryrefslogtreecommitdiff
path: root/internal/stupidgcm
diff options
context:
space:
mode:
authordanim72017-04-08 02:09:28 +0200
committerJakob Unterwurzacher2017-04-23 23:11:56 +0200
commitf1945c4daae65074cfca8f0ab5b97ac5a50c24a0 (patch)
treef6a555c9d7fedb0da6f5e21981f4154fa413c8c0 /internal/stupidgcm
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/stupidgcm')
-rw-r--r--internal/stupidgcm/stupidgcm.go18
-rw-r--r--internal/stupidgcm/stupidgcm_test.go4
-rw-r--r--internal/stupidgcm/without_openssl.go5
3 files changed, 20 insertions, 7 deletions
diff --git a/internal/stupidgcm/stupidgcm.go b/internal/stupidgcm/stupidgcm.go
index a1a5a14..133ee1a 100644
--- a/internal/stupidgcm/stupidgcm.go
+++ b/internal/stupidgcm/stupidgcm.go
@@ -26,17 +26,21 @@ const (
// stupidGCM implements the cipher.AEAD interface
type stupidGCM struct {
- key []byte
+ key []byte
+ forceDecode bool
}
+//authentication error
+var AuthError error = fmt.Errorf("stupidgcm: message authentication failed")
+
var _ cipher.AEAD = &stupidGCM{}
// New returns a new cipher.AEAD implementation..
-func New(key []byte) cipher.AEAD {
+func New(key []byte, forceDecode bool) cipher.AEAD {
if len(key) != keyLen {
log.Panicf("Only %d-byte keys are supported", keyLen)
}
- return stupidGCM{key: key}
+ return stupidGCM{key: key, forceDecode: forceDecode}
}
func (g stupidGCM) NonceSize() int {
@@ -186,7 +190,13 @@ func (g stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
C.EVP_CIPHER_CTX_free(ctx)
if res != 1 {
- return nil, fmt.Errorf("stupidgcm: message authentication failed")
+ // The error code must always be checked by the calling function, because the decrypted buffer
+ // may contain corrupted data that we are returning in case the user forced reads
+ if g.forceDecode == true {
+ return append(dst, buf...), AuthError
+ } else {
+ return nil, AuthError
+ }
}
return append(dst, buf...), nil
diff --git a/internal/stupidgcm/stupidgcm_test.go b/internal/stupidgcm/stupidgcm_test.go
index 3081085..eb322f2 100644
--- a/internal/stupidgcm/stupidgcm_test.go
+++ b/internal/stupidgcm/stupidgcm_test.go
@@ -27,7 +27,7 @@ func randBytes(n int) []byte {
// GCM implemenatation and verifies that the results are identical.
func TestEncryptDecrypt(t *testing.T) {
key := randBytes(32)
- sGCM := New(key)
+ sGCM := New(key, false)
authData := randBytes(24)
iv := randBytes(16)
dst := make([]byte, 71) // 71 = random length
@@ -77,7 +77,7 @@ func TestEncryptDecrypt(t *testing.T) {
// error
func TestCorruption(t *testing.T) {
key := randBytes(32)
- sGCM := New(key)
+ sGCM := New(key, false)
authData := randBytes(24)
iv := randBytes(16)
diff --git a/internal/stupidgcm/without_openssl.go b/internal/stupidgcm/without_openssl.go
index 18c5ddc..52d8fa0 100644
--- a/internal/stupidgcm/without_openssl.go
+++ b/internal/stupidgcm/without_openssl.go
@@ -14,12 +14,15 @@ const (
BuiltWithoutOpenssl = true
)
+//authentication error - needed to compile as same varaible is exported when openssl is enable via stupidgcm.go
+var AuthError error = fmt.Errorf("stupidgcm: message authentication failed with openssl disabled!")
+
func errExit() {
fmt.Fprintln(os.Stderr, "gocryptfs has been compiled without openssl support but you are still trying to use openssl")
os.Exit(2)
}
-func New(_ []byte) stupidGCM {
+func New(_ []byte, _ bool) stupidGCM {
errExit()
// Never reached
return stupidGCM{}