Problem importing AES 128 key

I try to import a 16bytes AES key:

openssl rand -out aes_key.bin 16
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -l --pin xxxxx --write-object aes_key.bin --type secrkey --key-type AES:16 --id 11 --label “MyAESKey”
Using slot 0 with a present token (0x0)
error: PKCS11 function C_CreateObject failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

Looks like what I want to do is basic, I don’t know what I’m missing, do you need full logs?

Thanks

The HSM does not allow import of sensitive key material in plain for security reasons. Sensitive key material would traverse several layers in the application and operating system with the risk of unwanted disclosure.

You will need to use a Key Encryption Key for import. The easiest way is to use the importAES.js script from the SmartCard-HSM Workspace. It is contained in the SmartCard-HSM Starterkit:

var aes = new Key();
aes.setComponent(Key.AES, new ByteString("00112233445566778899AABBCCDDEEFF", HEX));

// Use default crypto provider
var crypto = new Crypto();

// Create card access object
var card = new Card(_scsh3.reader);

card.reset(Card.RESET_COLD);

// Create SmartCard-HSM card service
var sc = new SmartCardHSM(card);

// Attach key store
var ks = new HSMKeyStore(sc);

// Initialize with key domain
var sci = new SmartCardHSMInitializer(card);
sci.setKeyDomains(1);
sci.initialize();

// Create DKEK domain with 00.00 DKEK
sc.createDKEKKeyDomain(0, 1);
var share = new ByteString("0000000000000000000000000000000000000000000000000000000000000000", HEX);
sc.importKeyShare(0, share);

// Create DKEK encoder and import share
var dkek = new DKEK(crypto);
dkek.importDKEKShare(share);

// Encode AES key into blob
var blob = dkek.encodeAESKey(aes);
dkek.dumpKeyBLOB(blob);

var key = ks.importAESKey("ImportedAESKey", blob, 128);

What the script does is to create a DKEK key domain on the HSM with a known key share of all ‘00’. It then encrypts the plain key value into a suitable key blob which is then imported.

Of course you should either choose a secret DKEK share or clear the DKEK share in the HSM to prevent later export under the known DKEK.

Thanks, is there a way to do it with PKCS11 API and sc-hsm-tool ?

You could do the import with sc-hsm-tool, but for encrypting the key blob you will need to use the Smart Card Shell.

Another question: Why do you want to generate the AES key outside the HSM ?

That defeats the purpose of using a Hardware Security Module, as you never know how many copies of the key exist.

You typically use a HSM, because you want to control the full key life-cycle, from creation to deletion. Of course you want a secure backup and key migration, that is what key domains are for.

I usually compare cryptographic keys to radioactive material. You never want to touch that by hand, which is why you handle radioactive material in a hot-cell. A HSM is for keys, what a hot-cell is for radioactive material, a safe containment.

I tried the scsh way and it works! Thanks

On why I don’t generate the key in the HSM, it’s a long story.
I use AES-ECB to generate a unique password based on some device serial number.
One copy of the key should be in factory (abroad, third party)
One copy of the key should be in a cloud provider (AWS/Azure/…)
But in the past, I used Luna Safenet HSM for this and could not have the right level of interoperability between the vendors (AWS cloud HSM, Azure HSM, Safenet).
Basically, you generate the key in your SafeNet HSM and are stuck with it; you can’t back it up and install it in another vendor or a cloud provider’s HSM you can only use Safenet HSM.

So what I’m experimenting with Nitrokey is to generate the key outside of the HSM and use the HSM to distribute the key to my factory, so it’s safe here. And if I need to change of HSM vendors (like pushing the key to AWS cloud HSM, I can do it).