Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/cipher: BlockMode and HSMs #26787

optnfast opened this issue Aug 3, 2018 · 3 comments

crypto/cipher: BlockMode and HSMs #26787

optnfast opened this issue Aug 3, 2018 · 3 comments


Copy link

@optnfast optnfast commented Aug 3, 2018

I am a maintainer of a Go package which provides access to keys held in PKCS#11 HSMs to Go programs, using (as far as possible) native Go crypto APIs.

For asymmetric keys, this was a pleasant experience. It was straightforward to expose ECDSA keys via crypto.Signer. The interface was obviously designed with HSMs in mind (and we appreciate the thought l-)

Currently I am adding support for symmetric keys. This can be made to work but certain operations are very slow, due to a mismatch between the PKCS#11 API and the Go crypto/cipher APIs.

Specifically, to efficiently perform 'bulk' crypto operations, the PKCS#11 API requires a sequence of three calls:

  1. C_EncryptInit
  2. C_EncryptUpdate (any number of times)
  3. C_EncryptFinal

Even if the mode in question does not produce any ciphertext in the call to C_EncryptFinal, it is necessary to call it in order to release resources.

However, cipher.Block and cipher.BlockMode provide no way for the caller to signal that they are finished. Essentially they lack a Close method. So an implementation of either of these interfaces that uses an HSM is not possible.

It is possible, of course, for a cipher.Block to encrypt a single block and clean up after itself (and this is what I've done). However using such an implementation from cipher.NewCBCEncrypter can be hundreds of times slower than an idiomatic PKCS#11-aware implementation.

My questions/requests in this issue are:

  1. Is there any possibility of adding Close() methods to the existing cipher.Block and cipher.BlockMode interfaces?
  2. Failing that is there any way for an implementation to detect that its object is no longer referenced and the underlying resources can be released? i.e. something analogous to, or attacking the same problem as, a C# finalizer?

See ThalesIgnite/crypto11#6 for additional information, although I believe I've captured everything relevant above.

What version of Go are you using (go version)?

go version go1.10.3 linux/amd64

Does this issue reproduce with the latest release?


What operating system and processor architecture are you using (go env)?

GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build914934708=/tmp/go-build -gno-record-gcc-switches"
@ianlancetaylor ianlancetaylor changed the title cipher.BlockMode and HSMs crypto/cipher: BlockMode and HSMs Aug 3, 2018
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Aug 3, 2018

This comment has been minimized.

Copy link

@ianlancetaylor ianlancetaylor commented Aug 3, 2018


This comment has been minimized.

Copy link

@agl agl commented Aug 3, 2018

The AEAD interface might be better suited here as I don't believe that we can add a Close method at this point.

However, r.e. your #2, set you aware of SetFinalizer?


This comment has been minimized.

Copy link

@optnfast optnfast commented Aug 6, 2018

Thankyou, I've adopted both suggestions.

Is there any work being done on future crypto APIs in Go? If so where can I go to help make them HSM-friendly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.