Testing the patches

Some CryptokiX tokens, obtained combining some of the available patches, has been tested against some wrap and decrypt attacks. As you can see from the results, every patch blocks only one of the attacks, so to obtain a secure (with respect to the class of attacks considered) token you must enable all the three patches.

Attacks

Three simple wrap and decrypt attacks have been used to test the patches implemented in CryptokiX.

The simplest one uses a key whose wrap and decrypt attributes are set
(wrap_and_decrypt_conflict):

h_myKey = GenerateKey();
SetAttributes(h_myKey, {decrypt => true, wrap => true});
wrapped = WrapKey(h_myKey, h_mySuperSecretKey);
theSuperSecretKey = Decrypt(h_myKey, wrapped);
print ("oops: " + theSuperSecretKey);

The same goal can be achieved generating a wrap-only key, wrapping the wanted key, converting the generated key to a decrypt-only key and finally decrypting the wrapped key to discover its value (wrap_and_decrypt_sticky):

h_myKey = GenerateKey();
SetAttributes(h_myKey, {decrypt => false, wrap => true});
wrapped = WrapKey(h_myKey, h_mySuperSecretKey);
SetAttributes(h_mykey, {wrap => false, decrypt => true});
theSuperSecretKey = Decrypt(h_myKey, wrapped);
print ("oops: " + theSuperSecretKey);

The last variant of this attack generates 8 random bytes (reading them from /dev/random) and unwrap them to obtain two keys whose values are exactly the same (wrapping_format): a wrap-only key and a decrypt-only one.

wrapped = ;
h_decKey = UnwrapKey(h_unwrapKey, wrapped, {decrypt => true, wrap => false});
h_wrapKey = UnwrapKey(h_unwrapKey, wrapped, {decrypt => false, wrap => true});
wrapped = WrapKey(h_myKey, h_mySuperSecretKey);
theSuperSecretKey = Decrypt(h_myKey, wrapped);
print ("oops: " + theSuperSecretKey);

In the following these attacks are used against (CryptokiX) tokens which selectively enable only one of the three available patches. In doing so, we use a utility program called generate_my_super_secret_key which, as you may guess, generate a key labelled ‘SuperSecret’ which is sensitive and stored inside the token: the key is generated as a non-sensitive one, so that the program can print its value to the screen, and then converted to a sensitive key.

$ sudo ./generate_my_super_secret_key MY_PIN
Searching for key labbeled: SuperSecret
Generating mySuperSecretKey {sensitive => false, encrypt => true, decrypt => true, label => 'SuperSecret'}
The key value is: 50891f2f7a487bc3
Make mySuperSecretKey to be a sensitive (secret) key

Testing a “vanilla” openCryptoki token

First of all, note that the “vanilla” opencryptoki token (obtained by giving no option to the configure script during the installation process) is vulnerable to all the attacks above:

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
Wrapping mySuperSecretKey with myKey
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
Unwrap the random byte stream to obtain wrapKey {decrypt => false, wrap => true}
Wrapping mySuperSecrteKey under wrapKey
Decrypt the wrapped key using decKey
oops: 50891f2f7a487bc3

Conflicting attributes

Enabling the conflicting attributes patch (running the configure script with the options --enable-conflict-check --enable-debug), only the first attack will be blocked. The debug messages show that the error is due to some conflicting attributes, indeed the program tries to generate a key with both decrypt and wrap attributes set.

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
ERROR swtok ../common/key.c:1308 Conflicting attributes detected
ERROR swtok ../common/obj_mgr.c:813 Object Mgr Create Skeleton failed
ERROR swtok ../common/key_mgr.c:441 Object Mgr Create Skeleton failed
ERROR swtok ../common/new_host.c:3922 Key Generation failed
wrap_and_decrypt_conflict.c:70 C_GenerateKey () exited with error 209: 

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
Unwrap the random byte stream to obtain wrapKey {decrypt => false, wrap => true}
Wrapping mySuperSecrteKey under wrapKey
Decrypt the wrapped key using decKey
oops: 50891f2f7a487bc3

Sticky attributes

With a token implementing only the sticky attributes patch, the wrap_and_decrypt_sticky attack fails while the other are still successful (run configure with the options --enable-sticky-attributes --enable-debug):

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
Wrapping mySuperSecretKey with myKey
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
ERROR swtok ../common/key.c:1398 Attempt to modify a sticky attribute detected
ERROR swtok ../common/object.c:864 Check Required Attributes Failed
ERROR swtok ../common/obj_mgr.c:2080 Object Set Attribute Values Failed
ERROR swtok ../common/new_host.c:2083 Object Set Attribute Values Failed
Cannot change myKey to a decrypting key: 16

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
Unwrap the random byte stream to obtain wrapKey {decrypt => false, wrap => true}
Wrapping mySuperSecrteKey under wrapKey
Decrypt the wrapped key using decKey
oops: 50891f2f7a487bc3

Wrapping format

To prevent the wrapping_format attack the token has to keep track of a key’s template when wrapping it, and checks that the same one is given when unwrapping it. The following are the results of the attacks on a token implementing only the wrapping formats patch (configure the token with the options --enable-wrap-format and --enable-debug):

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
Wrapping mySuperSecretKey with myKey
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
Decrypt the wrapped key using myKey
oops: 50891f2f7a487bc3

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
ERROR swtok ../common/key_mgr.c:1440 Template Inconsistent
ERROR swtok ../common/new_host.c:4170 Unwrap Key Failed
Cannot unwrap a random byte-stream to obtain decKey: 209

Detecting multiple attacks

We are not showing the results for all the possible combination of the patches. Consider for example a CryptokiX token implementing the conflicting attributes and sticky attributes patches. It will be able to detect the wrap_and_decrypt_* attacks, but it will still be vulnerable to the wrapping_format one:

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
ERROR swtok ../common/key.c:1308 Conflicting attributes detected
ERROR swtok ../common/obj_mgr.c:813 Object Mgr Create Skeleton failed
ERROR swtok ../common/key_mgr.c:441 Object Mgr Create Skeleton failed
ERROR swtok ../common/new_host.c:3922 Key Generation failed
wrap_and_decrypt_conflict.c:70 C_GenerateKey () exited with error 209: 

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
ERROR swtok ../common/key.c:1398 Attempt to modify a sticky attribute detected
ERROR swtok ../common/object.c:864 Check Required Attributes Failed
ERROR swtok ../common/obj_mgr.c:2080 Object Set Attribute Values Failed
ERROR swtok ../common/new_host.c:2083 Object Set Attribute Values Failed
Cannot change myKey to a decrypting key: 16

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
Unwrap the random byte stream to obtain wrapKey {decrypt => false, wrap => true}
Wrapping mySuperSecrteKey under wrapKey
Decrypt the wrapped key using decKey
oops: 50891f2f7a487bc3

A secure token

In order to be fully protected from this class of attacks, all the three patches must be enabled together (running the configure script with the options --enable-conflict-check --enable-sticky-attributes --enable-wrap-format).

$ sudo ./wrap_and_decrypt_conflict MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => true, wrap => true}
ERROR swtok ../common/key.c:1308 Conflicting attributes detected
ERROR swtok ../common/obj_mgr.c:813 Object Mgr Create Skeleton failed
ERROR swtok ../common/key_mgr.c:441 Object Mgr Create Skeleton failed
ERROR swtok ../common/new_host.c:3922 Key Generation failed
wrap_and_decrypt_conflict.c:70 C_GenerateKey () exited with error 209: 

$ sudo ./wrap_and_decrypt_sticky MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating myKey {decrypt => false, wrap => true}
Wrapping mySuperSecretKey with myKey
Changing myKey to a decrypt key {wrap => false, decrypt => true}
ERROR swtok ../common/key.c:1398 Attempt to modify a sticky attribute detected
ERROR swtok ../common/object.c:864 Check Required Attributes Failed
ERROR swtok ../common/obj_mgr.c:2080 Object Set Attribute Values Failed
ERROR swtok ../common/new_host.c:2083 Object Set Attribute Values Failed
Cannot change myKey to a decrypting key: 16

$ sudo ./wrapping_format MY_PIN
Searching for key labbeled: SuperSecret
Found mySuperSecretKey in the token
Generating unwrapKey {unwrap => true}
Unwrap the random byte stream to obtain decKey {decrypt => true, wrap => false}
ERROR swtok ../common/key_mgr.c:1440 Template Inconsistent
ERROR swtok ../common/new_host.c:4170 Unwrap Key Failed
Cannot unwrap a random byte-stream to obtain decKey: 209