Skip to content

Commit

Permalink
hsm: update libp11 patch
Browse files Browse the repository at this point in the history
Some PKCS#11 implementations don't support all the features libp11
is using. Some of them are removed.

Object attributes for RSA and ECC keypair were modified:
  - Removed CKA_WRAP from pub/priv RSA keys since it's unclear if RSA
    keys are used for wrapping in any cryptographic algorithm.
  - Changed RSA public exponent from 0x101 to 0x10001
  - Removed CKA_DERIVE from ECC public key since only private key is used
    for derivation along with public key from the other party
  - Removed CKA_WRAP from ECC public keys since algorithm that uses ECC
    public keys for key wrapping doesn't exist
  - Removed CKA_VERIFY_RECOVER from ECC public key since this is only
    supported for RSA based DSAs
  - Removed CKA_ENCRYPT from ECC public keys since they are never used
    for encryption
  - Removed CKA_UNWRAP from ECC private keys since algorithm that uses
    ECC private keys for key unwrapping doesn't exist
  • Loading branch information
istepic committed Apr 19, 2023
1 parent 5413e4a commit 115001d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 27 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ build/$ cmake -DBUILD_TESTING=True -DMOCOCRW_DILITHIUM_ENABLED=ON ..
### Build with HSM support

HSM support is an **optional** feature for MoCOCrW. This allows for loading and storing keys on HSM
and using those keys in various cryptographic algorithms without having keys in memory. To build
MoCOCrW with HSM support, a patched version of libp11 is necessary since upstream libp11 does not
support key generation through OpenSSL's ENGINE API.
and using those keys in various cryptographic algorithms without having keys in memory. Thread safety
is not guaranteed. To build MoCOCrW with HSM support, a patched version of libp11 is necessary since
upstream libp11 does not support key generation through OpenSSL's ENGINE API.

[libp11 release 0.4.12](https://github.com/OpenSC/libp11/releases/tag/libp11-0.4.12) patched with
[patch for key generation](https://github.com/bmwcarit/MoCOCrW/blob/openssl1.1/dockerfiles/feature-support/hsm-patches/0001-Introduce-generic-keypair-generation-interface-and-e.patch) is required for building MoCOCrW with
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
From 828282b17f40237bb875e93df0e216e12c4f2504 Mon Sep 17 00:00:00 2001
From 8468ecc844664c2f066492ed08569d5b7db37756 Mon Sep 17 00:00:00 2001
From: istepic <[email protected]>
Date: Mon, 5 Dec 2022 22:44:25 +0100
Subject: [PATCH] Introduce generic keypair generation interface and engine
Expand Down Expand Up @@ -46,13 +46,14 @@ Signed-off-by: istepic <[email protected]>
src/libp11-int.h | 15 ++-
src/libp11.h | 48 +++++++---
src/p11_front.c | 32 +++++--
src/p11_key.c | 119 +++++++++++++++++++++++-
src/p11_key.c | 133 +++++++++++++++++++++++---
src/p11_load.c | 1 -
src/p11_misc.c | 75 +++++++++++++++
src/p11_slot.c | 1 +
tests/Makefile.am | 6 +-
tests/keygen.c | 215 +++++++++++++++++++++++++++++++++++++++++++
tests/keygen.softhsm | 39 ++++++++
12 files changed, 587 insertions(+), 33 deletions(-)
13 files changed, 595 insertions(+), 40 deletions(-)
create mode 100644 tests/keygen.c
create mode 100755 tests/keygen.softhsm

Expand Down Expand Up @@ -330,7 +331,7 @@ index f74f209..f82c9a3 100644
{
PKCS11_OBJECT_private *key = PRIVKEY(pkey);
diff --git a/src/p11_key.c b/src/p11_key.c
index ec7f279..57cba43 100644
index ec7f279..5a30e79 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -252,8 +252,8 @@ int pkcs11_reload_object(PKCS11_OBJECT_private *obj)
Expand All @@ -344,7 +345,12 @@ index ec7f279..57cba43 100644

PKCS11_CTX_private *ctx = slot->ctx;
CK_SESSION_HANDLE session;
@@ -266,10 +266,20 @@ int pkcs11_generate_key(PKCS11_SLOT_private *slot, int algorithm, unsigned int b
@@ -262,36 +262,45 @@ int pkcs11_generate_key(PKCS11_SLOT_private *slot, int algorithm, unsigned int b
CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0
};
CK_ULONG num_bits = bits;
- CK_BYTE public_exponent[] = { 1, 0, 1 };
+ CK_BYTE public_exponent[] = { 1, 0, 0, 0, 1 };
CK_OBJECT_HANDLE pub_key_obj, priv_key_obj;
int rv;

Expand All @@ -353,7 +359,7 @@ index ec7f279..57cba43 100644
- if (pkcs11_get_session(slot, 1, &session))
+ // R/W session is mandatory for key generation.
+ if (pkcs11_open_session(slot, 1)) {
+ return -1;
return -1;
+ }
+ // open_session might call C_CloseAllSessions if current session is not R/W.
+ // C_CloseAllSessions logs everyone out
Expand All @@ -363,12 +369,38 @@ index ec7f279..57cba43 100644
+ }
+ }
+ if (pkcs11_get_session(slot, 1, &session)) {
return -1;
+ return -1;
+ }

+ /* The following attributes are necessary for RSA encryption and DSA */
/* pubkey attributes */
pkcs11_addattr(&pubtmpl, CKA_ID, id, id_len);
@@ -310,6 +320,105 @@ int pkcs11_generate_key(PKCS11_SLOT_private *slot, int algorithm, unsigned int b
if (label)
pkcs11_addattr_s(&pubtmpl, CKA_LABEL, label);
pkcs11_addattr_bool(&pubtmpl, CKA_TOKEN, TRUE);
- pkcs11_addattr_bool(&pubtmpl, CKA_ENCRYPT, TRUE);
pkcs11_addattr_bool(&pubtmpl, CKA_VERIFY, TRUE);
- pkcs11_addattr_bool(&pubtmpl, CKA_WRAP, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_ENCRYPT, TRUE);
pkcs11_addattr_var(&pubtmpl, CKA_MODULUS_BITS, num_bits);
- pkcs11_addattr(&pubtmpl, CKA_PUBLIC_EXPONENT, public_exponent, 3);
+ pkcs11_addattr(&pubtmpl, CKA_PUBLIC_EXPONENT, public_exponent, 5);

/* privkey attributes */
pkcs11_addattr(&privtmpl, CKA_ID, id, id_len);
if (label)
pkcs11_addattr_s(&privtmpl, CKA_LABEL, label);
- pkcs11_addattr_bool(&privtmpl, CKA_TOKEN, TRUE);
pkcs11_addattr_bool(&privtmpl, CKA_PRIVATE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_TOKEN, TRUE);
pkcs11_addattr_bool(&privtmpl, CKA_SENSITIVE, TRUE);
pkcs11_addattr_bool(&privtmpl, CKA_DECRYPT, TRUE);
pkcs11_addattr_bool(&privtmpl, CKA_SIGN, TRUE);
- pkcs11_addattr_bool(&privtmpl, CKA_UNWRAP, TRUE);

/* call the pkcs11 module to create the key pair */
rv = CRYPTOKI_call(ctx, C_GenerateKeyPair(
@@ -310,6 +319,108 @@ int pkcs11_generate_key(PKCS11_SLOT_private *slot, int algorithm, unsigned int b
return 0;
}

Expand All @@ -385,8 +417,8 @@ index ec7f279..57cba43 100644
+ CK_OBJECT_HANDLE pub_key_obj, priv_key_obj;
+ int rv;
+
+ unsigned char *ecdsa_params = NULL;
+ int ecdsa_params_len = 0;
+ unsigned char *ec_params = NULL;
+ int ec_params_len = 0;
+ unsigned char *tmp = NULL;
+ ASN1_OBJECT *curve_obj = NULL;
+ int curve_nid = NID_undef;
Expand Down Expand Up @@ -417,36 +449,39 @@ index ec7f279..57cba43 100644
+ curve_obj = OBJ_nid2obj(curve_nid);
+ if (!curve_obj)
+ return -1;
+ ecdsa_params_len = i2d_ASN1_OBJECT(curve_obj, NULL);
+ ecdsa_params = (unsigned char *)OPENSSL_malloc(ecdsa_params_len);
+ if (!ecdsa_params)
+ // convert to DER format and take just the length
+ ec_params_len = i2d_ASN1_OBJECT(curve_obj, NULL);
+ if (ec_params_len < 0)
+ return -1;
+ ec_params = OPENSSL_malloc(ec_params_len);
+ if (!ec_params)
+ return -1;
+ // ec_params points to begining of DER encoded object. Since we need this
+ // location later and OpenSSL changes it in i2d_ASN1_OBJECT to point to 1 byte
+ // after DER encoded object, we assign the pointer to temporary throw-away
+ // pointer tmp
+ tmp = ec_params;
+ if (i2d_ASN1_OBJECT(curve_obj, &tmp) < 0)
+ return -1;
+ tmp = ecdsa_params;
+ i2d_ASN1_OBJECT(curve_obj, &tmp);
+
+ /* The following attributes are necessary for ECDSA and ECDH mechanisms */
+ /* pubkey attributes */
+ pkcs11_addattr(&pubtmpl, CKA_ID, id, id_len);
+ if (label)
+ pkcs11_addattr_s(&pubtmpl, CKA_LABEL, label);
+ pkcs11_addattr_bool(&pubtmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_DERIVE, FALSE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_WRAP, FALSE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_VERIFY, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_VERIFY_RECOVER, FALSE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_ENCRYPT, FALSE);
+ pkcs11_addattr(&pubtmpl, CKA_ECDSA_PARAMS, ecdsa_params, ecdsa_params_len);
+ pkcs11_addattr(&pubtmpl, CKA_EC_PARAMS, ec_params, ec_params_len);
+
+ /* privkey attributes */
+ pkcs11_addattr(&privtmpl, CKA_ID, id, id_len);
+ if (label)
+ pkcs11_addattr_s(&privtmpl, CKA_LABEL, label);
+ pkcs11_addattr_bool(&privtmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_PRIVATE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_SENSITIVE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_DERIVE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_UNWRAP, FALSE);
+ pkcs11_addattr_bool(&privtmpl, CKA_SIGN, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_DECRYPT, FALSE);
+
+ /* call the pkcs11 module to create the key pair */
+ rv = CRYPTOKI_call(ctx, C_GenerateKeyPair(
Expand All @@ -465,7 +500,7 @@ index ec7f279..57cba43 100644
+ /* zap all memory allocated when building the template */
+ pkcs11_zap_attrs(&privtmpl);
+ pkcs11_zap_attrs(&pubtmpl);
+ OPENSSL_free(ecdsa_params);
+ OPENSSL_free(ec_params);
+
+ CRYPTOKI_checkerr(CKR_F_PKCS11_GENERATE_KEY, rv);
+ return 0;
Expand All @@ -474,6 +509,18 @@ index ec7f279..57cba43 100644
/*
* Store a private key on the token
*/
diff --git a/src/p11_load.c b/src/p11_load.c
index e89b0c7..330dc91 100644
--- a/src/p11_load.c
+++ b/src/p11_load.c
@@ -81,7 +81,6 @@ int pkcs11_CTX_load(PKCS11_CTX *ctx, const char *name)
/* Tell the PKCS11 to initialize itself */
memset(&args, 0, sizeof(args));
/* Unconditionally say using OS locking primitives is OK */
- args.flags |= CKF_OS_LOCKING_OK;
args.pReserved = cpriv->init_args;
rv = cpriv->method->C_Initialize(&args);
if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
diff --git a/src/p11_misc.c b/src/p11_misc.c
index 1b0e64d..1d9a845 100644
--- a/src/p11_misc.c
Expand Down

0 comments on commit 115001d

Please sign in to comment.