PKCS11 key derivation with CMAC

655 Views Asked by At

I would like to know if it's possible to make a key derivation using AES_CMAC mechanism.

I have an AES master key (key) and I want to generate an AES key : key2 = AES_CMAC(key, data). And ofcourse I want to get only key2 holder, not the value.

when I do like this :

public long derive_key(long key, byte[] data, String label) {
         long p_key = -1L;
         CK_MECHANISM mec = new CK_MECHANISM();
         mec.mechanism = PKCS11Constants.CKM_AES_CMAC;
         SecretKey keyTemplate = new AESSecretKey();
         
         fill(keyTemplate, label);
         ((AESSecretKey) keyTemplate).getValueLen().setLongValue(16L);
         ((AESSecretKey) keyTemplate).getValue().setByteArrayValue(data);
         
         CK_ATTRIBUTE[] attr = iaik.pkcs.pkcs11.objects.Object.getSetAttributes(keyTemplate);
         return cryptoki.C_DeriveKey(ckiSession, mec, key, attr, true);

I get CKR_MECHANISM_INVALID error.

And I can't use cryptoki.C_Sign(...) because it outputs the key value.

Thank you!

2

There are 2 best solutions below

0
On

PKCS#11 does define CKM_SP800-108_COUNTER_KDF (and _FEEDBACK_KDF and DOUBLE_PIPELINE_KDF), which does allow you to use AES_CMAC as the underlying algorithm used. Does that meet your needs? There may be other key derivation mechanisms that may let you use CMAC as well.

But a more general question is what are you trying to achieve. Typically derivation is done following the requirements of a larger scheme with additional requirements. If you are requesting CMAC specifically, i suspect you have other requirements to meet?

1
On

The CKM_AES_CMAC mechanism cannot be used for key derivation (see table here).

In my opinion it is not possible to implement CMAC key derivation via standard PKCS#11 mechanisms without exposing any intermediate result (see below for a method which leaks several intermediate results to SW).

Given how CMAC works you have no way to perform the sub-key derivation (conditional XOR and bitwise shift) and last input block tweaking.

In my opinion you have the following options:

  • use another key derivation algorithm

  • have this mechanism implemented as a custom code inside HSM (see e.g. here)

  • use another technology (e.g. custom smartcard)

Good luck with your project!


Theoretically, if you would not mind exposing E(k,0), sub-keys and one intermediate result in SW you could:

  • calculate E(k,0) via CKM_AES_ECB

  • compute the sub-keys in SW

  • compute CBC-MAC of input data blocks m_{1}..m_{n-1} via CKM_AES_MAC

  • tweak the last input data block m_{n} with the appropriate sub-key (and ISO 9797-1 Padding Method 2 if block is incomplete) in SW

  • use CKM_AES_CBC_ENCRYPT_DATA with IV equal to the computed CBC-MAC and data equal to the tweaked last block to derive the key

Do not do that! (although it is probably better than doing it all in SW).

Disclaimer: I am no crypto expert so please do validate my thoughts.