crypto11

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2019 License: MIT Imports: 25 Imported by: 0

README

Crypto11

GoDoc Build Status

This is an implementation of the standard Golang hardware crypto interface that uses PKCS#11 as a backend. The supported features are:

  • Generation and retrieval of RSA, DSA and ECDSA keys.
  • PKCS#1 v1.5 signing.
  • PKCS#1 PSS signing.
  • PKCS#1 v1.5 decryption
  • PKCS#1 OAEP decryption
  • ECDSA signing.
  • DSA signing.
  • Random number generation.
  • (Experimental) AES and DES3 encryption and decryption.
  • (Experimental) HMAC support.

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

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

See the documentation for details of various limitations.

There are some rudimentary tests.

There is a demo web server in the demo directory, which publishes the contents of /usr/share/doc.

Installation

(If you don't have one already) create a standard Go workspace and set the GOPATH environment variable to point to the workspace root.

crypto11 manages it's dependencies via dep. To Install dep run:

go get -u github.com/golang/dep/cmd/dep

Clone, ensure deps, and build:

go get github.com/ThalesIgnite/crypto11
cd $GOPATH/src/github.com/ThalesIgnite/crypto11
dep ensure
go build

Edit config to taste, and then run the test program:

go test  -count=1

Testing Guidance

Testing with 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:

$ cat config
{
  "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:

$ cat config
{
  "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:

$ cat config
{
  "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 SoftHSM

While the aim of the exercise is to use an HSM, it can be convenient to test with a software-only provider.

To set up a slot:

$ cat softhsm.conf
0:softhsm0.db
$ export SOFTHSM_CONF=`pwd`/softhsm.conf
$ softhsm --init-token --slot 0 --label test
The SO PIN must have a length between 4 and 255 characters.
Enter SO PIN:
The user PIN must have a length between 4 and 255 characters.
Enter user PIN:
The token has been initialized.

Configure as follows:

$ cat config
{
  "Path" : "/usr/lib/softhsm/libsofthsm.so",
  "TokenLabel": "test",
  "Pin" : "password"
}

DSA, ECDSA, PSS and OAEP aren't supported, so expect test failures.

Testing with SoftHSM2

To set up a slot:

$ cat softhsm2.conf
directories.tokendir = /home/rjk/go/src/github.com/ThalesIgnite/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:

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

(At time of writing) OAEP is only partial and HMAC is unsupported, so expect test skips.

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.

Wishlist

  • Full test instructions for additional PKCS#11 implementations.
  • A pony.

MIT License.

Copyright 2016-2018 Thales e-Security, Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

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

Simple use

1. Either write a configuration file (see ConfigureFromFile) or define a configuration in your application (see PKCS11Config and Configure). This will identify the PKCS#11 library and token to use, and contain the password (or "PIN" in PKCS#11 terminology) to use if the token requires login.

2. Create keys with GenerateDSAKeyPair, GenerateRSAKeyPair and GenerateECDSAKeyPair. The keys you get back implement the standard Go crypto.Signer interface (and crypto.Decrypter, for RSA). They are automatically persisted under random a randomly generated label and ID (use the Identify method to discover them).

3. Retrieve existing keys with FindKeyPair. The return value is a Go crypto.PrivateKey; it may be converted either to crypto.Signer or to *PKCS11PrivateKeyDSA, *PKCS11PrivateKeyECDSA or *PKCS11PrivateKeyRSA.

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. PKCS11Object captures both the object handle and the slot ID for an object.

2. For each slot we maintain a pool of read-write sessions. The pool expands dynamically up to an (undocumented) limit.

3. Each operation transiently takes a session from the pool. They have exclusive use of the session, meeting PKCS#11's concurrency requirements.

The details are, partially, exposed in the API; since the target use case is PKCS#11-unaware operation it may be that the API as it stands isn't good enough for PKCS#11-aware applications. Feedback welcome.

See also https://golang.org/pkg/crypto/

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/thalesignite/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/ThalesIgnite/crypto11/issues/6 for further discussion.

Index

Constants

View Source
const (
	// PaddingNone represents a block cipher with no padding. (See NewCBC.)
	PaddingNone = iota

	// PaddingPKCS represents a block cipher used with PKCS#7 padding. (See NewCBC.)
	PaddingPKCS
)
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)
)
View Source
const (
	// DefaultMaxSessions controls the maximum number of concurrent sessions to
	// open, unless otherwise specified in the PKCS11Config object.
	DefaultMaxSessions = 1024
)

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.

View Source
var ErrCannotGetRandomData = errors.New("crypto11: cannot get random data from PKCS#11")

ErrCannotGetRandomData is returned when the PKCS#11 library fails to return enough random data

View Source
var ErrCannotOpenPKCS11 = errors.New("crypto11: could not open PKCS#11")

ErrCannotOpenPKCS11 is returned when the PKCS#11 library cannot be opened

View Source
var ErrHmacClosed = errors.New("already called Sum()")

ErrHmacClosed is called if an HMAC is updated after it has finished.

View Source
var ErrKeyNotFound = errors.New("crypto11: could not find PKCS#11 key")

ErrKeyNotFound represents the failure to find the requested PKCS#11 key

View Source
var ErrMalformedDER = errors.New("crypto11: malformed DER message")

ErrMalformedDER represents a failure to decode an ASN.1-encoded message

View Source
var ErrMalformedPoint = errors.New("crypto11/ecdsa: malformed elliptic curve point")

ErrMalformedPoint is returned when crypto.elliptic.Unmarshal cannot decode a point.

View Source
var ErrMalformedRSAKey = errors.New("crypto11/rsa: malformed RSA key")

ErrMalformedRSAKey is returned when an RSA key is not in a suitable form.

Currently this means that the public exponent is either bigger than 32 bits, or less than 2.

View Source
var ErrMalformedSignature = errors.New("crypto11xo: malformed signature")

ErrMalformedSignature represents a failure to decode a signature. This means the PKCS#11 library has returned an empty or odd-length byte string.

View Source
var ErrNotConfigured = errors.New("crypto11: PKCS#11 not yet configured")

ErrNotConfigured is returned when the PKCS#11 library is not configured

View Source
var ErrTokenNotFound = errors.New("crypto11: could not find PKCS#11 token")

ErrTokenNotFound represents the failure to find the requested PKCS#11 token

View Source
var ErrUnrecognizedRSAOptions = errors.New("crypto11/rsa: unrecognized RSA options type")

ErrUnrecognizedRSAOptions is returned when unrecognized options structures are pased to Sign or Decrypt.

View Source
var ErrUnsupportedEllipticCurve = errors.New("crypto11/ecdsa: unsupported elliptic curve")

ErrUnsupportedEllipticCurve is returned when an elliptic curve unsupported by crypto11 is specified. Note that the error behavior for an elliptic curve unsupported by the underlying PKCS#11 implementation will be different.

View Source
var ErrUnsupportedKeyType = errors.New("crypto11: unrecognized key type")

ErrUnsupportedKeyType is returned when the PKCS#11 library returns a key type that isn't supported

View Source
var ErrUnsupportedRSAOptions = errors.New("crypto11/rsa: unsupported RSA option value")

ErrUnsupportedRSAOptions is returned when an unsupported RSA option is requested.

Currently this means a nontrivial SessionKeyLen when decrypting; or an unsupported hash function; or crypto.rsa.PSSSaltLengthAuto was requested.

Functions

func Close

func Close() error

Close releases all sessions and uninitializes library default handle. Once library handle is released, library may be configured once again.

func Configure

func Configure(config *PKCS11Config) (*pkcs11.Ctx, error)

Configure configures PKCS#11 from a PKCS11Config.

The PKCS#11 library context is returned, allowing a PKCS#11-aware application to make use of it. Non-aware appliations may ignore it.

Unsually, these values may be present even if the error is non-nil. This corresponds to the case that the library has already been configured. Note that it is NOT reconfigured so if you supply a different configuration the second time, it will be ignored in favor of the first configuration.

If config is nil, and the library has already been configured, the context from the first configuration is returned (and the error will be nil in this case).

func ConfigureFromFile

func ConfigureFromFile(configLocation string) (ctx *pkcs11.Ctx, err error)

ConfigureFromFile configures PKCS#11 from a name configuration file.

Configuration files are a JSON representation of the PKCSConfig object. The return value is as for Configure().

Note that if CRYPTO11_CONFIG_PATH is set in the environment, configuration will be read from that file, overriding any later runtime configuration.

func FindKeyPair

func FindKeyPair(id []byte, label []byte) (crypto.PrivateKey, error)

FindKeyPair retrieves a previously created asymmetric key.

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

func FindKeyPairOnSession

func FindKeyPairOnSession(session *PKCS11Session, slot uint, id []byte, label []byte) (crypto.PrivateKey, error)

FindKeyPairOnSession retrieves a previously created asymmetric key, using a specified session.

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

func FindKeyPairOnSlot

func FindKeyPairOnSlot(slot uint, id []byte, label []byte) (crypto.PrivateKey, error)

FindKeyPairOnSlot retrieves a previously created asymmetric key, using a specified slot.

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

Types

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 PKCS11Config

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

	// Token serial number
	TokenSerial string

	// Token label
	TokenLabel string

	// User PIN (password)
	Pin string

	// Maximum number of concurrent sessions to open
	MaxSessions int

	// Session idle timeout to be evicted from the pool
	IdleTimeout time.Duration

	// Maximum time allowed to wait a sessions pool for a session
	PoolWaitTimeout time.Duration
}

PKCS11Config holds PKCS#11 configuration information.

A token may be identified either by serial number or label. If both are specified then the first match wins.

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

type PKCS11Object

type PKCS11Object struct {
	// The PKCS#11 object handle.
	Handle pkcs11.ObjectHandle

	// The PKCS#11 slot number.
	//
	// This is used internally to find a session handle that can
	// access this object.
	Slot uint
}

PKCS11Object contains a reference to a loaded PKCS#11 object.

func (*PKCS11Object) Identify

func (object *PKCS11Object) Identify() (id []byte, label []byte, err error)

Identify returns the ID and label for a PKCS#11 object.

Either of these values may be used to retrieve the key for later use.

type PKCS11PrivateKey

type PKCS11PrivateKey struct {
	PKCS11Object

	// The corresponding public key
	PubKey crypto.PublicKey
}

PKCS11PrivateKey contains a reference to a loaded PKCS#11 private key object.

func (PKCS11PrivateKey) Public

func (signer PKCS11PrivateKey) Public() crypto.PublicKey

Public returns the public half of a private key.

This partially implements the go.crypto.Signer and go.crypto.Decrypter interfaces for PKCS11PrivateKey. (The remains of the implementation is in the key-specific types.)

type PKCS11PrivateKeyDSA

type PKCS11PrivateKeyDSA struct {
	PKCS11PrivateKey
}

PKCS11PrivateKeyDSA contains a reference to a loaded PKCS#11 DSA private key object.

func GenerateDSAKeyPair

func GenerateDSAKeyPair(params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)

GenerateDSAKeyPair creates a DSA private key on the default slot

The key will have a random label and ID.

func GenerateDSAKeyPairOnSession

func GenerateDSAKeyPairOnSession(session *PKCS11Session, slot uint, id []byte, label []byte, params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)

GenerateDSAKeyPairOnSession creates a DSA private key using a specified session

Either or both label and/or id can be nil, in which case random values will be generated.

func GenerateDSAKeyPairOnSlot

func GenerateDSAKeyPairOnSlot(slot uint, id []byte, label []byte, params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)

GenerateDSAKeyPairOnSlot creates a DSA private key on a specified slot

Either or both label and/or id can be nil, in which case random values will be generated.

func (*PKCS11PrivateKeyDSA) Sign

func (signer *PKCS11PrivateKeyDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

Sign signs a message using a DSA key.

This completes the implemention of crypto.Signer for PKCS11PrivateKeyDSA.

PKCS#11 expects to pick its own random data for signatures, so the rand argument is ignored.

The return value is a DER-encoded byteblock.

type PKCS11PrivateKeyECDSA

type PKCS11PrivateKeyECDSA struct {
	PKCS11PrivateKey
}

PKCS11PrivateKeyECDSA contains a reference to a loaded PKCS#11 ECDSA private key object.

func GenerateECDSAKeyPair

func GenerateECDSAKeyPair(c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPair creates an ECDSA private key using curve c.

The key will have a random label and ID.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func GenerateECDSAKeyPairOnSession

func GenerateECDSAKeyPairOnSession(session *PKCS11Session, slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPairOnSession creates an ECDSA private key using curve c, using a specified session.

label and/or id can be nil, in which case random values will be generated.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func GenerateECDSAKeyPairOnSlot

func GenerateECDSAKeyPairOnSlot(slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPairOnSlot creates an ECDSA private key using curve c, on a specified slot.

label and/or id can be nil, in which case random values will be generated.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11PrivateKeyECDSA) Sign

func (signer *PKCS11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Sign signs a message using an ECDSA key.

This completes the implemention of crypto.Signer for PKCS11PrivateKeyECDSA.

PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored.

The return value is a DER-encoded byteblock.

type PKCS11PrivateKeyRSA

type PKCS11PrivateKeyRSA struct {
	PKCS11PrivateKey
}

PKCS11PrivateKeyRSA contains a reference to a loaded PKCS#11 RSA private key object.

func GenerateRSAKeyPair

func GenerateRSAKeyPair(bits int) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPair creates an RSA private key of given length.

The key will have a random label and ID.

RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func GenerateRSAKeyPairOnSession

func GenerateRSAKeyPairOnSession(session *PKCS11Session, slot uint, id []byte, label []byte, bits int) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPairOnSession creates an RSA private key of given length, on a specified session.

Either or both label and/or id can be nil, in which case random values will be generated.

RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func GenerateRSAKeyPairOnSlot

func GenerateRSAKeyPairOnSlot(slot uint, id []byte, label []byte, bits int) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPairOnSlot creates a RSA private key on a specified slot

Either or both label and/or id can be nil, in which case random values will be generated.

func (*PKCS11PrivateKeyRSA) Decrypt

func (priv *PKCS11PrivateKeyRSA) Decrypt(rand io.Reader, ciphertext []byte, options crypto.DecrypterOpts) (plaintext []byte, err error)

Decrypt decrypts a message using a RSA key.

This completes the implemention of crypto.Decrypter for PKCS11PrivateKeyRSA.

Note that the SessionKeyLen option (for PKCS#1v1.5 decryption) is not supported.

The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11PrivateKeyRSA) Sign

func (priv *PKCS11PrivateKeyRSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

Sign signs a message using a RSA key.

This completes the implemention of crypto.Signer for PKCS11PrivateKeyRSA.

PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored.

Note that (at present) the crypto.rsa.PSSSaltLengthAuto option is not supported. The caller must either use crypto.rsa.PSSSaltLengthEqualsHash (recommended) or pass an explicit salt length. Moreover the underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11PrivateKeyRSA) Validate

func (priv *PKCS11PrivateKeyRSA) Validate() error

Validate checks an RSA key.

Since the private key material is not normally available only very limited validation is possible. (The underlying PKCS#11 implementation may perform stricter checking.)

type PKCS11RandReader

type PKCS11RandReader struct {
}

PKCS11RandReader is a random number reader that uses PKCS#11.

func (PKCS11RandReader) Read

func (reader PKCS11RandReader) Read(data []byte) (n int, err error)

Read fills data with random bytes generated via PKCS#11 using the default slot.

This implements the Reader interface for PKCS11RandReader.

type PKCS11SecretKey

type PKCS11SecretKey struct {
	PKCS11Object

	// Symmetric cipher information
	Cipher *SymmetricCipher
}

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

A *PKCS11SecretKey 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 FindKey

func FindKey(id []byte, label []byte) (*PKCS11SecretKey, error)

FindKey retrieves a previously created symmetric key.

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

func FindKeyOnSession

func FindKeyOnSession(session *PKCS11Session, slot uint, id []byte, label []byte) (key *PKCS11SecretKey, err error)

FindKeyOnSession retrieves a previously created symmetric key, using a specified session.

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

func FindKeyOnSlot

func FindKeyOnSlot(slot uint, id []byte, label []byte) (*PKCS11SecretKey, error)

FindKeyOnSlot retrieves a previously created symmetric key, using a specified slot.

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

func GenerateSecretKey

func GenerateSecretKey(bits int, cipher *SymmetricCipher) (*PKCS11SecretKey, error)

GenerateSecretKey creates an secret key of given length and type.

The key will have a random label and ID.

func GenerateSecretKeyOnSession

func GenerateSecretKeyOnSession(session *PKCS11Session, slot uint, id []byte, label []byte, bits int, cipher *SymmetricCipher) (key *PKCS11SecretKey, err error)

GenerateSecretKeyOnSession creates a symmetric key of given type and length, on a specified session.

Either or both label and/or id can be nil, in which case random values will be generated.

func GenerateSecretKeyOnSlot

func GenerateSecretKeyOnSlot(slot uint, id []byte, label []byte, bits int, cipher *SymmetricCipher) (*PKCS11SecretKey, error)

GenerateSecretKeyOnSlot creates as symmetric key on a specified slot

Either or both label and/or id can be nil, in which case random values will be generated.

func (*PKCS11SecretKey) BlockSize

func (key *PKCS11SecretKey) BlockSize() int

BlockSize returns the cipher's block size in bytes.

func (*PKCS11SecretKey) Decrypt

func (key *PKCS11SecretKey) Decrypt(dst, src []byte)

Decrypt decrypts the first block in src into dst. Dst and src must overlap entirely or not at all.

Using this method for bulk operation is very inefficient, as it makes a round trip to the HSM (which may be network-connected) for each block. For more efficient operation, see NewCBCDecrypterCloser, NewCBCDecrypter or NewCBC.

func (*PKCS11SecretKey) Encrypt

func (key *PKCS11SecretKey) Encrypt(dst, src []byte)

Encrypt encrypts the first block in src into dst. Dst and src must overlap entirely or not at all.

Using this method for bulk operation is very inefficient, as it makes a round trip to the HSM (which may be network-connected) for each block. For more efficient operation, see NewCBCEncrypterCloser, NewCBCEncrypter or NewCBC.

func (*PKCS11SecretKey) NewCBC

func (key *PKCS11SecretKey) NewCBC(paddingMode int) (g cipher.AEAD, err error)

NewCBC returns a given cipher wrapped in CBC mode.

Despite the cipher.AEAD return type, there is no support for additional data and no authentication. This method exists to provide a convenient way to do bulk (possibly padded) CBC encryption. Think carefully before passing the cipher.AEAD to any consumer that expects authentication.

func (*PKCS11SecretKey) NewCBCDecrypter

func (key *PKCS11SecretKey) NewCBCDecrypter(iv []byte) (bm cipher.BlockMode, err 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 (*PKCS11SecretKey) NewCBCDecrypterCloser

func (key *PKCS11SecretKey) NewCBCDecrypterCloser(iv []byte) (bmc BlockModeCloser, err 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 (*PKCS11SecretKey) NewCBCEncrypter

func (key *PKCS11SecretKey) NewCBCEncrypter(iv []byte) (bm cipher.BlockMode, err 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 (*PKCS11SecretKey) NewCBCEncrypterCloser

func (key *PKCS11SecretKey) NewCBCEncrypterCloser(iv []byte) (bmc BlockModeCloser, err 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 (*PKCS11SecretKey) NewGCM

func (key *PKCS11SecretKey) NewGCM() (g cipher.AEAD, err 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 (*PKCS11SecretKey) NewHMAC

func (key *PKCS11SecretKey) NewHMAC(mech int, length int) (h hash.Hash, err 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.

type PKCS11Session

type PKCS11Session struct {
	Ctx    *pkcs11.Ctx
	Handle pkcs11.SessionHandle
}

PKCS11Session is a pair of PKCS#11 context and a reference to a loaded session handle.

func (*PKCS11Session) Close deprecated

func (session *PKCS11Session) Close()

Close closes the session.

Deprecated: Use CloseSession, which returns any underlying errors.

func (*PKCS11Session) CloseSession

func (session *PKCS11Session) CloseSession() error

CloseSession closes the session.

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
A demo program using a PKCS#11-protected key to authenticate a web server.
A demo program using a PKCS#11-protected key to authenticate a web server.

Jump to

Keyboard shortcuts

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