Skip to content

Commit

Permalink
Merge pull request #59 from ThalesIgnite/cloudhsm
Browse files Browse the repository at this point in the history
Changes to support AWS CloudHSM
  • Loading branch information
Nick Smith authored Sep 17, 2019
2 parents ee5b3fb + ad6f4b1 commit 3d83a0a
Show file tree
Hide file tree
Showing 19 changed files with 698 additions and 267 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,53 @@ A minimal configuration file looks like this:
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 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
---------------------

Expand Down
40 changes: 29 additions & 11 deletions aead.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ const (
PaddingPKCS
)

var errBadGCMNonceSize = errors.New("nonce slice too small to hold IV")

type genericAead struct {
key *SecretKey

overhead int

nonceSize int

makeMech func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, error)
// Note - if the GCMParams result is non-nil, the caller must call Free() on the params when
// finished.
makeMech func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error)
}

// NewGCM returns a given cipher wrapped in Galois Counter Mode, with the standard
Expand All @@ -66,9 +70,9 @@ func (key *SecretKey) NewGCM() (cipher.AEAD, error) {
key: key,
overhead: 16,
nonceSize: 12,
makeMech: func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, error) {
makeMech: func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) {
params := pkcs11.NewGCMParams(nonce, additionalData, 16*8 /*bits*/)
return []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.GCMMech, params)}, nil
return []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.GCMMech, params)}, params, nil
},
}
return g, nil
Expand Down Expand Up @@ -96,12 +100,12 @@ func (key *SecretKey) NewCBC(paddingMode PaddingMode) (cipher.AEAD, error) {
key: key,
overhead: 0,
nonceSize: key.BlockSize(),
makeMech: func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, error) {
makeMech: func(nonce []byte, additionalData []byte) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) {
if len(additionalData) > 0 {
return nil, errors.New("additional data not supported for CBC mode")
return nil, nil, errors.New("additional data not supported for CBC mode")
}

return []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcsMech, nonce)}, nil
return []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcsMech, nonce)}, nil, nil
},
}

Expand All @@ -117,12 +121,15 @@ func (g genericAead) Overhead() int {
}

func (g genericAead) Seal(dst, nonce, plaintext, additionalData []byte) []byte {

var result []byte
if err := g.key.context.withSession(func(session *pkcs11Session) (err error) {
var mech []*pkcs11.Mechanism
if mech, err = g.makeMech(nonce, additionalData); err != nil {
return
mech, params, err := g.makeMech(nonce, additionalData)
if err != nil {
return err
}
defer params.Free()

if err = session.ctx.EncryptInit(session.handle, mech, g.key.handle); err != nil {
err = fmt.Errorf("C_EncryptInit: %v", err)
return
Expand All @@ -131,6 +138,15 @@ func (g genericAead) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
err = fmt.Errorf("C_Encrypt: %v", err)
return
}

if g.key.context.cfg.UseGCMIVFromHSM {
if len(nonce) != len(params.IV()) {
return errBadGCMNonceSize
}

copy(nonce, params.IV())
}

return
}); err != nil {
panic(err)
Expand All @@ -143,10 +159,12 @@ func (g genericAead) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
func (g genericAead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
var result []byte
if err := g.key.context.withSession(func(session *pkcs11Session) (err error) {
var mech []*pkcs11.Mechanism
if mech, err = g.makeMech(nonce, additionalData); err != nil {
mech, params, err := g.makeMech(nonce, additionalData)
if err != nil {
return
}
defer params.Free()

if err = session.ctx.DecryptInit(session.handle, mech, g.key.handle); err != nil {
err = fmt.Errorf("C_DecryptInit: %v", err)
return
Expand Down
Loading

0 comments on commit 3d83a0a

Please sign in to comment.