summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-06-30 23:24:12 +0200
committerJakob Unterwurzacher2017-06-30 23:24:12 +0200
commite4b5005bcce471ab017a3f8e44e1298424aefad4 (patch)
treeb1b8feea60dcc86344b74533c2344673fb709ca4
parentb2a23e94d10a7e3f7e25db50211b167f6fb280da (diff)
stupidgcm: Open: if "dst" is big enough, use it as the output buffer
This means we won't need any allocation for the plaintext.
-rw-r--r--internal/stupidgcm/stupidgcm.go16
-rw-r--r--internal/stupidgcm/stupidgcm_test.go7
2 files changed, 22 insertions, 1 deletions
diff --git a/internal/stupidgcm/stupidgcm.go b/internal/stupidgcm/stupidgcm.go
index 54915df..d690f93 100644
--- a/internal/stupidgcm/stupidgcm.go
+++ b/internal/stupidgcm/stupidgcm.go
@@ -139,7 +139,18 @@ func (g stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
if len(in) <= tagLen {
log.Panic("Input data too short")
}
- buf := make([]byte, len(in)-tagLen)
+
+ // If the "dst" slice is large enough we can use it as our output buffer
+ outLen := len(in) - tagLen
+ var buf []byte
+ inplace := false
+ if cap(dst)-len(dst) >= outLen {
+ inplace = true
+ buf = dst[len(dst) : len(dst)+outLen]
+ } else {
+ buf = make([]byte, len(in)-tagLen)
+ }
+
ciphertext := in[:len(in)-tagLen]
tag := in[len(in)-tagLen:]
@@ -207,5 +218,8 @@ func (g stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
return nil, ErrAuth
}
+ if inplace {
+ return dst[:len(dst)+outLen], nil
+ }
return append(dst, buf...), nil
}
diff --git a/internal/stupidgcm/stupidgcm_test.go b/internal/stupidgcm/stupidgcm_test.go
index 4d37d08..e5c99da 100644
--- a/internal/stupidgcm/stupidgcm_test.go
+++ b/internal/stupidgcm/stupidgcm_test.go
@@ -112,6 +112,13 @@ func TestInplaceSeal(t *testing.T) {
}
}
+// Open re-uses the "dst" buffer it is large enough.
+// Check that this works correctly by testing different "dst" capacities from
+// 5000 to 16 and "in" lengths from 1 to 5000.
+func TestInplaceOpen(t *testing.T) {
+ t.Skipf("TODO: IMPLEMENT TEST")
+}
+
// TestCorruption verifies that changes in the ciphertext result in a decryption
// error
func TestCorruption(t *testing.T) {