@@ -4,6 +4,7 @@ package openssl
44
55// #include "goopenssl.h"
66import "C"
7+
78import (
89 "crypto/cipher"
910 "encoding/binary"
@@ -145,8 +146,6 @@ func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) {
145146
146147type evpCipher struct {
147148 key []byte
148- enc_ctx C.GO_EVP_CIPHER_CTX_PTR
149- dec_ctx C.GO_EVP_CIPHER_CTX_PTR
150149 kind cipherKind
151150 blockSize int
152151}
@@ -159,19 +158,9 @@ func newEVPCipher(key []byte, kind cipherKind) (*evpCipher, error) {
159158 c := & evpCipher {key : make ([]byte , len (key )), kind : kind }
160159 copy (c .key , key )
161160 c .blockSize = int (C .go_openssl_EVP_CIPHER_get_block_size (cipher ))
162- runtime .SetFinalizer (c , (* evpCipher ).finalize )
163161 return c , nil
164162}
165163
166- func (c * evpCipher ) finalize () {
167- if c .enc_ctx != nil {
168- C .go_openssl_EVP_CIPHER_CTX_free (c .enc_ctx )
169- }
170- if c .dec_ctx != nil {
171- C .go_openssl_EVP_CIPHER_CTX_free (c .dec_ctx )
172- }
173- }
174-
175164func (c * evpCipher ) encrypt (dst , src []byte ) error {
176165 if len (src ) < c .blockSize {
177166 return errors .New ("input not full block" )
@@ -184,15 +173,13 @@ func (c *evpCipher) encrypt(dst, src []byte) error {
184173 if inexactOverlap (dst [:c .blockSize ], src [:c .blockSize ]) {
185174 return errors .New ("invalid buffer overlap" )
186175 }
187- if c .enc_ctx == nil {
188- var err error
189- c .enc_ctx , err = newCipherCtx (c .kind , cipherModeECB , cipherOpEncrypt , c .key , nil )
190- if err != nil {
191- return err
192- }
176+ enc_ctx , err := newCipherCtx (c .kind , cipherModeECB , cipherOpEncrypt , c .key , nil )
177+ if err != nil {
178+ return err
193179 }
180+ defer C .go_openssl_EVP_CIPHER_CTX_free (enc_ctx )
194181
195- if C .go_openssl_EVP_EncryptUpdate_wrapper (c . enc_ctx , base (dst ), base (src ), C .int (c .blockSize )) != 1 {
182+ if C .go_openssl_EVP_EncryptUpdate_wrapper (enc_ctx , base (dst ), base (src ), C .int (c .blockSize )) != 1 {
196183 return errors .New ("EncryptUpdate failed" )
197184 }
198185 runtime .KeepAlive (c )
@@ -211,18 +198,17 @@ func (c *evpCipher) decrypt(dst, src []byte) error {
211198 if inexactOverlap (dst [:c .blockSize ], src [:c .blockSize ]) {
212199 return errors .New ("invalid buffer overlap" )
213200 }
214- if c .dec_ctx == nil {
215- var err error
216- c .dec_ctx , err = newCipherCtx (c .kind , cipherModeECB , cipherOpDecrypt , c .key , nil )
217- if err != nil {
218- return err
219- }
220- if C .go_openssl_EVP_CIPHER_CTX_set_padding (c .dec_ctx , 0 ) != 1 {
221- return errors .New ("could not disable cipher padding" )
222- }
201+ dec_ctx , err := newCipherCtx (c .kind , cipherModeECB , cipherOpDecrypt , c .key , nil )
202+ if err != nil {
203+ return err
204+ }
205+ defer C .go_openssl_EVP_CIPHER_CTX_free (dec_ctx )
206+
207+ if C .go_openssl_EVP_CIPHER_CTX_set_padding (dec_ctx , 0 ) != 1 {
208+ return errors .New ("could not disable cipher padding" )
223209 }
224210
225- C .go_openssl_EVP_DecryptUpdate_wrapper (c . dec_ctx , base (dst ), base (src ), C .int (c .blockSize ))
211+ C .go_openssl_EVP_DecryptUpdate_wrapper (dec_ctx , base (dst ), base (src ), C .int (c .blockSize ))
226212 runtime .KeepAlive (c )
227213 return nil
228214}
@@ -321,7 +307,7 @@ const (
321307)
322308
323309type cipherGCM struct {
324- ctx C. GO_EVP_CIPHER_CTX_PTR
310+ c * evpCipher
325311 tls cipherGCMTLS
326312 // minNextNonce is the minimum value that the next nonce can be, enforced by
327313 // all TLS modes.
@@ -379,19 +365,10 @@ func (c *evpCipher) newGCMChecked(nonceSize, tagSize int) (cipher.AEAD, error) {
379365}
380366
381367func (c * evpCipher ) newGCM (tls cipherGCMTLS ) (cipher.AEAD , error ) {
382- ctx , err := newCipherCtx (c .kind , cipherModeGCM , cipherOpNone , c .key , nil )
383- if err != nil {
384- return nil , err
385- }
386- g := & cipherGCM {ctx : ctx , tls : tls , blockSize : c .blockSize }
387- runtime .SetFinalizer (g , (* cipherGCM ).finalize )
368+ g := & cipherGCM {c : c , tls : tls , blockSize : c .blockSize }
388369 return g , nil
389370}
390371
391- func (g * cipherGCM ) finalize () {
392- C .go_openssl_EVP_CIPHER_CTX_free (g .ctx )
393- }
394-
395372func (g * cipherGCM ) NonceSize () int {
396373 return gcmStandardNonceSize
397374}
@@ -464,14 +441,19 @@ func (g *cipherGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
464441 panic ("cipher: invalid buffer overlap" )
465442 }
466443
444+ ctx , err := newCipherCtx (g .c .kind , cipherModeGCM , cipherOpNone , g .c .key , nil )
445+ if err != nil {
446+ panic (err )
447+ }
448+ defer C .go_openssl_EVP_CIPHER_CTX_free (ctx )
467449 // Encrypt additional data.
468450 // When sealing a TLS payload, OpenSSL app sets the additional data using
469451 // 'EVP_CIPHER_CTX_ctrl(g.ctx, C.EVP_CTRL_AEAD_TLS1_AAD, C.EVP_AEAD_TLS1_AAD_LEN, base(additionalData))'.
470452 // This makes the explicit nonce component to monotonically increase on every Seal operation without
471453 // relying in the explicit nonce being securely set externally,
472454 // and it also gives some interesting speed gains.
473455 // Unfortunately we can't use it because Go expects AEAD.Seal to honor the provided nonce.
474- if C .go_openssl_EVP_CIPHER_CTX_seal_wrapper (g . ctx , base (out ), base (nonce ),
456+ if C .go_openssl_EVP_CIPHER_CTX_seal_wrapper (ctx , base (out ), base (nonce ),
475457 base (plaintext ), C .int (len (plaintext )),
476458 base (additionalData ), C .int (len (additionalData ))) != 1 {
477459
@@ -506,8 +488,13 @@ func (g *cipherGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte,
506488 panic ("cipher: invalid buffer overlap" )
507489 }
508490
491+ ctx , err := newCipherCtx (g .c .kind , cipherModeGCM , cipherOpNone , g .c .key , nil )
492+ if err != nil {
493+ return nil , err
494+ }
495+ defer C .go_openssl_EVP_CIPHER_CTX_free (ctx )
509496 ok := C .go_openssl_EVP_CIPHER_CTX_open_wrapper (
510- g . ctx , base (out ), base (nonce ),
497+ ctx , base (out ), base (nonce ),
511498 base (ciphertext ), C .int (len (ciphertext )),
512499 base (additionalData ), C .int (len (additionalData )), base (tag ))
513500 runtime .KeepAlive (g )
0 commit comments