Closed Dvergatal closed 3 years ago
For some reason they set their template to include CKA_DERIVE=true, which is not supported: ERROR: CKA_DERIVE=true not supported
You can use tpm2_ptool addkey --algorithm ecc256 ...
Offhand, I think if you use p11-tool, but I could be wrong.
The TPM can't support CKA_DERIVE true, which is why the library fails. I could soften this to a warning and move on, but I don't know what the ramifications would be getting an object that doesn't support it's template.
From: Dvergatal notifications@github.com Sent: Thursday, February 18, 2021 1:01 PM To: tpm2-software/tpm2-pkcs11 tpm2-pkcs11@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: [tpm2-software/tpm2-pkcs11] pkcs11-tools EC:prime256v1 keypair gen fails (#656)
OS: Rockchip modified Buildroot 2018-rc3 (opensc 0.20.0) tpm2-tss: 3.0.1 (tarball) tpm2-pkcs11: 1.5.0 (tarball) tpm2-abrmd: 2.3.3 (tarball) Token initialized with pkcs11-tool with label foo
root@px30-64:~# pkcs11-tool --modul /usr/lib/libtpm2_pkcs11.so --login --login-type user --keypairgen --id 1 --key-type EC:prime256v1 ERROR: Listing FAPI token objects failed. Using slot 0 with a present token (0x1) Logging in to "foo". Please enter User PIN: ERROR: CKA_DERIVE=true not supported ERROR: Failed checking private attrs error: PKCS11 function C_GenerateKeyPair failed: rv = CKR_ATTRIBUTE_VALUE_INVALID (0x13) Aborting.
With RSA key type all is working .
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/tpm2-software/tpm2-pkcs11/issues/656, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEHNWBZD3HJ2E47GM4KXV3DS7VPXBANCNFSM4X23CUDA.
I can check it with p11-tool, but still pkcs11-tool is a part of opensc as well as libpkcs11.so openssl engine library. So i think that it does not matter if i will use pkcs11-tool or libpkcs11 engine, the result will be the same because of the common api. And my goal is to use this engine to load tpm2-pkcs11.so module with it.
Ok i have verified it with p11tool and it actually does the ec key. I have also verified using pkcs11-tool that it read the token objects correctly and yeah, ec key is also being read with it. I dunno maybe i should post to pkcs11-tool guys and ask them for support in this problem?
@williamcroberts I have read some other bugs related to EC key generation and it is different than in RSA. According to this and this EC keys should have CKA_DERIVE attribute supported instead of CKA_DECRYPT.
I think that this should be fixed int tpm2-pkcs11 library. Btw. you've mentioned that TPM can't support CKA_DERIVE true. Does it come from hardware limitations?
@williamcroberts I have read some other bugs related to EC key generation and it is different than in RSA. According to this and this EC keys should have CKA_DERIVE attribute supported instead of CKA_DECRYPT.
I think that this should be fixed int tpm2-pkcs11 library. Btw. you've mentioned that TPM can't support CKA_DERIVE true. Does it come from hardware limitations?
Section 6.3 says EC only supports Sign, Verify and Derive.
The template should probably be sent with derive set to false, then it would work.
But I can't really support Derive.. as children keys are not derived from parent keys but rather random values fed through a kdf.
Ok i have verified it with p11tool and it actually does the ec key. I have also verified using pkcs11-tool that it read the token objects correctly and yeah, ec key is also being read with it. I dunno maybe i should post to pkcs11-tool guys and ask them for support in this problem?
They have a --usage-derive option, perhaps we can do:
--usage-derive (default to true)
--usage-derive=false
--usage-derive=true
but they might not take the gnu getopt_long extension for optional arguments.
Hi @williamcroberts i have started the talk about the problem at OpenSC/OpenSC#2238. We should probably discuss it all together.
As one of the OpenSC developers...
@williamcroberts you said: "But I can't really support Derive.. as children keys are not derived from parent keys but rather random values fed through a kdf." I am not sure what you mean.
EC keys can support ECDSA to sign, verify and/or a number of ECDH* mechanisms. With ECDH, each party uses the peer's public key and its own private key to derive a shared secret. The peer might be an ephemeral EC key, or an actual hardware key on some other machine.
But from your https://github.com/tpm2-software/tpm2-pkcs11/blob/master/docs/ARCHITECTURE.md it looks like you are doing more then just using the crypto capabilities of a TPM module. @Dvergatal This might be your problem too, as if they appear to not support ECDH in a way that you maybe trying to use it.
These might help: https://tools.ietf.org/html/rfc5753 https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3066.pdf
In any case an EC key should not have the encrypt/decrypt usage bits set.
(And note that if a EC key is meant to be used only for derivation, it may need to be used with ECDSA to sign a certificate request at least once.)
@dengert Thx for your quick response. In the OpenSC issue i have posted you that mine tpm supports ECDH. I can also ask @PeterHuewe from infineon to confirm if this is true.
BTW.I think i now get what @williamcroberts meant by kdf and derive, because yesterday i was also confused about it. According to my knowledge KDF is a key derivation function, but as far as i know it is rather used to generate AES-like cipher nounce or key and derive is a parameter in assymetric cryptography which is describing that key maybe used i.e. by ECDH or ECMQV schemes. But still ECDH or even ECMQV doesn't need KDF to derive shared secret, because it's it is how this algorithm works, it simply generates it.
"This mechanism derives a secret value, and truncates the result according to the CKA_KEY_TYPE attribute of the template and, if it has one and the key type supports it, the CKA_VALUE_LEN attribute of the template. (The truncation removes bytes from the leading end of the secret value.)"
Yes, you specify the CKA_KEY_TYPE in the template. There is also a CKK_GENERIC_SECRET that does no truncation.
@williamcroberts you said: "But I can't really support Derive.. as children keys are not derived from parent keys but rather random values fed through a kdf." I am not sure what you mean.
@dengert maybe my understanding of attribute CKA_DERVIVE is incorrect. If their are any key derivation processes that need access to the private key bytes themselves, I wouldn't be able to support it. But it appears that most usages around this are for DH through the C_DeriveKey() interface, which I don't support, but we can let a key live with this attribute.
So I guess we can just allow it.
The C_DeriveKey when used with and EC key uses one of the CKM_ECDH* mechanisms. The EC key must have CKA_DERIVE=true. For example a token might have a EC key used only for signatures and one used only for keyAgreement (x509 usage bits) i.e. CKA_DERIVE in PKCS11.
So does "So I guess we can just allow it." mean you will allow the creation of the key with CKA_DERIVE=true and save in the TPM some equivalent usage bits. But you PKCS11 module will not support the the use of C_DeriveKey with an EC key? So you could create it, but not be able to use it.
But I am under the impression @Dvergatal wants to use your PKCS11 module with C_DeriveKey. Or is there some other PKCS11 or other way to access the TPM?
From the above conversation, both of you are talking like C_DeriveKey just "simply generates it" or "as children keys are not derived from parent keys but rather random values fed through a kdf."
That is not quite true with EC keys. random data is not used. The point is ECDH requires 2 EC keys. Party A and Party B usually on different machines. They each exchange public keys usually via certificates. So A uses A's private key and B's public key to generate a shared secret, and B uses B's private key, and A's public key to generate the same shared secret. So they can then use this shared symmetric key for encryption.
The above is the simple case, but A and B will always create the same shared secret. So there are ways to use a third temporary EC key, called an ephemeral EC key usually done is software using random data on one side. Then different shared secrets can be created for each session. (Google for ephemeral ECDH) But the PKCS11 module does not have to deal with the ephemeral EC key as it can be done in software.
With RSA, A creates a symmetric key, encrypts using the public key of B, sends the encrypted key to B, who decrypts it with B's private RSA key.
No no, first of all i do not think that C_DeriveKey simply generates it, because i know ECDH and ECMQV shemes, i do know how both of theme works. The mechanism for both of them is during i.e. TLS protocol and in such case the shared key is being derived for the session not for the whole time of key in the token storage. And as you have @dengert rightly noted in case of RSA encryption the shared key is encrypted and send to the receiver and vice versa. I really know the use cases :]
My real problem was, from the beginning, that i wasn't able to create and hence properly use ec keys for example with diffie-hellman algorithm, which is being used in tls protocol. Maybe i haven't written it properly in the subject, which is why i apologize.
P.S. i know that ECDH/ECMQV can be done with the software using crypto++ or openssl whatever :] still i just simply wanted to generate ec key pair using opensc/pkcs11-tool/libp11 api and for now it is not possible.
So does "So I guess we can just allow it." mean you will allow the creation of the key with CKA_DERIVE=true and save in the TPM some equivalent usage bits. But you PKCS11 module will not support the the use of C_DeriveKey with an EC key? So you could create it, but not be able to use it.
Yes, but I can't add any usage bits like that to the TPM side, it has encrypt, decrypt attributes and then some interfaces for performing the private key operation. That's why the keys have those attributes set, its just a side affect of the way I coded it. I see we need to change that to something else, I guess thats CKA_DERIVE.
But I am under the impression @Dvergatal wants to use your PKCS11 module with C_DeriveKey. Or is there some other PKCS11 or other way to access the TPM?
I think the issue just stems from key generation, the pkcs11-tool puts it in the template for EC key generation without any way to turn it off AFAICT.
From the above conversation, both of you are talking like C_DeriveKey just "simply generates it" or "as children keys are not derived from parent keys but rather random values fed through a kdf."
That is not quite true with EC keys. random data is not used. The point is ECDH requires 2 EC keys. Party A and Party B usually on different machines. They each exchange public keys usually via certificates. So A uses A's private key and B's public key to generate a shared secret, and B uses B's private key, and A's public key to generate the same shared secret. So they can then use this shared symmetric key for encryption.
Yeah I get DH. I didn't understand what CKA_DERIVE was really after, it was using that key via C_DeriveKey call. So disregard what I said there.
@Dvergatal well if TLS is going to use the TPM, does it use some other API?
It also looks like if you used pkcs11-tool --module /usr/lib/libtpm2_pkcs11.so --login --login-type user --keypairgen --id 1 --key-type EC:prime256v1 --usage-sign
it would only set the CKA_SIGN and not the CKA_DERIVE. The default is to set both.
https://github.com/OpenSC/OpenSC/blob/master/src/tools/pkcs11-tool.c#L2533-L2545 So no changes would be needed.
@dengert Thx for your quick response. In the OpenSC issue i have posted you that mine tpm supports ECDH. I can also ask @PeterHuewe from infineon to confirm if this is true.
Yes our SLx 9670 supports TPM2_ECDH_KeyGen
and TPM2_ECDH_ZGen
@PeterHuewe Hi thx for the confirmation :-) @dengert yeah i could do that, but wouldn't be that key unusable than with ECDH?
@williamcroberts does this pull request changes will be sufficiant with tag 1.5.0 or do i need to use guthub repo version? Ok that is true. I need the newest version from github :]
@williamcroberts Btw. will you be able to add support for ECDH mechanism too?
Not knowing much about TPM commands but a lot about smart cards and PKCS11, I have been relying on the latter.
In PKCS11 an EC key is an EC key, and can be used for ECDSA or ECDH with constrains based on the usage. A smart card could also enforce this if the usage is also saved or implied by information on the card. But since a key usually also has a certificate, and a certificate is obtained by the use or a CSR and the CSR is signed by the private key using ECDSA, a EC key meant to be used for ECDH only will still need to be used once to sign a CSR. In PKCS11 a key pair can be generated C_GererateKey on the smart card with the smartcard using its internal "random number generator".
In TPM it looks like the equivalent operation is TPM2_CreatePrimary as it appears to me the TPM does not have a uses the primary seed in the TPM for the "random number generator".
The PKCS11 C_DeriveKey with CKM_ECDH appears to equivalent to TPM2_ECDH_KeyGen. (I could be wrong.)
PKCS11 has been around since the late 1990's (My first use of PKCS11 and a smartcard was in 1998). Cards were very slow and no EC, so only the most primitive crypto operation was done on the card, i.e. RSA RAW. TPM is much newer with faster hardware, so much more can be done on the device.
http://epubs.surrey.ac.uk/813932/1/SSR.pdf has been helpful, (One of the Authors is from Infineon Technologies AG, rainer.urian@infineon.com)
But it still not clear if the usage bits are saved on the TPM and enforced by TPM.
It is also not clear if the TLS code @Dvergatal needs to use requires PKCS11 or uses some other API with the TPM.
@dengert Mainly i will use MQTTnet package written in C# on linux, but it uses openssl and openssl will use pkcs11 engine with tpm2-pkcs11 module, so i would suspect that if module is being used by openssl/libp11 engine than it will use PKCS11.
P.S. i should also write the whole process in here so let i describe it step by step:
@williamcroberts btw. as it was written already there shouldn't be encrypt/decrypt usages for ec keys, only sign, verify and derive.
@williamcroberts btw. as it was written already there shouldn't be encrypt/decrypt usages for ec keys, only sign, verify and derive.
Gotta love the PKCS11 spec, I don't know what section 6.3 @dengert is referencing. I went off the base spec which has, in Table 25 CKA_DECRYPT for all objects of class CKO_PRIVATE_KEY.
Not knowing much about TPM commands but a lot about smart cards and PKCS11, I have been relying on the latter.
In PKCS11 an EC key is an EC key, and can be used for ECDSA or ECDH with constrains based on the usage. A smart card could also enforce this if the usage is also saved or implied by information on the card. But since a key usually also has a certificate, and a certificate is obtained by the use or a CSR and the CSR is signed by the private key using ECDSA, a EC key meant to be used for ECDH only will still need to be used once to sign a CSR. In PKCS11 a key pair can be generated C_GererateKey on the smart card with the smartcard using its internal "random number generator".
In TPM it looks like the equivalent operation is TPM2_CreatePrimary as it appears to me the TPM does not have a uses the primary seed in the TPM for the "random number generator".
The PKCS11 C_DeriveKey with CKM_ECDH appears to equivalent to TPM2_ECDH_KeyGen. (I could be wrong.)
PKCS11 has been around since the late 1990's (My first use of PKCS11 and a smartcard was in 1998). Cards were very slow and no EC, so only the most primitive crypto operation was done on the card, i.e. RSA RAW.
I think our paths have crossed before, I did a PIV card years back and added the AES256 support for the symmetric admin commands.
TPM is much newer with faster hardware, so much more can be done on the device.
http://epubs.surrey.ac.uk/813932/1/SSR.pdf has been helpful, (One of the Authors is from Infineon Technologies AG, rainer.urian@infineon.com)
But it still not clear if the usage bits are saved on the TPM and enforced by TPM.
The attributes as known by PKCS11 are just stored in a sqlite3db, as they really are not of any use to the TPM itself. In this DB are two blobs that are the TPM keys, sealed to the TPM. Those blobs contain the key usages, as known by the TPM.
While pkcs11 has oodles of attributes, the TPM only has a few. So for things like EC keys, where later when we want to support derive and we have use commands like TPM2_ECDH_ZGen. The TPM object is created with TPMA_OBJECT_DECRYPT, and CKA_DERIVE is set to whatever.
It is also not clear if the TLS code @Dvergatal needs to use requires PKCS11 or uses some other API with the TPM.
I know folks that have TLS connections established with PKCS11, but I am not sure if they are EC based or not. If @Dvergatal needs something like C_DeriveKey, that's not supported, so we would need to add support for that. We have currently have the ECDH commands available in the tpm2-tools and libraries, but not integrated with pkcs11 at the time.
I guess what I could see here is mapping CKA_DERIVE onto the TPM's decrypt value, so when folks send a template down for EC and set CKA_DERIVE = false|true they get the right mapping. Right now thats toggled off of CKA_DECRYPT.
I don't see where I said anything about section 6.3.
pkcs11-base-v2.40-errata01-os-complete: Table 25 "CKA_DECRYPT for all objects of class CKO_PRIVATE_KEY." also says: "CK_TRUE if key supports decryption 9"
pkcs11-curr-v2.40-cs01.pdf section "2.3 Elliptic Curve" "Table 28, Elliptic Curve Mechanisms vs. Functions" shows EC keys do not support decryption.
I don't see where I said anything about section 6.3.
I don't know either :-p For some reason above something pops in about that section in my comment, and I thought it was markdown screwing up the interleaving of replys.
pkcs11-base-v2.40-errata01-os-complete: Table 25 "CKA_DECRYPT for all objects of class CKO_PRIVATE_KEY." also says: "CK_TRUE if key supports decryption 9"
pkcs11-curr-v2.40-cs01.pdf section "2.3 Elliptic Curve" "Table 28, Elliptic Curve Mechanisms vs. Functions" shows EC keys do not support decryption.
Got it, thanks, that's where I was missing the mapping. So I will map CKA_DERIVE to TPM's decrypt flag for EC objects. I'm not sure what I hate more, the TPM spec or the PKCS11 spec.
According to ECDH, I think that CKA_DERIVE is mappped to both encrypt/decrypt, because the real key which is being used is a symmetric key for i.e. AES.
I know folks that have TLS connections established with PKCS11, but I am not sure if they are EC based or not. If @Dvergatal needs something like C_DeriveKey, that's not supported, so we would need to add support for that. We have currently have the ECDH commands available in the tpm2-tools and libraries, but not integrated with pkcs11 at the time.
I'm sorry if i have made some complications:P but ECC isn't rather a new cryptography and from what i see many ppl have switched from RSA to ECC, despite the fact it was succesfully jaibraked i.e. on ps3 by GeoHotz but there was a faulty EC implementation:P sony was using static random value in ECDSA algorithm...
I don't see where I said anything about section 6.3.
I think there is probably to many answers in here right now:P maybe we should move to another topic #661
The CKA_DERIVE says the EC key can derive a secret. The derived secret can be any type of symmetric key or used in some KDF as long as both parties do the same thing. The common use would be an AES key. So the encrypt/decrypt attributes are for the resulting secret key object.
With PKCS11, the derived secret key is returned as a handle to a secret key. Depending on the token and PKCS11 attributes CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, CKA_NEVER_EXTRACTABLE etc, a calling application may or may not be able to read the CKA_VALUE
In the PIV case, I am familiar with, the card can do CKM_ECDH1_COFACTOR_DERIVE which is the same as CKM_ECDH1_DERIVE for the 2 curves the card supports, and the kdf is CKD_NULL. The PIV card also returns the value of the derivation. The secret key object is considered CKA_TOKEN=false and the application can obtain the result in the CKA_VALUE and CKA_VALUE_LEN.
But with TPM, may be more flexible, not allowing the key value to be read, thus forcing a PKCS11 application to have to use the key via PKCS11 mechanisms like CKM_AES_ECB.
The CKA_DERIVE says the EC key can derive a secret. The derived secret can be any type of symmetric key or used in some KDF as long as both parties do the same thing. The common use would be an AES key. So the encrypt/decrypt attributes are for the resulting secret key object.
With PKCS11, the derived secret key is returned as a handle to a secret key. Depending on the token and PKCS11 attributes CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, CKA_NEVER_EXTRACTABLE etc, a calling application may or may not be able to read the CKA_VALUE
In the PIV case, I am familiar with, the card can do CKM_ECDH1_COFACTOR_DERIVE which is the same as CKM_ECDH1_DERIVE for the 2 curves the card supports, and the kdf is CKD_NULL. The PIV card also returns the value of the derivation. The secret key object is considered CKA_TOKEN=false and the application can obtain the result in the CKA_VALUE and CKA_VALUE_LEN.
But with TPM, may be more flexible, not allowing the key value to be read, thus forcing a PKCS11 application to have to use the key via PKCS11 mechanisms like CKM_AES_ECB.
The derived secret is given out to the client application even in the TPM model, for two reasons:
The derived secret is given out to the client application even in the TPM model, for two reasons:
1. The TPM sucks at bulk encryption 2. Most TPMs do not support symmetric encryption
Could it be done depending on the TPM? I don't know how about others but i.e. mine SLB 9670VQ2.0 Infineon supports AES. @PeterHuewe Btw. i see that there is this * sign under AES, but i do not see any more information.
The derived secret is given out to the client application even in the TPM model, for two reasons:
1. The TPM sucks at bulk encryption 2. Most TPMs do not support symmetric encryption
Could it be done depending on the TPM? I don't know how about others but i.e. mine SLB 9670VQ2.0 Infineon supports AES.
In theory yes, but you wouldn't gain anything. Deriving the secret, the secret would end up in the client application and then you would have to reseal that key into the TPM. At that point, might as well just leave the key with the application.
Most of the derived keys, IIUC, are used for like session encryption, and bulk AES operations with the TPM would be sloooow.
Ahhh ok. I have forgotten that symmetric encryption is to slow with tpm. So it should be done some other way. I dunno if pkcs11 api should use it instead, but this is a special case for the TPM case.
Ahhh ok. I have forgotten that symmetric encryption is to slow with tpm. So it should be done some other way. I dunno if pkcs11 api should use it instead, but this is a special case for the TPM case.
You would still use it via the OpenSSL API. I would need to return the object handle via C_DeriveKey, that references an object with CKA_LOCAL=false. You would then use that object via C_Encrypt/Decrypt APIs, which would just map to openssl over the TPM.
I have a few questions on whether or not that key should persist, I would imagine not because if the application crashes, it would leave a potential session key lingering around in the DB. @dengert do you know those details?
It should not persist as it is only a temporary key, which is being generated for the time of session. It is nearly the same as it is in WPA2-PSK with 4way handshake where key is also generated for the session time.
Oh duh, CKA_TOKEN=false, not on token, thus not persisted in db. CKA_LOCAL=false as well, as it wasn't generated on token.
Hmmm CKA_TOKEN=false because not available from the token. CKA_LOCAL i don't know. Maybe @dengert can confirm.
Btw. these parameters should be the same as in RSA encryption for shared key.
Hmmm CKA_TOKEN=false because not available from the token. CKA_LOCAL i don't know. Maybe @dengert can confirm.
More of a statement than a question, the spec says:
Attribute | Type | Description |
---|---|---|
CKA_LOCAL | CK_BBOOL | CK_TRUE only if key was either generated locally (i.e., on the token) with a C_GenerateKey or C_GenerateKeyPair call created with a C_CopyObject call as a copy of a key which had its CKA_LOCAL attribute set to CK_TRUE |
Btw. these parameters should be the same as in RSA encryption for shared key.
RSA can have encrypt/decrypt set as well.
Yes RSA has encrypt/decrypt but there is completly different scheme. Created shared key is being encrypted with RSA public key than owner of private key decrypts this shared key. For ECDH shared key is being derived according to this pattern:
The shared secret calculated by both parties is equal, because
And because:
Legend: - is our shared secret, but it still needs to be derived by hash function. G - generator point (fixed constant, a base point on the EC) d - private key (integer) Q - public key (point)
P.S. I'm sorry for pasting it like this, i would do it much better, but i don't know if i can write here in latex. Now it looks much better:P
P.S.2 @dengert said about ephemeral keys, these keys are being used in a ECDH variant called ECDHE (which i think is not supported by TPM) and another algorithm ECMQV (which is definitlely not supported, due to some stupid certicom pattents, by the TPM).
P.S.3 According to the parameter description, which you have pasted, i would also set CKA_LOCAL=false, because as i said earlier this is just a temporary shared key. Not a token object, but just for the session. Btw. i have just now noticed that @dengert has already written that CKA_TOKEN=false :P
OS: Rockchip modified Buildroot 2018-rc3 (opensc 0.20.0) tpm2-tss: 3.0.1 (tarball) tpm2-pkcs11: 1.5.0 (tarball) tpm2-abrmd: 2.3.3 (tarball) Token initialized with pkcs11-tool with label foo
With RSA key type all is working .
Token supported mechanism: