1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
Crypto11
========
[](https://godoc.org/github.com/ThalesIgnite/crypto11)
[](https://travis-ci.com/ThalesIgnite/crypto11)
This is an implementation of the standard Golang crypto interfaces that
uses [PKCS#11](http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/os/pkcs11-base-v2.40-errata01-os-complete.html) as a backend. The supported features are:
* Generation and retrieval of RSA, DSA and ECDSA keys.
* Importing and retrieval of x509 certificates
* 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.
* AES and DES3 encryption and decryption.
* HMAC support.
Signing is done through the
[crypto.Signer](https://golang.org/pkg/crypto/#Signer) interface and
decryption through
[crypto.Decrypter](https://golang.org/pkg/crypto/#Decrypter).
To verify signatures or encrypt messages, retrieve the public key and do it in software.
See [the documentation](https://godoc.org/github.com/ThalesIgnite/crypto11) for details of various limitations,
especially regarding symmetric crypto.
Installation
============
Since v1.0.0, crypto11 requires Go v1.11+. Install the library by running:
```bash
go get github.com/ThalesIgnite/crypto11
```
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](https://godoc.org/github.com/ThalesIgnite/crypto11)) or via a configuration
file. The configuration file is a JSON representation of the `Config` struct.
A minimal configuration file looks like this:
```json
{
"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.
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).
Testing with Thales Luna HSM
----------------------------
Testing with AWS CloudHSM
-------------------------
A minimal configuration file for CloudHSM will look like this:
```json
{
"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
---------------------
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.
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:
$ 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.
Limitations
===========
* The [PKCS1v15DecryptOptions SessionKeyLen](https://golang.org/pkg/crypto/rsa/#PKCS1v15DecryptOptions) 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](https://github.com/ThalesIgnite/crypto11/issues/5) for further discussion.
* Symmetric crypto support via [cipher.Block](https://golang.org/pkg/crypto/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](https://golang.org/pkg/crypto/cipher/#BlockMode)).
See [issue #6](https://github.com/ThalesIgnite/crypto11/issues/6) for further discussion.
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.
|