I am writing a demo to generate and store key pair in tpm device on linux (ubuntu) by nss and pkcs#11.
I've added the tpm2-pkcs11 module to nssdb, like:
time@PF2CMPHV:~$ modutil -list -dbdir sql:/home/time/.time/nssdb
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.98
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
2. TPM2_PKCS11
library name: /usr/local/lib/libtpm2_pkcs11.so
uri: pkcs11:library-manufacturer=tpm2-software.github.io;library-description=TPM2.0%20Cryptoki;library-version=1.9
slots: 3 slots attached
status: loaded
slot: time.test
token: time.test
uri: pkcs11:token=time.test;manufacturer=Intel;serial=0000000000000000;model=Intel
slot: time.test.token
token: time.test.token
uri: pkcs11:token=time.test.token;manufacturer=Intel;serial=0000000000000000;model=Intel
slot:
token:
uri: pkcs11:manufacturer=Intel;serial=0000000000000000;model=Intel
Besides, I list the available slots by pkcs11-tool
time@PF2CMPHV:~$ pkcs11-tool --module /usr/local/lib/libtpm2_pkcs11.so --list-slots
Available slots:
Slot 0 (0x1): time.test
token label : time.test
token manufacturer : Intel
token model : Intel
token flags : login required, rng, token initialized, PIN initialized
hardware version : 1.38
firmware version : 244.14
serial num : 0000000000000000
pin min/max : 0/128
Slot 1 (0x2): time.test.token
token label : time.test.token
token manufacturer : Intel
token model : Intel
token flags : login required, rng, token initialized, PIN initialized
hardware version : 1.38
firmware version : 244.14
serial num : 0000000000000000
pin min/max : 0/128
Slot 2 (0x3):
token state: uninitialized
I've initialized pin of token. Then I try to get these token and login by code:
static const char db_dir[] = "sql:/home/time/.time/nssdb";
int InitNSSDatabase() {
SECStatus rv = NSS_Init(db_dir);
if (rv != SECSuccess) {
std::cout << "NSS_Init failed, " << PORT_ErrorToName(PR_GetError()) << std::endl;
return -1;
}
return 0;
}
char USER_PIN[] = "userpin";
int ValidatePin(CK_SLOT_ID slot_id) {
int rtv = 0;
rtv = InitNSSDatabase();
if (rtv != 0) {
return rtv;
}
char module_path[] = "/usr/local/lib/libtpm2_pkcs11.so";
SECMODModule* module = SECMOD_LoadUserModule(module_path, NULL, PR_FALSE);
if (!module) {
std::cout << "SECMOD_LoadUserModule failed, " << PORT_ErrorToString(PR_GetError()) << std::endl;
return -1;
}
PK11SlotInfo* slot_info = nullptr;
PK11SlotList* slot_list = PK11_GetAllTokens(CKM_EC_KEY_PAIR_GEN, PR_TRUE, PR_TRUE, nullptr);
for (PK11SlotListElement* ele = slot_list->head; ele != slot_list->tail; ele = ele->next) {
slot_info = ele->slot;
TokenInfo token_info = GetTokenInfo(slot_info);
token_info.DebugPrint();
if (token_info.module_name == "TPM2_PKCS11") {
break;
}
}
bool need_login = PK11_NeedLogin(slot_info);
std::cout << "need login: " << need_login << std::endl;
std::cout << "is present: " << PK11_IsPresent(slot_info) << std::endl;
// PK11_SetPasswordFunc(pin_func);
SECStatus status = PK11_Authenticate(slot_info, PR_TRUE, nullptr);
if (status != SECSuccess) {
std::cout << "PK11_Authenticate failed: " << PORT_ErrorToName(PR_GetError()) << std::endl;
// return -1;
}
}
Then I got PK11_Authenticate failed: An I/O error occurred during security authorization.
Besides, the current user has tss group. I've tried to chgrp /dev/tpm* to tss, which seems enough to manipulate tpm device, but it not works.
crw-rw---- 1 tss tss 10, 224 Feb 8 13:41 /dev/tpm0
crw-rw---- 1 tss tss 253, 65536 Feb 8 13:41 /dev/tpmrm0