// Open decrypts and authenticates ciphertext, authenticates the // additional data and, if successful, appends the resulting plaintext // to dst, returning the updated slice. The nonce must be NonceSize() // bytes long and both it and the additional data must match the // value passed to Seal. // // The ciphertext and dst may alias exactly or not at all. func (be opensslGCM) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { l := len(ciphertext) tag := ciphertext[l-AUTH_TAG_LEN : l] ciphertext = ciphertext[0 : l-AUTH_TAG_LEN] plainBuf := bytes.NewBuffer(dst) dctx, err := openssl.NewGCMDecryptionCipherCtx(KEY_LEN*8, nil, be.key, nonce) if err != nil { return nil, err } err = dctx.ExtraData(data) if err != nil { return nil, err } part, err := dctx.DecryptUpdate(ciphertext) if err != nil { return nil, err } plainBuf.Write(part) err = dctx.SetTag(tag) if err != nil { return nil, err } part, err = dctx.DecryptFinal() if err != nil { return nil, err } plainBuf.Write(part) return plainBuf.Bytes(), nil }
func BenchmarkOpensslDec4K(b *testing.B) { buf := makeOpensslCiphertext() b.SetBytes(int64(1024 * 4)) tag := buf[4096:] buf = buf[0:4096] var key [cryptfs.KEY_LEN]byte var nonce [12]byte var plaintext bytes.Buffer var part []byte b.ResetTimer() for i := 0; i < b.N; i++ { plaintext.Reset() dctx, err := openssl.NewGCMDecryptionCipherCtx(cryptfs.KEY_LEN*8, nil, key[:], nonce[:]) if err != nil { b.FailNow() } part, err = dctx.DecryptUpdate(buf) if err != nil { b.FailNow() } plaintext.Write(part) err = dctx.SetTag(tag) if err != nil { b.FailNow() } part, err = dctx.DecryptFinal() if err != nil { b.FailNow() } plaintext.Write(part) } }