From e4b5005bcce471ab017a3f8e44e1298424aefad4 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Fri, 30 Jun 2017 23:24:12 +0200 Subject: stupidgcm: Open: if "dst" is big enough, use it as the output buffer This means we won't need any allocation for the plaintext. --- internal/stupidgcm/stupidgcm.go | 16 +++++++++++++++- internal/stupidgcm/stupidgcm_test.go | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) 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) { -- cgit v1.2.3