diff options
author | Jakob Unterwurzacher | 2017-06-30 23:24:12 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2017-06-30 23:24:12 +0200 |
commit | e4b5005bcce471ab017a3f8e44e1298424aefad4 (patch) | |
tree | b1b8feea60dcc86344b74533c2344673fb709ca4 /internal | |
parent | b2a23e94d10a7e3f7e25db50211b167f6fb280da (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.
Diffstat (limited to 'internal')
-rw-r--r-- | internal/stupidgcm/stupidgcm.go | 16 | ||||
-rw-r--r-- | internal/stupidgcm/stupidgcm_test.go | 7 |
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) { |