crypto11

package module
v2.0.0-rc4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 27 Imported by: 0

README

Crypto11

Go Reference Build Lint Secret Scan Release OpenSSF Scorecard GitHub release Changelog

This is an implementation of the standard Golang crypto interfaces that uses PKCS#11 as a backend.

Low-level PKCS#11 (Cryptoki) bindings, including the PKCS#11 v3.2 mechanisms needed for post-quantum algorithms such as ML-KEM, are provided by github.com/eclipse-keypont/pkcs11-go. crypto11 builds the familiar crypto.Signer / crypto.Decrypter Go interfaces on top of it.

v2 is a breaking release: the PKCS#11 binding moved to pkcs11-go, bringing PKCS#11 v3.2 and post-quantum ML-KEM key support, alongside a full lint/vet cleanup and a security-hardening pass. See CHANGELOG.md for a summary of what changed between v1 and v2, or Releases for the full commit-level history.

This repository is built with a hardened GitHub Actions pipeline: golangci-lint, govulncheck, CodeQL, secret scanning, dependency review, and an OpenSSF Scorecard rating gate every push, and tagged releases ship a signed, SLSA3-attested source archive plus a signed CycloneDX SBOM rather than just being pushed — see Verifying release artifacts below for what ships and how to check it.

Part of Eclipse Keypont

crypto11 is part of Eclipse Keypont, alongside gose and pkcs11-go. Keypont — "key" plus the French pont ("bridge") — reflects the project's goal: bridging Go applications to cryptographic keys held in HSMs and other PKCS#11-backed hardware.

Supported Algorithms

Asymmetric keys

Algorithm Key generation Signing Decryption Notes
RSA PKCS#1 v1.5, PSS PKCS#1 v1.5, OAEP Via crypto.Signer / crypto.Decrypter
ECDSA Via crypto.Signer
DSA Via crypto.Signer

To verify signatures or encrypt messages, retrieve the public key and do it in software.

Post-quantum keys (PKCS#11 v3.2)

Algorithm Key generation Encapsulation Decapsulation Notes
ML-KEM 512 FIPS 203 / PKCS#11 v3.2 (CKM_ML_KEM)
ML-KEM 768 FIPS 203 / PKCS#11 v3.2 (CKM_ML_KEM)
ML-KEM 1024 FIPS 203 / PKCS#11 v3.2 (CKM_ML_KEM)

ML-KEM uses the MLKEMEncapsulator / MLKEMDecapsulator interfaces (not crypto.Signer). Requires a PKCS#11 v3.2-capable token such as SoftHSMv3.

Symmetric keys

Algorithm Key sizes Modes Notes
AES 128, 192, 256 bit CBC, GCM cipher.Block, cipher.BlockMode, BlockModeCloser, AEAD
DES3 192 bit CBC Token support varies

Other

Feature Notes
X.509 certificates Import and retrieval
HMAC Token support varies (not available on SoftHSM)
Random number generation Via io.Reader

Signing is done through the crypto.Signer interface and decryption through crypto.Decrypter.

See the documentation for details of various limitations, especially regarding symmetric crypto.

Installation

crypto11 requires Go 1.25 or later (see the go directive in go.mod). Install the library by running:

Note on Go version policy

crypto11 is a library. Bumping the go directive in go.mod raises the minimum Go version required by every project that imports it, which can break consumers still on older toolchains.

To avoid this, we follow a two-directive pattern:

  • go X.Y.0 — the minimum Go version consumers need (kept conservative).
  • toolchain go X.Y.Z — the recommended toolchain used by maintainers (tracks the latest patch release).

This lets projects on older Go versions still import crypto11, while maintainers can develop and test with the latest toolchain. See #137 for context.

go get github.com/eclipse-keypont/crypto11/v2

The crypto11 library needs to be configured with information about your PKCS#11 installation. This is either done programmatically (see the Config struct in the documentation) or via a configuration file. The configuration file is a JSON representation of the Config struct.

A minimal configuration file looks like this:

{
  "Path": "/usr/lib/softhsm/libsofthsm2.so",
  "TokenLabel": "token1",
  "Pin": "password"
}
  • Path points to the library from your PKCS#11 vendor.
  • TokenLabel is the CKA_LABEL of the token you wish to use.
  • Pin is the password for the CKU_USER user.
  • UseGCMIVFromHSM generates the IV for GCM mechanism from the HSM

Build

This package is using CGo for cryptographic packages.
Enable CGo before building Crypto11 :

go env -w CGO_ENABLED=1
go build

A Makefile wraps the common developer commands:

Target Description
make build go build ./...
make test go test ./... (see Testing Guidance below for HSM-backed coverage)
make lint Runs golangci-lint (v2) against .golangci.yml, same checks as CI
make lint-fix Runs golangci-lint with --fix for mechanically-fixable findings
make notices Regenerates NOTICES.md via go-licenses
make version Prints the most recent git tag
make release VERSION=x.y.z Creates a signed vx.y.z tag and pushes it, triggering the release workflow

Testing Guidance

Disabling tests

To disable specific tests, set the environment variable CRYPTO11_SKIP=<flags> where <flags> is a comma-separated list of the following options:

  • CERTS - disables certificate-related tests. Needed for AWS CloudHSM, which doesn't support certificates.
  • OAEP_LABEL - disables RSA OAEP encryption tests that use source data encoding parameter (also known as a 'label' in some crypto libraries). Needed for AWS CloudHSM.
  • DSA - disables DSA tests. Needed for AWS CloudHSM (and any other tokens not supporting DSA).

SoftHSMv3 supports PKCS#11 v3.2 and is required for ML-KEM and other post-quantum tests. Token provisioning is fully automated:

PKCS11_MODULE=/path/to/libsofthsmv3.so go test ./...

Override the user PIN (default 1234):

PKCS11_MODULE=/path/to/libsofthsmv3.so PKCS11_PIN=mypin go test ./...

TestMain in setup_test.go creates three ephemeral tokens (crypto11-test, token1, token2) via the PKCS#11 API, writes a temporary config file, runs all tests, then cleans up. No external tools or manual token setup are required.

DSA, DES3, PSS, and HMAC are not supported by SoftHSMv3 and those tests are automatically skipped.

Unit test on one file

export DEPENDENCIES="rand.go attributes.go hmac.go crypto11.go common.go keys.go rsa.go certificates.go ecdsa.go blockmode.go sessions.go aead.go dsa.go symmetric.go mlkem.go common_test.go"
go test blockmode_test.go $DEPENDENCIES

Remote debug :

dlv test --headless --listen=:2345 --api-version=2 --accept-multiclient blockmode_test.go $DEPENDENCIES

Testing with AWS CloudHSM

A minimal configuration file for CloudHSM will look like this:

{
  "Path": "/opt/cloudhsm/lib/libcloudhsm_pkcs11_standard.so",
  "TokenLabel": "cavium",
  "Pin": "username:password",
  "UseGCMIVFromHSM": true
}

To run the test suite you must skip unsupported tests:

CRYPTO11_SKIP=CERTS,OAEP_LABEL,DSA go test -v

Be sure to take note of the supported mechanisms, key types and other idiosyncrasies described at https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-library.html. Here's a collection of things we noticed when testing with the v2.0.4 PKCS#11 library:

  • 1024-bit RSA keys don't appear to be supported, despite what C_GetMechanismInfo tells you.
  • The CKM_RSA_PKCS_OAEP mechanism doesn't support source data. I.e. when constructing a CK_RSA_PKCS_OAEP_PARAMS, one must set pSourceData to NULL and ulSourceDataLen to zero.
  • CloudHSM will generate it's own IV for GCM mode. This is described in their documentation, see footnote 4 on https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-mechanisms.html.
  • It appears that CKA_ID values must be unique, otherwise you get a CKR_ATTRIBUTE_VALUE_INVALID error.
  • Very rapid session opening can trigger the following error:
    C_OpenSession failed with error CKR_ARGUMENTS_BAD : 0x00000007
    HSM error 8c: HSM Error: Already maximum number of sessions are issued
    

Testing with SoftHSM2

SoftHSMv2 covers all classical algorithms but does not support ML-KEM or other PKCS#11 v3.2 mechanisms (those tests will be skipped automatically via skipIfMechUnsupported).

To set up a slot:

$ cat softhsm2.conf
directories.tokendir = /home/rjk/go/src/github.com/eclipse-keypont/crypto11/tokens
objectstore.backend = file
log.level = INFO
$ mkdir tokens
$ export SOFTHSM2_CONF=`pwd`/softhsm2.conf
$ softhsm2-util --init-token --slot 0 --label test
=== SO PIN (4-255 characters) ===
Please enter SO PIN: ********
Please reenter SO PIN: ********
=== User PIN (4-255 characters) ===
Please enter user PIN: ********
Please reenter user PIN: ********
The token has been initialized.

The configuration looks like this:

{
  "Path" : "/usr/lib/softhsm/libsofthsm2.so",
  "TokenLabel": "test",
  "Pin" : "password"
}

OAEP is only partial and HMAC is unsupported on SoftHSMv2, so expect test skips.

Testing with nCipher nShield

In all cases, it's worth enabling nShield PKCS#11 log output:

export CKNFAST_DEBUG=2

To protect keys with a 1/N operator cardset:

{
  "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so",
  "TokenLabel": "rjk",
  "Pin" : "password"
}

You can also identify the token by serial number, which in this case means the first 16 hex digits of the operator cardset's token hash:

{
  "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so",
  "TokenSerial": "1d42780caa22efd5",
  "Pin" : "password"
}

A card from the cardset must be in the slot when you run go test.

To protect keys with the module only, use the 'accelerator' token:

{
  "Path" : "/opt/nfast/toolkits/pkcs11/libcknfast.so",
  "TokenLabel": "accelerator",
  "Pin" : "password"
}

(At time of writing) GCM is not implemented, so expect test skips.

Testing with a TPM and PKCS11

You must know that tpm2-pkcs11 is much more limited than other libraries like softhsm2 for cryptographic operations.
The absence of the C_GenerateKey function in the tpm2-pkcs11 library is one example of the limitations.
However, some of the tests have been modified to support the tpm2-pkcs11 library's specificities.

To test with a TPM, you need to :

  • install a virtual TPM or use a TPM on your machine
  • install the libtpm2_pkcs11 library
  • create all the keys you need for the unit tests in the TPM (since C_Generate key is not supported)

Configure :

{
  "Path": "/usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1",
  "TokenLabel": "mylabel",
  "Pin": "mypin"
}

Fine tune the unit tests to use the keys you created in the previous step.
Beware that a lot of unit tests may fail otherwise. You must fine-tune your usecase for a TPM usage.

Limitations

  • The PKCS1v15DecryptOptions SessionKeyLen field is not implemented and an error is returned if it is nonzero. The reason for this is that it is not possible for crypto11 to guarantee the constant-time behavior in the specification. See issue #5 for further discussion.
  • Symmetric crypto support via cipher.Block is very slow. You can use the BlockModeCloser API (over 400 times as fast on my computer) but you must call the Close() interface (not found in cipher.BlockMode). See issue #6 for further discussion.
  • Unit tests may interfere between them. You should fine tune and select the Go test file you want to run, one at a time.

Verifying release artifacts

Each GitHub Release ships a deterministic source archive plus everything needed to verify it without trusting GitHub. For a release vX.Y.Z you'll find:

Asset Purpose
crypto11-vX.Y.Z.tar.gz The source archive, built with git archive from the tagged commit
crypto11-vX.Y.Z.tar.gz.sha256 SHA-256 checksum of the archive
crypto11-vX.Y.Z.tar.gz.cosign.bundle Keyless cosign signature (signed via GitHub Actions OIDC — no private key involved)
crypto11-vX.Y.Z.cdx.json CycloneDX 1.6 SBOM of the module — see Software Bill of Materials
crypto11-vX.Y.Z.cdx.json.sha256 SHA-256 checksum of the SBOM
crypto11-vX.Y.Z.cdx.json.cosign.bundle Keyless cosign signature of the SBOM
crypto11-vX.Y.Z.intoto.jsonl SLSA3 build provenance covering both the archive and the SBOM, produced by slsa-github-generator

Download all assets for the release you want to verify:

gh release download vX.Y.Z --repo eclipse-keypont/crypto11

1. Verify the checksums

sha256sum -c crypto11-vX.Y.Z.tar.gz.sha256
sha256sum -c crypto11-vX.Y.Z.cdx.json.sha256

2. Verify the cosign signatures (requires cosign)

for f in crypto11-vX.Y.Z.tar.gz crypto11-vX.Y.Z.cdx.json; do
  cosign verify-blob \
    --bundle "$f.cosign.bundle" \
    --certificate-identity-regexp '^https://github\.com/eclipse-keypont/crypto11/\.github/workflows/release\.yml@refs/tags/v.*$' \
    --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
    "$f"
done

3. Verify the SLSA provenance (requires slsa-verifier)

The provenance has two subjects — the archive and the SBOM — so verify both in one call:

slsa-verifier verify-artifact \
  --provenance-path crypto11-vX.Y.Z.intoto.jsonl \
  --source-uri github.com/eclipse-keypont/crypto11 \
  --source-tag vX.Y.Z \
  crypto11-vX.Y.Z.tar.gz crypto11-vX.Y.Z.cdx.json

4. Verify the git tag itself — release tags are GPG/SSH-signed by make release (git tag -s):

git verify-tag vX.Y.Z

go get consumers don't need any of this — they fetch source through the Go module proxy and verify it via go.sum / sum.golang.org. These assets exist for auditors and to satisfy OpenSSF Scorecard's Signed-Releases check.

Software Bill of Materials

Every release ships a CycloneDX 1.6 SBOM (crypto11-vX.Y.Z.cdx.json), generated with cyclonedx-gomod and signed and attested exactly like the source archive (see Verifying release artifacts). It describes:

  • the crypto11 component itself, typed as a library, with its module path, version and VCS reference;
  • its build-time dependency graph — pkcs11-go and pkg/errors — as pkg:golang/... PackageURLs;
  • the Go standard library as a component (pkg:golang/std@goX.Y.Z), so stdlib CVEs stay visible to SBOM consumers, matching what govulncheck covers;
  • detected licenses, recorded as CycloneDX evidence rather than assertions (detection is heuristic).

Test-only dependencies (testify and friends) are deliberately excluded: they are not part of what a consumer of the library links against, and including them produces false positives in downstream vulnerability scanners.

Regenerate the SBOM yourself with the same flags CI uses:

go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.10.0
make sbom          # writes crypto11.cdx.json

The SBOM is generated with -noserial -notimestamp, so it is byte-reproducible from the tagged commit — checking out vX.Y.Z and running make sbom on linux/amd64 yields the same content as the published artifact (the goos/goarch PackageURL qualifiers make the output platform-specific).

Feed it into whatever consumes CycloneDX — for example Dependency-Track, osv-scanner (osv-scanner scan source --sbom crypto11-vX.Y.Z.cdx.json) or grype sbom:crypto11-vX.Y.Z.cdx.json.

Contributions

Contributions are gratefully received. Before beginning work on sizeable changes, please open an issue first to discuss.

Here are some topics we'd like to cover:

  • Full test instructions for additional PKCS#11 implementations.

Third-party notices

NOTICES.md lists all third-party dependency licenses and is auto-generated via make notices (requires go-licenses).

Vulnerability check

$ govulncheck ./...

Scanning your code and 112 packages across 5 dependent modules for known vulnerabilities...

No vulnerabilities found.

Documentation

Overview

Package crypto11 enables access to cryptographic keys from PKCS#11 using Go crypto API.

Configuration

PKCS#11 tokens are accessed via Context objects. Each Context connects to one token.

Context objects are created by calling Configure or ConfigureFromFile. In the latter case, the file should contain a JSON representation of a Config.

Key Generation and Usage

There is support for generating DSA, RSA and ECDSA keys. These keys can be found later using FindKeyPair. All three key types implement the crypto.Signer interface and the RSA keys also implement crypto.Decrypter.

RSA keys obtained through FindKeyPair will need a type assertion to be used for decryption. Assert either crypto.Decrypter or SignerDecrypter, as you prefer.

Symmetric keys can also be generated. These are found later using FindKey. See the documentation for SecretKey for further information.

Sessions and concurrency

Note that PKCS#11 session handles must not be used concurrently from multiple threads. Consumers of the Signer interface know nothing of this and expect to be able to sign from multiple threads without constraint. We address this as follows.

1. When a Context is created, a session is created and the user is logged in. This session remains open until the Context is closed, to ensure all object handles remain valid and to avoid repeatedly calling C_Login.

2. The Context also maintains a pool of read-write sessions. The pool expands dynamically as needed, but never beyond the maximum number of r/w sessions supported by the token (as reported by C_GetInfo). If other applications are using the token, a lower limit should be set in the Config.

3. Each operation transiently takes a session from the pool. They have exclusive use of the session, meeting PKCS#11's concurrency requirements. Sessions are returned to the pool afterwards and may be re-used.

Behaviour of the pool can be tweaked via Config fields:

- PoolWaitTimeout controls how long an operation can block waiting on a session from the pool. A zero value means there is no limit. Timeouts occur if the pool is fully used and additional operations are requested.

- MaxSessions sets an upper bound on the number of sessions. If this value is zero, a default maximum is used (see DefaultMaxSessions). In every case the maximum supported sessions as reported by the token is obeyed.

Context.PoolStats reports how the pool is coping, for metrics and for sizing the two values above.

Limitations

The PKCS1v15DecryptOptions SessionKeyLen field is not implemented and an error is returned if it is nonzero. The reason for this is that it is not possible for crypto11 to guarantee the constant-time behavior in the specification. See https://github.com/eclipse-keypont/crypto11/issues/5 for further discussion.

Symmetric crypto support via cipher.Block is very slow. You can use the BlockModeCloser API but you must call the Close() interface (not found in cipher.BlockMode). See https://github.com/eclipse-keypont/crypto11/issues/6 for further discussion.

Index

Constants

View Source
const (
	CkaClass                  = AttributeType(0x00000000)
	CkaToken                  = AttributeType(0x00000001)
	CkaPrivate                = AttributeType(0x00000002)
	CkaLabel                  = AttributeType(0x00000003)
	CkaApplication            = AttributeType(0x00000010)
	CkaValue                  = AttributeType(0x00000011)
	CkaObjectId               = AttributeType(0x00000012)
	CkaCertificateType        = AttributeType(0x00000080)
	CkaIssuer                 = AttributeType(0x00000081)
	CkaSerialNumber           = AttributeType(0x00000082)
	CkaAcIssuer               = AttributeType(0x00000083)
	CkaOwner                  = AttributeType(0x00000084)
	CkaAttrTypes              = AttributeType(0x00000085)
	CkaTrusted                = AttributeType(0x00000086)
	CkaCertificateCategory    = AttributeType(0x00000087)
	CkaJavaMIDPSecurityDomain = AttributeType(0x00000088)
	CkaUrl                    = AttributeType(0x00000089)
	CkaHashOfSubjectPublicKey = AttributeType(0x0000008A)
	CkaHashOfIssuerPublicKey  = AttributeType(0x0000008B)
	CkaNameHashAlgorithm      = AttributeType(0x0000008C)
	CkaCheckValue             = AttributeType(0x00000090)

	CkaKeyType         = AttributeType(0x00000100)
	CkaSubject         = AttributeType(0x00000101)
	CkaId              = AttributeType(0x00000102)
	CkaSensitive       = AttributeType(0x00000103)
	CkaEncrypt         = AttributeType(0x00000104)
	CkaDecrypt         = AttributeType(0x00000105)
	CkaWrap            = AttributeType(0x00000106)
	CkaUnwrap          = AttributeType(0x00000107)
	CkaSign            = AttributeType(0x00000108)
	CkaSignRecover     = AttributeType(0x00000109)
	CkaVerify          = AttributeType(0x0000010A)
	CkaVerifyRecover   = AttributeType(0x0000010B)
	CkaDerive          = AttributeType(0x0000010C)
	CkaStartDate       = AttributeType(0x00000110)
	CkaEndDate         = AttributeType(0x00000111)
	CkaModulus         = AttributeType(0x00000120)
	CkaModulusBits     = AttributeType(0x00000121)
	CkaPublicExponent  = AttributeType(0x00000122)
	CkaPrivateExponent = AttributeType(0x00000123)
	CkaPrime1          = AttributeType(0x00000124)
	CkaPrime2          = AttributeType(0x00000125)
	CkaExponent1       = AttributeType(0x00000126)
	CkaExponent2       = AttributeType(0x00000127)
	CkaCoefficient     = AttributeType(0x00000128)
	CkaPublicKeyInfo   = AttributeType(0x00000129)
	CkaPrime           = AttributeType(0x00000130)
	CkaSubprime        = AttributeType(0x00000131)
	CkaBase            = AttributeType(0x00000132)

	CkaPrimeBits    = AttributeType(0x00000133)
	CkaSubprimeBits = AttributeType(0x00000134)
	/* (To retain backwards-compatibility) */
	CkaSubPrimeBits = CkaSubprimeBits

	CkaValueBits        = AttributeType(0x00000160)
	CkaValueLen         = AttributeType(0x00000161)
	CkaExtractable      = AttributeType(0x00000162)
	CkaLocal            = AttributeType(0x00000163)
	CkaNeverExtractable = AttributeType(0x00000164)
	CkaAlwaysSensitive  = AttributeType(0x00000165)
	CkaKeyGenMechanism  = AttributeType(0x00000166)

	CkaModifiable = AttributeType(0x00000170)
	CkaCopyable   = AttributeType(0x00000171)

	/* new for v2.40 */
	CkaDestroyable = AttributeType(0x00000172)

	/* CKA_ECDSA_PARAMS is deprecated in v2.11,
	 * CKA_EC_PARAMS is preferred. */
	CkaEcdsaParams = AttributeType(0x00000180)
	CkaEcParams    = AttributeType(0x00000180)

	CkaEcPoint = AttributeType(0x00000181)

	/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
	 * are new for v2.10. Deprecated in v2.11 and onwards. */
	CkaSecondaryAuth = AttributeType(0x00000200) /* Deprecated */
	CkaAuthPinFlags  = AttributeType(0x00000201) /* Deprecated */

	CkaAlwaysAuthenticate = AttributeType(0x00000202)

	CkaWrapWithTrusted = AttributeType(0x00000210)

	CkaWrapTemplate   = ckfArrayAttribute | AttributeType(0x00000211)
	CkaUnwrapTemplate = ckfArrayAttribute | AttributeType(0x00000212)

	CkaOtpFormat               = AttributeType(0x00000220)
	CkaOtpLength               = AttributeType(0x00000221)
	CkaOtpTimeInterval         = AttributeType(0x00000222)
	CkaOtpUserFriendlyMode     = AttributeType(0x00000223)
	CkaOtpChallengeRequirement = AttributeType(0x00000224)
	CkaOtpTimeRequirement      = AttributeType(0x00000225)
	CkaOtpCounterRequirement   = AttributeType(0x00000226)
	CkaOtpPinRequirement       = AttributeType(0x00000227)
	CkaOtpCounter              = AttributeType(0x0000022E)
	CkaOtpTime                 = AttributeType(0x0000022F)
	CkaOtpUserIdentifier       = AttributeType(0x0000022A)
	CkaOtpServiceIdentifier    = AttributeType(0x0000022B)
	CkaOtpServiceLogoType      = AttributeType(0x0000022D)

	CkaGOSTR3410Params = AttributeType(0x00000250)
	CkaGOSTR3411Params = AttributeType(0x00000251)
	CkaGOST28147Params = AttributeType(0x00000252)

	CkaHwFeatureType = AttributeType(0x00000300)
	CkaResetOnInit   = AttributeType(0x00000301)
	CkaHasReset      = AttributeType(0x00000302)

	CkaPixelX                 = AttributeType(0x00000400)
	CkaPixelY                 = AttributeType(0x00000401)
	CkaResolution             = AttributeType(0x00000402)
	CkaCharRows               = AttributeType(0x00000403)
	CkaCharColumns            = AttributeType(0x00000404)
	CkaColor                  = AttributeType(0x00000405)
	CkaBitsPerPixel           = AttributeType(0x00000406)
	CkaCharSets               = AttributeType(0x00000480)
	CkaEncodingMethods        = AttributeType(0x00000481)
	CkaMimeTypes              = AttributeType(0x00000482)
	CkaMechanismType          = AttributeType(0x00000500)
	CkaRequiredCmsAttributes  = AttributeType(0x00000501)
	CkaDefaultCmsAttributes   = AttributeType(0x00000502)
	CkaSupportedCmsAttributes = AttributeType(0x00000503)
	CkaAllowedMechanisms      = ckfArrayAttribute | AttributeType(0x00000600)

	/* new for v3.2 (PKCS#11 v3.2, KEM / post-quantum) */
	CkaParameterSet        = AttributeType(0x0000061d)
	CkaEncapsulateTemplate = AttributeType(0x0000062a)
	CkaDecapsulateTemplate = AttributeType(0x0000062b)
	CkaEncapsulate         = AttributeType(0x00000633)
	CkaDecapsulate         = AttributeType(0x00000634)
)

noinspection GoUnusedConst,GoDeprecation

View Source
const (
	// DefaultMaxSessions controls the maximum number of concurrent sessions to
	// open, unless otherwise specified in the Config object.
	DefaultMaxSessions = 1024

	// DefaultGCMIVLength controls the expected length of IVs generated by the token
	DefaultGCMIVLength = 16

	// CryptoUser is the Thales vendor constant for CKU_CRYPTO_USER.
	CryptoUser = 0x80000001

	// DefaultUserType is the default PKCS#11 user type (CKU_USER).
	DefaultUserType = 1
)
View Source
const (
	// NFCK_VENDOR_NCIPHER distinguishes nShield vendor-specific mechanisms.
	NFCK_VENDOR_NCIPHER = 0xde436972

	// CKM_NCIPHER is the base for nShield vendor-specific mechanisms.
	CKM_NCIPHER = pkcs11.CKM_VENDOR_DEFINED | NFCK_VENDOR_NCIPHER

	// CKM_NC_MD5_HMAC_KEY_GEN is the nShield-specific HMACMD5 key-generation mechanism
	CKM_NC_MD5_HMAC_KEY_GEN = CKM_NCIPHER + 0x6

	// CKM_NC_SHA_1_HMAC_KEY_GEN is the nShield-specific HMACSHA1 key-generation mechanism
	CKM_NC_SHA_1_HMAC_KEY_GEN = CKM_NCIPHER + 0x3

	// CKM_NC_SHA224_HMAC_KEY_GEN is the nShield-specific HMACSHA224 key-generation mechanism
	CKM_NC_SHA224_HMAC_KEY_GEN = CKM_NCIPHER + 0x24

	// CKM_NC_SHA256_HMAC_KEY_GEN is the nShield-specific HMACSHA256 key-generation mechanism
	CKM_NC_SHA256_HMAC_KEY_GEN = CKM_NCIPHER + 0x25

	// CKM_NC_SHA384_HMAC_KEY_GEN is the nShield-specific HMACSHA384 key-generation mechanism
	CKM_NC_SHA384_HMAC_KEY_GEN = CKM_NCIPHER + 0x26

	// CKM_NC_SHA512_HMAC_KEY_GEN is the nShield-specific HMACSHA512 key-generation mechanism
	CKM_NC_SHA512_HMAC_KEY_GEN = CKM_NCIPHER + 0x27
)

Variables

View Source
var CipherAES = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_AES,
			GenMech: pkcs11.CKM_AES_KEY_GEN,
		},
	},
	BlockSize:   16,
	Encrypt:     true,
	MAC:         false,
	ECBMech:     pkcs11.CKM_AES_ECB,
	CBCMech:     pkcs11.CKM_AES_CBC,
	CBCPKCSMech: pkcs11.CKM_AES_CBC_PAD,
	GCMMech:     pkcs11.CKM_AES_GCM,
}

CipherAES describes the AES cipher. Use this with the GenerateSecretKey... functions.

View Source
var CipherDES3 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_DES3,
			GenMech: pkcs11.CKM_DES3_KEY_GEN,
		},
	},
	BlockSize:   8,
	Encrypt:     true,
	MAC:         false,
	ECBMech:     pkcs11.CKM_DES3_ECB,
	CBCMech:     pkcs11.CKM_DES3_CBC,
	CBCPKCSMech: pkcs11.CKM_DES3_CBC_PAD,
	GCMMech:     0,
}

CipherDES3 describes the three-key triple-DES cipher. Use this with the GenerateSecretKey... functions.

View Source
var CipherGeneric = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 64,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherGeneric describes the CKK_GENERIC_SECRET key type. Use this with the GenerateSecretKey... functions.

The spec promises that this mechanism can be used to perform HMAC operations, although implementations vary; CipherHMACSHA1 and so on may give better results.

View Source
var CipherHMACSHA1 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_SHA_1_HMAC,
			GenMech: CKM_NC_SHA_1_HMAC_KEY_GEN,
		},
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 64,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherHMACSHA1 describes the CKK_SHA_1_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
var CipherHMACSHA224 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_SHA224_HMAC,
			GenMech: CKM_NC_SHA224_HMAC_KEY_GEN,
		},
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 64,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherHMACSHA224 describes the CKK_SHA224_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
var CipherHMACSHA256 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_SHA256_HMAC,
			GenMech: CKM_NC_SHA256_HMAC_KEY_GEN,
		},
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 64,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherHMACSHA256 describes the CKK_SHA256_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
var CipherHMACSHA384 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_SHA384_HMAC,
			GenMech: CKM_NC_SHA384_HMAC_KEY_GEN,
		},
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 64,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherHMACSHA384 describes the CKK_SHA384_HMAC key type. Use this with the GenerateSecretKey... functions.

View Source
var CipherHMACSHA512 = &SymmetricCipher{
	GenParams: []SymmetricGenParams{
		{
			KeyType: pkcs11.CKK_SHA512_HMAC,
			GenMech: CKM_NC_SHA512_HMAC_KEY_GEN,
		},
		{
			KeyType: pkcs11.CKK_GENERIC_SECRET,
			GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
		},
	},
	BlockSize: 128,
	Encrypt:   false,
	MAC:       true,
	ECBMech:   0,
	CBCMech:   0,
	GCMMech:   0,
}

CipherHMACSHA512 describes the CKK_SHA512_HMAC key type. Use this with the GenerateSecretKey... functions.

Ciphers is a map of PKCS#11 key types (CKK_...) to symmetric cipher information.

Functions

func MLKEMDeriveKey

func MLKEMDeriveKey(paramSet MLKEMParameterSet, sharedSecret []byte) ([]byte, error)

MLKEMDeriveKey derives an AES key from an ML-KEM shared secret (as returned by MLKEMSharedSecret.Bytes, following Encapsulate or Decapsulate) using KMAC, per NIST SP 800-185. paramSet must match the parameter set the shared secret was produced under; it selects both the output key size and the KMAC variant (KMAC128 for ML-KEM-512, KMAC256 for ML-KEM-768/1024) and binds the derivation to that parameter set so that encapsulation/decapsulation under a different parameter set can never collide.

Parameters per NIST SP 800-185:

  • K (key): sharedSecret
  • X (data): be32(len(alg)) || alg || be32(outputLen*8) — AlgorithmID || SuppPubInfo
  • L (outputLen): key size in bytes (16 or 32), from mlkemCekSize
  • S (customization): empty string

Types

type Attribute

type Attribute = pkcs11.Attribute

Attribute represents a PKCS#11 CK_ATTRIBUTE type.

func CopyAttribute

func CopyAttribute(a *Attribute) *Attribute

CopyAttribute returns a deep copy of the given Attribute.

func NewAttribute

func NewAttribute(attributeType AttributeType, value interface{}) (a *Attribute, err error)

NewAttribute is a helper function that populates a new Attribute for common data types. This function will return an error if value is not of type bool, int, uint, string, []byte or time.Time (or is nil).

type AttributeSet

type AttributeSet map[AttributeType]*Attribute

An AttributeSet groups together operations that are common for a collection of Attributes.

func NewAttributeSet

func NewAttributeSet() AttributeSet

NewAttributeSet creates an empty AttributeSet.

func NewAttributeSetWithID

func NewAttributeSetWithID(id []byte) (AttributeSet, error)

NewAttributeSetWithID is a helper function that populates a new slice of Attributes with the provided ID. This function returns an error if the ID is an empty slice.

func NewAttributeSetWithIDAndLabel

func NewAttributeSetWithIDAndLabel(id, label []byte) (a AttributeSet, err error)

NewAttributeSetWithIDAndLabel is a helper function that populates a new slice of Attributes with the provided ID and Label. This function returns an error if either the ID or the Label is an empty slice.

func (AttributeSet) AddIfNotPresent

func (a AttributeSet) AddIfNotPresent(additional []*Attribute)

AddIfNotPresent adds the attributes if the Attribute Type is not already present in the AttributeSet.

func (AttributeSet) Copy

func (a AttributeSet) Copy() AttributeSet

Copy returns a deep copy of the AttributeSet. This function will return an error if value is not of type bool, int, uint, string, []byte or time.Time (or is nil).

func (AttributeSet) Set

func (a AttributeSet) Set(attributeType AttributeType, value interface{}) error

Set stores a new attribute in the AttributeSet. Any existing value will be overwritten. This function will return an error if value is not of type bool, int, uint, string, []byte or time.Time (or is nil).

func (AttributeSet) String

func (a AttributeSet) String() string

func (AttributeSet) ToSlice

func (a AttributeSet) ToSlice() []*Attribute

ToSlice returns a deep copy of Attributes contained in the AttributeSet.

func (AttributeSet) Unset

func (a AttributeSet) Unset(attributeType AttributeType)

Unset removes an attribute from the attributes set. If the set does not contain the attribute, this is a no-op.

type AttributeType

type AttributeType = uint

AttributeType represents a PKCS#11 CK_ATTRIBUTE value.

type BlockModeCloser

type BlockModeCloser interface {
	cipher.BlockMode

	// Close() releases resources associated with the block mode.
	Close()
}

BlockModeCloser represents a block cipher running in a block-based mode (e.g. CBC).

BlockModeCloser embeds cipher.BlockMode, and can be used as such. However, in this case (or if the Close() method is not explicitly called for any other reason), resources allocated to it may remain live indefinitely.

type Config

type Config struct {
	// Full path to PKCS#11 library.
	Path string

	// Token serial number.
	TokenSerial string

	// Token label.
	TokenLabel string

	// SlotNumber identifies a token to use by the slot containing it.
	SlotNumber *int

	// User PIN (password).
	Pin string

	// Maximum number of concurrent sessions to open. If zero, DefaultMaxSessions is used.
	// Otherwise, the value specified must be at least 2.
	MaxSessions int

	// User type identifies the user type logging in. If zero, DefaultUserType is used.
	UserType int

	// Maximum time to wait for a session from the sessions pool. Zero means wait indefinitely.
	PoolWaitTimeout time.Duration

	// LoginNotSupported should be set to true for tokens that do not support logging in.
	LoginNotSupported bool

	// UseGCMIVFromHSM should be set to true for tokens such as CloudHSM, which ignore the supplied IV for
	// GCM mode and generate their own. In this case, the token will write the IV used into the CK_GCM_PARAMS.
	// If UseGCMIVFromHSM is true, we will copy this IV and overwrite the 'nonce' slice passed to Seal and Open. It
	// is therefore necessary that the nonce is the correct length (12 bytes for CloudHSM).
	UseGCMIVFromHSM bool

	// GCMIVLength is the length of IVs to use in GCM mode. Refer to NIST SP800-38 for guidance on the length of
	// RBG-based IVs in GCM mode. When the UseGCMIVFromHSM parameter is true
	GCMIVLength int

	GCMIVFromHSMControl GCMIVFromHSMConfig
}

Config holds PKCS#11 configuration information.

A token may be selected by label, serial number or slot number. It is an error to specify more than one way to select the token.

Supply this to Configure(), or alternatively use ConfigureFromFile().

type Context

type Context struct {
	// contains filtered or unexported fields
}

A Context stores the connection state to a PKCS#11 token. Use Configure or ConfigureFromFile to create a new Context. Call Close when finished with the token, to free up resources.

All functions, except Close, are safe to call from multiple goroutines.

func Configure

func Configure(config *Config) (*Context, error)

Configure creates a new Context based on the supplied PKCS#11 configuration.

func ConfigureFromFile

func ConfigureFromFile(configLocation string) (*Context, error)

ConfigureFromFile is a convenience method, which parses the configuration file and calls Configure. The configuration file should be a JSON representation of a Config object.

func (*Context) Close

func (c *Context) Close() error

Close releases resources used by the Context and unloads the PKCS #11 library if there are no other Contexts using it. Close blocks until existing operations have finished. A closed Context cannot be reused. Close is idempotent: calling it more than once is safe and returns nil on subsequent calls.

func (*Context) DeleteCertificate

func (c *Context) DeleteCertificate(id []byte, label []byte, serial *big.Int) error

DeleteCertificate destroys a previously imported certificate. it will return nil if succeeds or if the certificate does not exist. Any combination of id, label and serial can be provided. An error is return if all are nil.

func (*Context) FindAllCertificates

func (c *Context) FindAllCertificates() (certificates []*x509.Certificate, err error)

FindAllCertificates retrieves every X.509 certificate on the token, or a nil slice if there are none. It is the unfiltered counterpart of FindCertificate, for callers that know nothing about what the token holds.

Only objects whose CKA_CERTIFICATE_TYPE is CKC_X_509 are returned; certificate objects of another type (WTLS or attribute certificates) are not X.509 certificates and are left to the token rather than reported as an error. An object that claims to be X.509 but whose CKA_VALUE does not parse is reported, since that is corruption rather than a kind of certificate this package cannot represent.

Certificates are not matched against private keys. Use FindAllPairedCertificates for the certificates this token can also sign with.

The certificates are returned as stored. Being on the token is not a statement of trust — anyone able to write to it can add a certificate — so a caller building a trust store or verifying a chain must still validate them.

func (*Context) FindAllKeyPairs

func (c *Context) FindAllKeyPairs() ([]Signer, error)

FindAllKeyPairs retrieves all existing asymmetric key pairs, or a nil slice if none can be found.

If a private key is found, but the corresponding public key is not, the key is not returned because we cannot implement crypto.Signer without the public key. Keys whose type this package cannot represent as a Signer (ML-KEM key pairs, for example) are skipped.

The returned Signers can only sign. For every key pair on the token that can also decrypt, use FindAllRSAKeyPairs, which returns SignerDecrypters.

func (*Context) FindAllKeys

func (c *Context) FindAllKeys() ([]*SecretKey, error)

FindAllKeys retrieves all existing symmetric keys, or a nil slice if none can be found.

func (*Context) FindAllPairedCertificates

func (c *Context) FindAllPairedCertificates() (certificates []tls.Certificate, err error)

FindAllPairedCertificates finds all certificates on the token that have a matching private key.

func (*Context) FindAllRSAKeyPairs

func (c *Context) FindAllRSAKeyPairs() ([]SignerDecrypter, error)

FindAllRSAKeyPairs retrieves all existing RSA asymmetric key pairs, or a nil slice if none can be found. It is the decryption-capable counterpart of FindAllKeyPairs: every returned key is a SignerDecrypter, so this is the one-call form of "give me everything on this token I can decrypt with".

Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer or SignerDecrypter without the public key. Private keys that are not RSA are skipped.

func (*Context) FindCertificate

func (c *Context) FindCertificate(id []byte, label []byte, serial *big.Int) (*x509.Certificate, error)

FindCertificate retrieves a previously imported certificate. Any combination of id, label and serial can be provided. An error is return if all are nil.

func (*Context) FindKey

func (c *Context) FindKey(id []byte, label []byte) (*SecretKey, error)

FindKey retrieves a previously created symmetric key, or nil if it cannot be found.

Either (but not both) of id and label may be nil, in which case they are ignored.

func (*Context) FindKeyPair

func (c *Context) FindKeyPair(id []byte, label []byte) (Signer, error)

FindKeyPair retrieves a previously created asymmetric key pair, or nil if it cannot be found.

At least one of id and label must be specified. Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer without the public key.

The returned Signer can only sign. To decrypt with an existing key pair, use FindRSAKeyPair, which returns a SignerDecrypter.

func (*Context) FindKeyPairWithAttributes

func (c *Context) FindKeyPairWithAttributes(attributes AttributeSet) (Signer, error)

FindKeyPairWithAttributes retrieves a previously created asymmetric key pair, or nil if it cannot be found. The given attributes are matched against the private half only. Then the public half with a matching CKA_ID and CKA_LABEL values is found.

Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer without the public key.

func (*Context) FindKeyPairs

func (c *Context) FindKeyPairs(id []byte, label []byte) (signer []Signer, err error)

FindKeyPairs retrieves all matching asymmetric key pairs, or a nil slice if none can be found.

At least one of id and label must be specified. Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer without the public key.

The returned Signers can only sign. To decrypt with existing key pairs, use FindRSAKeyPairs, which returns SignerDecrypters.

func (*Context) FindKeyPairsWithAttributes

func (c *Context) FindKeyPairsWithAttributes(attributes AttributeSet) (signer []Signer, err error)

FindKeyPairsWithAttributes retrieves previously created asymmetric key pairs, or nil if none can be found. The given attributes are matched against the private half only. Then the public half with a matching CKA_ID and CKA_LABEL values is found.

Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer without the public key. Keys whose type this package cannot represent as a Signer (ML-KEM key pairs, for example) are skipped.

The returned Signers can only sign. To decrypt with existing key pairs, use FindRSAKeyPairsWithAttributes, which returns SignerDecrypters.

func (*Context) FindKeyWithAttributes

func (c *Context) FindKeyWithAttributes(attributes AttributeSet) (*SecretKey, error)

FindKeyWithAttributes retrieves a previously created symmetric key, or nil if it cannot be found.

func (*Context) FindKeys

func (c *Context) FindKeys(id []byte, label []byte) (key []*SecretKey, err error)

FindKeys retrieves all matching symmetric keys, or a nil slice if none can be found.

At least one of id and label must be specified.

func (*Context) FindKeysWithAttributes

func (c *Context) FindKeysWithAttributes(attributes AttributeSet) ([]*SecretKey, error)

FindKeysWithAttributes retrieves previously created symmetric keys, or a nil slice if none can be found. Keys of a type this package has no Cipher for are skipped.

func (*Context) FindMLKEMKeyPair

func (c *Context) FindMLKEMKeyPair(id, label []byte) (MLKEMKeyPair, error)

FindMLKEMKeyPair retrieves a previously created ML-KEM key pair, or an error if it cannot be found. At least one of id or label must be specified.

func (*Context) FindMLKEMKeyPairs

func (c *Context) FindMLKEMKeyPairs(id, label []byte) ([]MLKEMKeyPair, error)

FindMLKEMKeyPairs retrieves all matching ML-KEM key pairs, or a nil slice if none can be found. At least one of id or label must be specified.

func (*Context) FindMLKEMKeyPairsWithAttributes

func (c *Context) FindMLKEMKeyPairsWithAttributes(attributes AttributeSet) ([]MLKEMKeyPair, error)

FindMLKEMKeyPairsWithAttributes retrieves ML-KEM key pairs matching the given attributes. Attributes are matched against the private half; the public half is located by CKA_ID / CKA_LABEL. The attribute set must not contain CkaClass.

func (*Context) FindPrivateKey

func (c *Context) FindPrivateKey(id []byte, label []byte) (PrivateKey, error)

FindPrivateKey retrieves a previously created asymmetric private key, or nil if it cannot be found.

At least one of id and label must be specified.

func (*Context) FindPrivateKeyWithAttributes

func (c *Context) FindPrivateKeyWithAttributes(attributes AttributeSet) (PrivateKey, error)

FindPrivateKeyWithAttributes retrieves a previously created asymmetric private keys, or nil if it cannot be found. The given attributes are matched against the private half only.

func (*Context) FindPrivateKeys

func (c *Context) FindPrivateKeys(id []byte, label []byte) (signer []PrivateKey, err error)

FindPrivateKeys retrieves all matching asymmetric private keys, or a nil slice if none can be found.

At least one of id and label must be specified.

func (*Context) FindPrivateKeysWithAttributes

func (c *Context) FindPrivateKeysWithAttributes(attributes AttributeSet) (signer []PrivateKey, err error)

FindPrivateKeysWithAttributes retrieves previously created asymmetric private keys, or nil if none can be found. The given attributes are matched against the private half only. Keys whose type this package cannot represent as a PrivateKey (ML-KEM keys, for example) are skipped.

func (*Context) FindRSAKeyPair

func (c *Context) FindRSAKeyPair(id []byte, label []byte) (SignerDecrypter, error)

FindRSAKeyPair retrieves a previously created asymmetric RSA key pair, or nil if it cannot be found. At least one of id or label must be specified. This method is specific to rsa only because it is the only supported type able to decrypt and sign.

func (*Context) FindRSAKeyPairs

func (c *Context) FindRSAKeyPairs(id []byte, label []byte) (signer []SignerDecrypter, err error)

FindRSAKeyPairs retrieves all matching asymmetric RSA key pairs, or a nil slice if none can be found. At least one of id and label must be specified. Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer or SignerDecrypter without the public key.

func (*Context) FindRSAKeyPairsWithAttributes

func (c *Context) FindRSAKeyPairsWithAttributes(attributes AttributeSet) (signer []SignerDecrypter, err error)

FindRSAKeyPairsWithAttributes retrieves previously created RSA asymmetric key pairs, or nil if none can be found. The given attributes are matched against the private half only. Then the public half with a matching CKA_ID and CKA_LABEL values is found. Only private keys that have a non-empty CKA_ID will be found, as this is required to locate the matching public key. If the private key is found, but the public key with a corresponding CKA_ID is not, the key is not returned because we cannot implement crypto.Signer or SignerDecrypter without the public key. Private keys that are not RSA are skipped.

func (*Context) FindRSAPrivateKey

func (c *Context) FindRSAPrivateKey(id []byte, label []byte) (RSAPrivateKey, error)

FindRSAPrivateKey retrieves a previously created asymmetric RSA private key, or nil if it cannot be found. At least one of id or label must be specified. This method is specific to rsa only because it is the only supported type able to decrypt and sign.

func (*Context) FindRSAPrivateKeys

func (c *Context) FindRSAPrivateKeys(id []byte, label []byte) (pks []RSAPrivateKey, err error)

FindRSAPrivateKeys retrieves all matching asymmetric RSA private keys, or a nil slice if none can be found. At least one of id or label must be specified. This method is specific to rsa only because it is the only supported type able to decrypt and sign.

func (*Context) FindRSAPrivateKeysWithAttributes

func (c *Context) FindRSAPrivateKeysWithAttributes(attributes AttributeSet) (pks []RSAPrivateKey, err error)

FindRSAPrivateKeysWithAttributes retrieves previously created asymmetric RSA private keys, or nil if none can be found. The given attributes are matched against the private half only. Private keys that are not RSA are skipped. This method is specific to rsa only because it is the only supported type able to decrypt and sign.

func (*Context) GenerateDSAKeyPair

func (c *Context) GenerateDSAKeyPair(id []byte, params *dsa.Parameters) (Signer, error)

GenerateDSAKeyPair creates a DSA key pair on the token. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) GenerateDSAKeyPairWithAttributes

func (c *Context) GenerateDSAKeyPairWithAttributes(public, private AttributeSet, params *dsa.Parameters) (Signer, error)

GenerateDSAKeyPairWithAttributes creates a DSA key pair on the token. After this function returns, public and private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to a default value.

func (*Context) GenerateDSAKeyPairWithLabel

func (c *Context) GenerateDSAKeyPairWithLabel(id, label []byte, params *dsa.Parameters) (Signer, error)

GenerateDSAKeyPairWithLabel creates a DSA key pair on the token. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil.

func (*Context) GenerateECDSAKeyPair

func (c *Context) GenerateECDSAKeyPair(id []byte, curve elliptic.Curve) (Signer, error)

GenerateECDSAKeyPair creates a ECDSA key pair on the token using curve c. The id parameter is used to set CKA_ID and must be non-nil. Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*Context) GenerateECDSAKeyPairWithAttributes

func (c *Context) GenerateECDSAKeyPairWithAttributes(public, private AttributeSet, curve elliptic.Curve) (Signer, error)

GenerateECDSAKeyPairWithAttributes generates an ECDSA key pair on the token. After this function returns, public and private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to a default value.

func (*Context) GenerateECDSAKeyPairWithLabel

func (c *Context) GenerateECDSAKeyPairWithLabel(id, label []byte, curve elliptic.Curve) (Signer, error)

GenerateECDSAKeyPairWithLabel creates a ECDSA key pair on the token using curve c. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil. Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*Context) GenerateMLKEMKeyPair

func (c *Context) GenerateMLKEMKeyPair(id []byte, paramSet MLKEMParameterSet) (MLKEMKeyPair, error)

GenerateMLKEMKeyPair creates an ML-KEM key pair on the token. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) GenerateMLKEMKeyPairWithAttributes

func (c *Context) GenerateMLKEMKeyPairWithAttributes(public, private AttributeSet, paramSet MLKEMParameterSet) (MLKEMKeyPair, error)

GenerateMLKEMKeyPairWithAttributes generates an ML-KEM key pair on the token. After this function returns, public and private will contain the attributes applied to the key pair. If required attributes are missing they will be set to a default value.

func (*Context) GenerateMLKEMKeyPairWithLabel

func (c *Context) GenerateMLKEMKeyPairWithLabel(id, label []byte, paramSet MLKEMParameterSet) (MLKEMKeyPair, error)

GenerateMLKEMKeyPairWithLabel creates an ML-KEM key pair on the token. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil.

func (*Context) GenerateRSAKeyPair

func (c *Context) GenerateRSAKeyPair(id []byte, bits int) (SignerDecrypter, error)

GenerateRSAKeyPair creates an RSA key pair on the token. The id parameter is used to set CKA_ID and must be non-nil. RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func (*Context) GenerateRSAKeyPairWithAttributes

func (c *Context) GenerateRSAKeyPairWithAttributes(public, private AttributeSet, bits int) (SignerDecrypter, error)

GenerateRSAKeyPairWithAttributes generates an RSA key pair on the token. After this function returns, public and private will contain the attributes applied to the key pair. If required attributes are missing, they will be set to a default value.

func (*Context) GenerateRSAKeyPairWithLabel

func (c *Context) GenerateRSAKeyPairWithLabel(id, label []byte, bits int) (SignerDecrypter, error)

GenerateRSAKeyPairWithLabel creates an RSA key pair on the token. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil. RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func (*Context) GenerateSecretKey

func (c *Context) GenerateSecretKey(id []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error)

GenerateSecretKey creates an secret key of given length and type. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) GenerateSecretKeyWithAttributes

func (c *Context) GenerateSecretKeyWithAttributes(template AttributeSet, bits int, cipher *SymmetricCipher) (k *SecretKey, err error)

GenerateSecretKeyWithAttributes creates an secret key of given length and type. After this function returns, template will contain the attributes applied to the key. If required attributes are missing, they will be set to a default value.

func (*Context) GenerateSecretKeyWithLabel

func (c *Context) GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error)

GenerateSecretKeyWithLabel creates an secret key of given length and type. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil.

func (*Context) GetAttribute

func (c *Context) GetAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error)

GetAttribute gets the value of the specified attribute on the given key or keypair. If the key is asymmetric, then the attribute is retrieved from the private half.

If the object is not a crypto11 key or keypair then an error is returned.

func (*Context) GetAttributes

func (c *Context) GetAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error)

GetAttributes gets the values of the specified attributes on the given key or keypair. If the key is asymmetric, then the attributes are retrieved from the private half.

If the object is not a crypto11 key or keypair then an error is returned.

func (*Context) GetPubAttribute

func (c *Context) GetPubAttribute(key interface{}, attribute AttributeType) (a *Attribute, err error)

GetPubAttribute gets the value of the specified attribute on the public half of the given key.

If the object is not a crypto11 keypair then an error is returned.

func (*Context) GetPubAttributes

func (c *Context) GetPubAttributes(key interface{}, attributes []AttributeType) (a AttributeSet, err error)

GetPubAttributes gets the values of the specified attributes on the public half of the given keypair.

If the object is not a crypto11 keypair then an error is returned.

func (*Context) ImportCertificate

func (c *Context) ImportCertificate(id []byte, certificate *x509.Certificate) error

ImportCertificate imports a certificate onto the token. The id parameter is used to set CKA_ID and must be non-nil.

func (*Context) ImportCertificateWithAttributes

func (c *Context) ImportCertificateWithAttributes(template AttributeSet, certificate *x509.Certificate) error

ImportCertificateWithAttributes imports a certificate onto the token. After this function returns, template will contain the attributes applied to the certificate. If required attributes are missing, they will be set to a default value.

func (*Context) ImportCertificateWithLabel

func (c *Context) ImportCertificateWithLabel(id []byte, label []byte, certificate *x509.Certificate) error

ImportCertificateWithLabel imports a certificate onto the token. The id and label parameters are used to set CKA_ID and CKA_LABEL respectively and must be non-nil.

func (*Context) NewRandomReader

func (c *Context) NewRandomReader() (io.Reader, error)

NewRandomReader returns a reader for the random number generator on the token.

func (*Context) PoolStats

func (c *Context) PoolStats() PoolStats

PoolStats returns a snapshot of the state of the session pool, for metrics and diagnostics.

It only reads counters the pool maintains in memory: no PKCS#11 call is made and no session is taken, so it is cheap and safe to call from a metrics scrape, concurrently with any other operation, and on a closed Context (where it reports the pool as it was torn down, with Capacity zero).

type GCMIVFromHSMConfig

type GCMIVFromHSMConfig struct {

	// SupplyIvForHSMGCM_encrypt controls the supply of a non-nil IV for GCM use during C_EncryptInit
	SupplyIvForHSMGCMEncrypt bool

	// SupplyIvForHSMGCM_decrypt controls the supply of a non-nil IV for GCM use during C_DecryptInit
	SupplyIvForHSMGCMDecrypt bool
}

GCMIVFromHSMConfig controls IV buffer management for tokens that generate their own GCM IVs.

type MLKEMDecapsulator

type MLKEMDecapsulator interface {
	// Decapsulate recovers the shared secret from a ciphertext produced by the matching
	// encapsulator, deriving a new key object on the token using sharedSecretAttrs as the template.
	Decapsulate(ciphertext []byte, sharedSecretAttrs AttributeSet) (*MLKEMSharedSecret, error)

	// ParameterSet returns the ML-KEM security level (MLKEM512, MLKEM768, or MLKEM1024).
	ParameterSet() MLKEMParameterSet

	// Delete removes the private key object from the token.
	Delete() error
}

MLKEMDecapsulator is an ML-KEM private key capable of recovering a shared secret from a ciphertext.

type MLKEMEncapsulator

type MLKEMEncapsulator interface {
	// Encapsulate generates a fresh shared secret, encapsulates it with the public key, and
	// derives a new key object on the token using sharedSecretAttrs as the template.
	// The returned ciphertext must be transmitted to the holder of the matching private key.
	Encapsulate(sharedSecretAttrs AttributeSet) (ciphertext []byte, sharedSecret *MLKEMSharedSecret, err error)

	// ParameterSet returns the ML-KEM security level (MLKEM512, MLKEM768, or MLKEM1024).
	ParameterSet() MLKEMParameterSet

	// Delete removes the public key object from the token.
	Delete() error
}

MLKEMEncapsulator is an ML-KEM public key capable of encapsulating a shared secret.

type MLKEMKeyPair

type MLKEMKeyPair interface {
	MLKEMEncapsulator
	MLKEMDecapsulator
}

MLKEMKeyPair is a full ML-KEM key pair supporting both encapsulation and decapsulation.

type MLKEMParameterSet

type MLKEMParameterSet = uint

MLKEMParameterSet identifies an ML-KEM security level as defined in FIPS 203.

ML-KEM parameter set constants (PKCS#11 v3.2 CKP_ML_KEM_*).

type MLKEMSharedSecret

type MLKEMSharedSecret struct {
	// contains filtered or unexported fields
}

MLKEMSharedSecret wraps a PKCS#11 object handle for a KEM-derived shared secret key. The object is created on the token by Encapsulate or Decapsulate.

func (*MLKEMSharedSecret) Bytes

func (s *MLKEMSharedSecret) Bytes() ([]byte, error)

Bytes extracts the raw shared secret value from the token. The key must have been created with CKA_EXTRACTABLE = true in the shared secret template.

Security note: extracting the shared secret pulls sensitive key material out of the HSM into ordinary (garbage-collected, swappable) process memory, which defeats the protection the HSM provides. Prefer keeping the derived key on the token and using its handle for subsequent operations. If you must extract, wipe the returned slice (pkcs11.Wipe) as soon as you are done with it.

func (*MLKEMSharedSecret) Delete

func (o *MLKEMSharedSecret) Delete() error

type PaddingMode

type PaddingMode int

A PaddingMode is used by a block cipher (see NewCBC).

const (
	// PaddingNone represents a block cipher with no padding.
	PaddingNone PaddingMode = iota

	// PaddingPKCS represents a block cipher used with PKCS#7 padding.
	PaddingPKCS
)

type PoolStats

type PoolStats struct {
	// Capacity is the number of sessions the pool may hand out. crypto11 keeps
	// one session of its own to hold the login state, so this is one less than
	// the effective MaxSessions. Closing the Context sets it to zero.
	Capacity int64

	// Available is the number of sessions that could be taken from the pool
	// without waiting. A session that has not been opened yet still counts as
	// available: the pool opens it on first use.
	Available int64

	// Active is the number of sessions actually open on the token, whether idle
	// in the pool or currently claimed. It grows towards Capacity as load
	// requires, and never shrinks unless sessions are closed.
	Active int64

	// InUse is the number of sessions claimed by in-flight operations.
	InUse int64

	// MaxCapacity is the ceiling Capacity could be raised to. crypto11 creates
	// the pool at full size, so this is the initial Capacity and, unlike
	// Capacity, it is unaffected by Close.
	MaxCapacity int64

	// WaitCount is the cumulative number of operations that had to wait for a
	// session because none was available, and WaitTime the total time they
	// spent waiting. Both only ever grow. A rising WaitCount means MaxSessions
	// is below what the workload needs (or that Config.PoolWaitTimeout is about
	// to start biting).
	WaitCount int64
	WaitTime  time.Duration

	// IdleTimeout is how long an idle session is kept before being closed and
	// replaced, and IdleClosed the number of sessions closed that way. crypto11
	// does not currently enable idle timeouts, so both are always zero; they
	// are reported for completeness.
	IdleTimeout time.Duration
	IdleClosed  int64
}

PoolStats is a snapshot of a Context's session pool counters, as returned by Context.PoolStats. It is a plain value with no reference to the pool itself, so it is safe to keep, copy and marshal (durations marshal to JSON as nanoseconds).

The fields are read one at a time from the pool's atomic counters rather than under a lock, so a snapshot taken while other goroutines are using the token is individually accurate but not necessarily internally consistent: Available and InUse need not add up to Capacity.

type PrivateKey

type PrivateKey interface {
	Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

	KeyType() uint
}

PrivateKey is a dedicated interface for signing operations using a private key only, without the need of specifying a public Key. Despite being very similar to Signer, PrivateKey does not include the method to return the public key from the private key. One usecase implemented by PrivateKey is a pkcs11 store protecting a private key without its public pair.

type RSAPrivateKey

type RSAPrivateKey interface {
	Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

	Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)

	KeyType() uint
}

RSAPrivateKey is a dedicated interface for signing operations or decryption operations using an RSA private key only, without the need of specifying a public Key. Despite being very similar to SignerDecrypter, RSAPrivateKey does not include the method to return the public key from the private key. One usecase implemented by RSAPrivateKey is a pkcs11 store protecting a private key without its public pair.

type SecretKey

type SecretKey struct {

	// Symmetric cipher information
	Cipher *SymmetricCipher
	// contains filtered or unexported fields
}

SecretKey contains a reference to a loaded PKCS#11 symmetric key object.

A *SecretKey implements the cipher.Block interface, allowing it be used as the argument to cipher.NewCBCEncrypter and similar methods. For bulk operation this is very inefficient; using NewCBCEncrypterCloser, NewCBCEncrypter or NewCBC from this package is much faster.

func (*SecretKey) Delete

func (key *SecretKey) Delete() error

Delete deletes the secret key from the token.

func (*SecretKey) NewCBCDecrypter

func (key *SecretKey) NewCBCDecrypter(iv []byte) (cipher.BlockMode, error)

NewCBCDecrypter returns a cipher.BlockMode which decrypts in cipher block chaining mode, using the given key. The length of iv must be the same as the key's block size and must match the iv used to encrypt the data.

The new BlockMode acquires persistent resources which are released (eventually) by a finalizer. If this is a problem for your application then use NewCBCDecrypterCloser instead.

If that is not possible then adding calls to runtime.GC() may help.

func (*SecretKey) NewCBCDecrypterCloser

func (key *SecretKey) NewCBCDecrypterCloser(iv []byte) (BlockModeCloser, error)

NewCBCDecrypterCloser returns a BlockModeCloser which decrypts in cipher block chaining mode, using the given key. The length of iv must be the same as the key's block size and must match the iv used to encrypt the data.

Use of NewCBCDecrypterCloser rather than NewCBCEncrypter represents a commitment to call the Close() method of the returned BlockModeCloser.

func (*SecretKey) NewCBCEncrypter

func (key *SecretKey) NewCBCEncrypter(iv []byte) (cipher.BlockMode, error)

NewCBCEncrypter returns a cipher.BlockMode which encrypts in cipher block chaining mode, using the given key. The length of iv must be the same as the key's block size.

The new BlockMode acquires persistent resources which are released (eventually) by a finalizer. If this is a problem for your application then use NewCBCEncrypterCloser instead.

If that is not possible then adding calls to runtime.GC() may help.

func (*SecretKey) NewCBCEncrypterCloser

func (key *SecretKey) NewCBCEncrypterCloser(iv []byte) (BlockModeCloser, error)

NewCBCEncrypterCloser returns a BlockModeCloser which encrypts in cipher block chaining mode, using the given key. The length of iv must be the same as the key's block size.

Use of NewCBCEncrypterCloser rather than NewCBCEncrypter represents a commitment to call the Close() method of the returned BlockModeCloser.

func (*SecretKey) NewGCM

func (key *SecretKey) NewGCM() (cipher.AEAD, error)

NewGCM returns a given cipher wrapped in Galois Counter Mode, with the standard nonce length.

This depends on the HSM supporting the CKM_*_GCM mechanism. If it is not supported then you must use cipher.NewGCM; it will be slow.

func (*SecretKey) NewHMAC

func (key *SecretKey) NewHMAC(mech int, length int) (hash.Hash, error)

NewHMAC returns a new HMAC hash using the given PKCS#11 mechanism and key. length specifies the output size, for _GENERAL mechanisms.

If the mechanism is not in the built-in list of known mechanisms then the Size() function will return whatever length was, even if it is wrong. BlockSize() will always return 0 in this case.

The Reset() method is not implemented. After Sum() is called no new data may be added.

Failure handling: the returned hash.Hash cannot report errors through Sum, whose signature is fixed by the interface. If the underlying HSM operation fails (for example the session is lost mid-operation), Write returns an error and a subsequent Sum panics rather than returning a bogus MAC. Callers that must tolerate HSM faults should surface the Write error and/or wrap Sum in a recover().

type Signer

type Signer interface {
	crypto.Signer

	// Delete deletes the key pair from the token.
	Delete() error
}

Signer is a PKCS#11 key that implements crypto.Signer.

A Signer can only sign. To also decrypt with an existing key pair, use SignerDecrypter and the FindRSAKeyPair, FindRSAKeyPairs, FindRSAKeyPairsWithAttributes and FindAllRSAKeyPairs finders: RSA is the only supported key type that can both sign and decrypt.

type SignerDecrypter

type SignerDecrypter interface {
	Signer

	// Decrypt implements crypto.Decrypter.
	Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)
}

SignerDecrypter is a PKCS#11 key implements crypto.Signer and crypto.Decrypter.

Use the FindRSAKeyPair, FindRSAKeyPairs, FindRSAKeyPairsWithAttributes and FindAllRSAKeyPairs finders to obtain one; the generic FindKeyPair family returns a Signer, which cannot decrypt.

type SymmetricCipher

type SymmetricCipher struct {
	// Possible key generation parameters
	// (For HMAC this varies between PKCS#11 implementations.)
	GenParams []SymmetricGenParams

	// Block size in bytes
	BlockSize int

	// True if encryption supported
	Encrypt bool

	// True if MAC supported
	MAC bool

	// ECB mechanism (CKM_..._ECB)
	ECBMech uint

	// CBC mechanism (CKM_..._CBC)
	CBCMech uint

	// CBC mechanism with PKCS#7 padding (CKM_..._CBC)
	CBCPKCSMech uint

	// GCM mechanism (CKM_..._GCM)
	GCMMech uint
}

SymmetricCipher represents information about a symmetric cipher.

type SymmetricGenParams

type SymmetricGenParams struct {
	// Key type (CKK_...)
	KeyType uint

	// Key generation mechanism (CKM_..._KEY_GEN)
	GenMech uint
}

SymmetricGenParams holds a consistent (key type, mechanism) key generation pair.

Directories

Path Synopsis
internal
pool
Package pool provides functionality to manage and reuse resources like connections.
Package pool provides functionality to manage and reuse resources like connections.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL