Topic: PKCS11 callback for hardware

Dear community,

I am using a hardware token to do some PKCS11 operation such as generate key pair, generate random and sign using ECC.
I am using the WolfMQTT client with the latest wolfSSL code with  --enable-pkcs11 and --enable-crytocb for the callback.

My hardware is well initialized, the  communication is fine.

I modify the 'mqttexample' to load the private key from the token, which seems to be fine.

I am using:
typedef int (*CryptoDevCallbackFunc)(int devId, wc_CryptoInfo* info, void* ctx);
WOLFSSL_API int wc_CryptoCb_RegisterDevice(
    int devId,
    CryptoDevCallbackFunc cb,
    void* ctx);

in my mqttexample file:
_ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb,  &token);

This seems to be fine.

The problem i am facing is my token only support generate key pair, generate random and sign using ECC.
All the other operation, i do not wish to use my hardware token.

Unfortunately by using this callback, WofSSL expect the verify operation to be found, but it is not supported.

How can implement a callback to only support these 3 operations. (random, genKeyPair and Sign)?

Thank you for your help.
Regards
Remy

Share

Re: PKCS11 callback for hardware

Hi Remy,

Thanks for joining the wolfSSL Forum. When you said:

Unfortunately by using this callback, WofSSL expect the verify operation to be found, but it is not supported.

Could you please share the error that you are seeing? Is it an actual verify operation failure, or just that the init is failing because the verify does not exist (NULL)?

Re: PKCS11 callback for hardware

Hi Remy,

In your crypto callback just return `CRYPTOCB_UNAVAILABLE` and it will fallback to using software operations.

Thanks,
David Garske, wolfSSL

Share

4 (edited by saksik.remy 2021-02-21 19:58:54)

Re: PKCS11 callback for hardware

Hi all,

Thanks for your help.

i will try to return the "CRYPTOCB_UNAVAILABLE" and see if it is working for me.

@embhor:
The verify operation fails i guess because it is NULL due to the ''Not supported operation"

@all:
I also got confuse between the" --enable-crytocb", and the "--enable-pk-callback"...
I believe I do not need the pk-callback, because I do not want to do extra operation with the keys...But maybe this two feature are working together.


For your reference I have posted the log i am getting...
You can see I am using the private key ID as a standard URL with "%" separator, I am not sure that this is supported by WolfSSL tho.

pi@raspberrypi:~/experiment/wolfMQTT-Client/wolfMQTT/examples/mqttclient $ ./mqttclient -h localhost -p 1883 -t -A ~/certs/ca.crt -c ~/certs/exportedClientCert.crt -K %AA%07%19%18%C6%16%14%FF%DF%C7%3F%12%85%24
MQTT Client: QoS 0, Use TLS 1
MQTT Net Init: Success (0)
MQTT Init: Success (0)
NetConnect: Host localhost, Port 1883, Timeout 5000 ms, Use TLS 1
wolfSSL Entering wolfSSL_Init
wolfSSL Entering wolfCrypt_Init
wolfSSL Entering TLSv1_2_client_method_ex
wolfSSL Entering wolfSSL_CTX_new_ex
wolfSSL Entering wolfSSL_CertManagerNew
wolfSSL Leaving WOLFSSL_CTX_new, return 0
wolfSSL Entering wolfSSL_CTX_set_verify
wolfSSL_CTX_load_verify_locations_ex
Getting dynamic buffer
Processing CA PEM file

<WolfSSL step hidden all okay >

Got Cert Header
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Cert Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
Got Key
ECDSA cert signature [What is this step?]

PKCS 11 REQUIRED
CTX DEV ID is 1
Loading my pkcs library

Application::Application - Elapsed time <0.003377> seconds
C_GetFunctionList - <BEGIN> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:08(UTC)]
C_GetFunctionList - [IN]
C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <0x25244>
C_GetFunctionList - Elapsed time <0.000001> seconds
C_GetFunctionList - [RV] <0x00> (CKR_OK)
C_GetFunctionList - [OUT]
C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <0x25244>
C_GetFunctionList - <END> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:08(UTC)]


PKCS 11 object are found here

Object CKO_CERTIFICATE
CKA_TOKEN <1>
CKA_PRIVATE <0>
CKA_MODIFIABLE <1>
CKA_TRUSTED <1>
CKA_SUBJECT - <0x2435c0> - size <33> - buffer <30 1F 31 1D 30 1B 06 03 55 04 03 0C 14 38 39 39 36 36 30 36 30 39 39 30 30 38 37 34 32 34 31 32 38>
CKA_ID - <0x2430e8> - size <20> - buffer <61 0A B8 C5 27 B1 CD 91 9B C4 E6 6A B2 42 70 45 9C A1 63 05>

Object CKO_PUBLIC_KEY
CKA_TOKEN <1>
CKA_PRIVATE <0>
CKA_ID - <0x2420a0> - size <20> - buffer <AA 07 19 18 C6 16 14 FF DF C7 3F 12 85 24 E9 18 FF B3 B7 02>

Object CKO_PRIVATE_KEY
CKA_TOKEN <1>
CKA_PRIVATE <1>
CKA_MODIFIABLE <1>
CKA_ID - <0x2446d8> - size <20> - buffer <AA 07 19 18 C6 16 14 FF DF C7 3F 12 85 24 E9 18 FF B3 B7 02>


C_CloseSession - Elapsed time <0.000062> seconds
C_CloseSession - [RV] <0x00> (CKR_OK)
C_CloseSession - <END> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]

wolfSSL Leaving SSL_new, return 0
wolfSSL Entering wolfSSL_SetCertCbCtx
SSL DEVICE ID IS SET TO 1
wolfSSL Entering SSL_connect()
wolfSSL Entering SendClientHello
Adding signature algorithms extension
growing output buffer

Signature Algorithms extension to write
Point Formats extension to write
Supported Groups extension to write
Encrypt-Then-Mac extension to write
EMS extension to write
Shrinking output buffer

wolfSSL Leaving SendClientHello, return 0
connect state: CLIENT_HELLO_SENT
growing input buffer

received record layer msg
got HANDSHAKE
wolfSSL Entering DoHandShakeMsg()
wolfSSL Entering DoHandShakeMsgType
processing server hello
wolfSSL Entering DoServerHello
Point Formats extension received
Extended Master Secret extension received
wolfSSL Entering VerifyClientSuite
wolfSSL Leaving DoServerHello, return 0
Shrinking input buffer

wolfSSL Leaving DoHandShakeMsgType(), return 0
wolfSSL Leaving DoHandShakeMsg(), return 0
growing input buffer

received record layer msg
got HANDSHAKE
wolfSSL Entering DoHandShakeMsg()
wolfSSL Entering DoHandShakeMsgType
processing certificate
wolfSSL Entering DoCertificate
wolfSSL Entering ProcessPeerCerts
Loading peer's cert chain
        Put another cert into chain
        Put another cert into chain
wolfSSL Entering GetExplicitVersion
wolfSSL Entering GetSerialNumber
Got Cert Header
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Cert Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
Got Key
Parsed Past Key
wolfSSL Entering DecodeCertExtensions
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeSubjKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAuthKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeBasicCaConstraint
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
CA found
wolfSSL Entering ConfirmSignature
wolfSSL Entering GetObjectId()

C_OpenSession - <BEGIN> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]
C_OpenSession - [IN]
C_OpenSession - slotID <00>
C_OpenSession - CK_FLAGS <CKF_SERIAL_SESSION>
C_OpenSession - pApplication <00>
C_OpenSession - Notify <00>
C_OpenSession - phSession <0xbe80aab8> (0x323935a0)

C_GetMechanismInfo - <BEGIN> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]
C_GetMechanismInfo - [IN]
C_GetMechanismInfo - slotID <00>
C_GetMechanismInfo - CK_MECHANISM_TYPE <CKM_ECDSA>
C_GetMechanismInfo - CK_MECHANISM_INFO - ulMinKeySize <0xb6eeaf2c> - ulMaxKeySize <0xbe80aab8> - flags <CKF_EXTENSION | CKF_UNWRAP | CKF_WRAP | CKF_GENERATE | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_SIGN>


C_GetMechanismInfo - Elapsed time <0.034830> seconds
C_GetMechanismInfo - [RV] <0x5> (CKR_GENERAL_ERROR) //Not Supported by hardware
C_GetMechanismInfo - [OUT]
C_GetMechanismInfo - CK_MECHANISM_INFO - ulMinKeySize <0xb6eeaf2c> - ulMaxKeySize <0xbe80aab8> - flags <CKF_EXTENSION | CKF_UNWRAP | CKF_WRAP | CKF_GENERATE | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_SIGN>

C_CloseSession - Elapsed time <0.000062> seconds
C_CloseSession - [RV] <0x00> (CKR_OK)
C_CloseSession - <END> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]

wolfSSL Leaving ConfirmSignature, return 0
Verified CA from chain and already had it
Verifying Peer's cert
wolfSSL Entering GetExplicitVersion
wolfSSL Entering GetSerialNumber
Got Cert Header
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Cert Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
Got Key
Parsed Past Key
wolfSSL Entering DecodeCertExtensions
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAuthKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeBasicCaConstraint
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeKeyUsage
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAltNames
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
CA found
wolfSSL Entering ConfirmSignature
wolfSSL Entering GetObjectId()

C_OpenSession - Elapsed time <0.000159> seconds
C_OpenSession - [RV] <0x00> (CKR_OK)

C_GetMechanismInfo - Elapsed time <0.019171> seconds
C_GetMechanismInfo - [RV] <0x5> (CKR_GENERAL_ERROR) //Not Supported by hardware

C_CloseSession - Elapsed time <0.000060> seconds
C_CloseSession - [RV] <0x00> (CKR_OK)
C_CloseSession - <END> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]

wolfSSL Leaving ConfirmSignature, return 0
Verified Peer's cert
wolfSSL Entering GetObjectId()
wolfSSL Leaving ProcessPeerCerts, return 0
wolfSSL Leaving DoCertificate, return 0
Shrinking input buffer

wolfSSL Leaving DoHandShakeMsgType(), return 0
wolfSSL Leaving DoHandShakeMsg(), return 0
growing input buffer

received record layer msg
got HANDSHAKE
wolfSSL Entering DoHandShakeMsg()
wolfSSL Entering DoHandShakeMsgType
processing server key exchange
wolfSSL Entering DoServerKeyExchange
wolfSSL Entering EccVerify
C_OpenSession - <BEGIN> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]
C_OpenSession - [IN]
C_OpenSession - slotID <00>

C_GetMechanismInfo - Elapsed time <0.019167> seconds
C_GetMechanismInfo - [RV] <0x5> (CKR_GENERAL_ERROR) //Not Supported by hardware
C_GetMechanismInfo - [OUT]
C_GetMechanismInfo - CK_MECHANISM_INFO - ulMinKeySize <0xb6eeaf2c> - ulMaxKeySize <0xbe80ab68> - flags <CKF_EXTENSION | CKF_GENERATE | CKF_VERIFY | CKF_DIGEST | CKF_SIGN>

C_CloseSession - Elapsed time <0.000063> seconds
C_CloseSession - [RV] <0x00> (CKR_OK)
C_CloseSession - <END> [PID=0x000003B1, TID=0xb6f6a210] [2021-02-22 02:01:12(UTC)]

wolfSSL Leaving EccVerify, return 0
wolfSSL Leaving DoServerKeyExchange, return 0
Shrinking input buffer

wolfSSL Leaving EccSign, return -170
wolfSSL Leaving SendCertificateVerify, return -170
wolfSSL error occurred, error = -170
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return -170
wolfSSL Entering SSL_free
CTX ref count not 0 yet, no free
Shrinking output buffer

Share

Re: PKCS11 callback for hardware

The `-K` option is expecting a path to a file.

6 (edited by saksik.remy 2021-02-24 00:26:13)

Re: PKCS11 callback for hardware

Great I managed to verify my Certificate.

I still have an issue tho, could someone explain a bit the SendClientKeyExhange()?

I am using ECC (ECDSA 256). But somehow in this function after generating the Public key (EccMakeKey), I end up exporting the key with  wc_ecc_export_x963 .... Which i found really strange...I am not sure i understand this part. I am supposed to compute the DH keys...

Then i have a error ECC_EXPORT_ERROR             = -354,   /* Bad ECC Export Key */
Which make sense to me.

Did I forgot a #Define ?? or configure the WolfSSL build with some missing options?


The code below is the internal.c file, sendClientKeyExchange(...)

i have define HAVE_ECC but i never defined the ECCKEY_EXPORT and I dont not have PK_CALLBACKS.

I would appreciate some help where I go wrong...

Thanks a lot for your time
Remy

 #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
                #ifdef HAVE_PK_CALLBACKS
                    /* if callback then use it for shared secret */
                    if (ssl->ctx->EccSharedSecretCb != NULL) {
                        break;
                    }
                #endif
                WOLFSSL_MSG("\reach here, why?\n");
                    /* Place ECC key in buffer, leaving room for size */
                    ret = wc_ecc_export_x963((ecc_key*)ssl->hsKey,
                                args->encSecret + OPAQUE8_LEN, &args->encSz);
                    if (ret != 0) {
                        ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
                    }
                #endif /* HAVE_ECC */

Share

Re: PKCS11 callback for hardware

Do you still have `--enable-pk-callback` in your configure line?

8 (edited by saksik.remy 2021-02-25 03:02:18)

Re: PKCS11 callback for hardware

I have removed it because i do not do anything extra with the public key, It is just the normal process of TLS handshake. But perhaps I am wrong. I am doubtful on the callback usage...I don't want to modify the internal.c code.

At sendClientKeyExhange():
The process leads me to: wc_ecc_export_x963.

Why do I need to export the public key?

The GenerateKeyPair() was successful so I have the public key already.

The process is:
A. public key = Generate the Key pair()
B. Export the public key () - strange to me
C. Compute the share secret()

Am I wrong?

Remy

Share

Re: PKCS11 callback for hardware

Hi Remy,

No, I do not think you need the pk callback option, but you mentioned earlier in the thread.

The `NO_ECC_KEY_EXPORT` define comes from here (because `HAVE_ECC` is defined):
https://github.com/wolfSSL/wolfssl/blob … gs.h#L1821

The public key is exported to the `ssl->hsKey` structure in order to compute the shared secret.

                    ret = EccSharedSecret(ssl,
                        (ecc_key*)ssl->hsKey, ssl->peerEccKey,
                        args->output + OPAQUE8_LEN, &args->length,
                        ssl->arrays->preMasterSecret + OPAQUE16_LEN,
                        &ssl->arrays->preMasterSz,
                        WOLFSSL_CLIENT_END
                    );