From 171aa6fa5fcd1189cbd2e71dd162b677ba36180b Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@dhcp-16-206.sjc.redhat.com>
Date: Fri, 24 Mar 2017 15:56:17 -0700
Subject: [PATCH] SCP03 support for g&d sc 7 card.

This allows the use of the g&d 7 card.
This will require the following:

1. An out of band method is needed to generate an AES based master key.
We do not as of yet have support with tkstool for this:

Ex:

/usr/lib64/nss/unsupported-tools/symkeyutil -d . -K -n new_master_aes -t aes -s 16

2. There are some new config params that can be adjusted to support either the 6.0 or 7.0 cards:

Ex:

tks.defKeySet._005=## tks.prot3   , protocol 3 specific settings
tks.defKeySet._006=## divers= emv,visa2 : Values for the master key case, or > version one.
tks.defKeySet._007=## diversVer1 = emv,visa2, or none. This is for developer or version one keyset
tks.defKeySet._008=## devKeyType = DES3or AES. This is for the key type of developer or version one keys.
tks.defKeySet._009=## masterKeyType = DES3 or AES. This is for the type of key for the master key.
tks.defKeySet._010=##
tks.defKeySet._011=## Only supports two tokens now: G&D Smart Cafe 6 and Smart Cafe 7, use these exact settings
tks.defKeySet._013=## Smart Cafe 6 settings:
tks.defKeySet._014=##    tks.defKeySet.prot3.divers=emv
tks.defKeySet._015=##    tks.defKeySet.prot3.diversVer1Keys=emv
tks.defKeySet._016=##    tks.defKeySet.prot3.devKeyType=DES3
tks.defKeySet._017=##    tks.defKeySet.prot3.masterKeyType=DES3
tks.defKeySet._018=##Smart Cafe 7 settings:
tks.defKeySet._019=##    tks.defKeySet.prot3.divers=none
tks.defKeySet._020=##    tks.defKeySet.prot3.diversVer1Keys=none
tks.defKeySet._021=##    tks.defKeySet.prot3.devKeyType=AES
tks.defKeySet._022=##    tks.defKeySet.prot3.masterKeyType=AES
tks.defKeySet._023=##
tks.defKeySet._024=##
---
 .../src/com/netscape/cms/servlet/tks/GPParams.java |  21 ++++
 .../netscape/cms/servlet/tks/NistSP800_108KDF.java | 114 +++++----------------
 .../cms/servlet/tks/SecureChannelProtocol.java     | 107 ++++++++++++++-----
 .../com/netscape/cms/servlet/tks/TokenServlet.java |  20 ++++
 base/tks/shared/conf/CS.cfg                        |  24 +++++
 base/tps/shared/conf/CS.cfg                        |   2 +-
 6 files changed, 174 insertions(+), 114 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/GPParams.java b/base/server/cms/src/com/netscape/cms/servlet/tks/GPParams.java
index f16481b..bda4e66 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/GPParams.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/GPParams.java
@@ -30,6 +30,8 @@ public class GPParams {
     public static String DIVER_NONE = "none";
     public static String DIVER_VISA2 = "visa2";
     public static String NIST_SP800 = "nistsp_800";
+    public static String AES = "AES";
+    public static String DES3 ="DES3";
 
     public GPParams() {
     }
@@ -39,6 +41,25 @@ public class GPParams {
     //Diversification scheme for just version one or developer keys
     private String version1DiversificationScheme;
 
+    private String devKeyType;
+    private String masterKeyType;
+
+    public String getDevKeyType() {
+        return devKeyType;
+    }
+
+    public String getMasterKeyType() {
+        return masterKeyType;
+    }
+
+    public void setDevKeyType(String newType) {
+        devKeyType = newType;
+    }
+
+    public void setMasterKeyType(String newType) {
+        masterKeyType = newType;
+    }
+
     public boolean isDiversEmv() {
         if (DIVER_EMV.equalsIgnoreCase(diversificationScheme))
             return true;
diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java b/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
index ad4a370..1f2c1b5 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
@@ -461,8 +461,8 @@ public class NistSP800_108KDF extends KDF {
     // Collection of informal invocations of api used to create various session keys
     // Done with test data.
     public static void main(String[] args) {
-/*
-      Options options = new Options();
+
+  /*   Options options = new Options();
 
         options.addOption("d", true, "Directory for tokendb");
 
@@ -474,15 +474,20 @@ public class NistSP800_108KDF extends KDF {
                 (byte) 0x4f };
 
         byte test_cuid[] = { (byte) 0x47,(byte) 0x90,(byte)0x50,(byte)0x37,(byte)0x72,(byte)0x71,(byte)0x97,(byte)0x00,(byte)0x74,(byte)0xA9 };
-        byte test_kdd[] = { (byte)0x00, (byte)0x00, (byte)0x50, (byte)0x24,(byte) 0x97,(byte) 0x00,(byte) 0x74, (byte) 0xA9, (byte)0x72,(byte)0x71 };
+        byte test_kdd[] = { 0x00 ,0x00, 0x04 ,(byte)0x47 ,0x00 ,(byte)0x1F ,0x00 ,(byte)0x46 ,(byte)0xA7 ,0x02 };
+
 
+        byte test_host_challenge[]  = { (byte)0x2F ,(byte)0xB7 ,(byte)0x9F ,(byte)0xB7 ,(byte)0x04 ,(byte)0xFA ,(byte)0x60 ,(byte)0xE8 };
+        byte test_card_challenge[]  = { (byte)0xB9,(byte) 0x69 ,(byte)0xB0 ,(byte)0xCA ,(byte)0x37 ,(byte)0x27 ,(byte)0x2F ,(byte)0x89};
 
-        byte test_host_challenge[]  = { 0x06 ,(byte)0xA4 ,0x46 ,0x57 ,(byte) 0x8B ,0x65 ,0x48 ,0x51 };
-        byte test_card_challenge[]  = { (byte) 0xAD ,(byte) 0x2E ,(byte)0xD0 ,0x1E ,0x7C ,0x2D ,0x0C ,0x6F};
+        byte test_host_challenge_1[] = { (byte)0xD9 ,(byte)0xA0 ,(byte)0x0E ,(byte)0x36 ,(byte)0x69 ,(byte)0x67 ,(byte)0xFA ,(byte)0xFB };
+        byte test_card_challenge_1[] = {(byte)0x08 ,(byte) 0xF3 ,(byte) 0xE2 ,(byte)0xC3 ,0x72 ,(byte)0xF0 ,(byte)0xBE ,0x26 };
 
-        byte test_key_info[] = { (byte) 0x02,(byte) 03,(byte) 00 };
+        byte test_key_info[] = { (byte) 0x01,(byte) 03,(byte) 70 };
         byte test_old_key_info[] = {0x01,0x03,0x00};
 
+        byte test_sequence_counter[] = { 0x00 ,0x00 ,0x06 };
+
         try {
             CommandLineParser parser = new DefaultParser();
             CommandLine cmd = parser.parse(options, args);
@@ -500,11 +505,6 @@ public class NistSP800_108KDF extends KDF {
         SymmetricKey macKey = null;
         SymmetricKey kekKey = null;
 
-        SymmetricKey putEncKey = null;
-        SymmetricKey putMacKey = null;
-        SymmetricKey putKekKey = null;
-
-        SymmetricKey tempKey = null;
 
         try {
             CryptoManager.initialize(db_dir);
@@ -512,113 +512,55 @@ public class NistSP800_108KDF extends KDF {
 
             CryptoToken token = cm.getInternalKeyStorageToken();
 
-           KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.AES);
-
-            SymmetricKey.Usage usages[] = new SymmetricKey.Usage[4];
-            usages[0] = SymmetricKey.Usage.WRAP;
-            usages[1] = SymmetricKey.Usage.UNWRAP;
-            usages[2] = SymmetricKey.Usage.ENCRYPT;
-            usages[3] = SymmetricKey.Usage.DECRYPT;
-
-            kg.setKeyUsages(usages);
-            kg.temporaryKeys(true);
-            kg.initialize(128);
-            tempKey = kg.generate();
-
-
-            Cipher encryptor = token.getCipherContext(EncryptionAlgorithm.AES_128_CBC);
-
-            int ivLength = EncryptionAlgorithm.AES_128_CBC.getIVLength();
-            byte[] iv = null;
-
-            if (ivLength > 0) {
-                iv = new byte[ivLength]; // all zeroes
-            }
-
-            encryptor.initEncrypt(tempKey, new IVParameterSpec(iv));
-            byte[] wrappedKey = encryptor.doFinal(devKey);
-
-            KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.AES_CBC);
-            keyWrap.initUnwrap(tempKey, new IVParameterSpec(iv));
-
-            encKey = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES3, 16);
-            macKey = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES3, 16);
-            kekKey = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES3, 16);
-
             String transportName = "TPS-dhcp-16-206.sjc.redhat.com-8443 sharedSecret";
             SecureChannelProtocol prot = new SecureChannelProtocol(SecureChannelProtocol.PROTOCOL_THREE);
 
             SymmetricKey masterKey =  SecureChannelProtocol.getSymKeyByName(token,"new_master");
 
             GPParams params = new GPParams();
-            params.setVersion1DiversificationScheme("visa2");
-            params.setDiversificationScheme("visa2");
-
-            putEncKey = prot.computeSessionKey_SCP03("internal", "new_master",test_old_key_info,
-                    SecureChannelProtocol.encType, devKey, "defKeySet", test_cuid, test_kdd, null, null,
-                    transportName,params);
-
-            putMacKey = prot.computeSessionKey_SCP03("internal", "new_master",test_old_key_info,
-                    SecureChannelProtocol.macType, devKey, "defKeySet", test_cuid, test_kdd, null, null,
-                    transportName,params);
-
-            putKekKey = prot.computeSessionKey_SCP03("internal", "new_master",test_old_key_info,
-                    SecureChannelProtocol.kekType, devKey, "defKeySet", test_cuid, test_kdd, null, null,
-                    transportName,params);
+            params.setVersion1DiversificationScheme("emv");
+            params.setDiversificationScheme("emv");
+            params.setDevKeyType(GPParams.AES);
+            params.setMasterKeyType(GPParams.AES);
 
             //create test session keys
-            encKey = prot.computeSessionKey_SCP03("internal", "new_master",test_key_info,
-                    SecureChannelProtocol.encType, devKey, "defKeySet", test_cuid, test_kdd, test_host_challenge, test_card_challenge,
+            encKey = prot.computeSessionKey_SCP03("internal", "#01#03#70",test_key_info,
+                    SecureChannelProtocol.encType, devKey, "defKeySet", test_cuid, test_kdd, test_host_challenge_1, test_card_challenge_1,
                     transportName,params);
 
-            macKey = prot.computeSessionKey_SCP03("internal", "new_master",test_key_info,
-                    SecureChannelProtocol.macType,devKey,"defKeySet", test_cuid, test_kdd, test_host_challenge, test_card_challenge,
+            macKey = prot.computeSessionKey_SCP03("internal", "#01#03#70",test_key_info,
+                    SecureChannelProtocol.macType,devKey,"defKeySet", test_cuid, test_kdd, test_host_challenge_1, test_card_challenge_1,
                     transportName,params);
 
-            kekKey = prot.computeSessionKey_SCP03("internal", "new_master",test_key_info,
-                    SecureChannelProtocol.kekType, devKey, "defKeySet", test_cuid, test_kdd, test_host_challenge, test_card_challenge,
+            kekKey = prot.computeSessionKey_SCP03("internal", "#01#03#70",test_key_info,
+                    SecureChannelProtocol.kekType, devKey, "defKeySet", test_cuid, test_kdd, test_host_challenge_1, test_card_challenge_1,
                     transportName,params);
 
             System.out.println("masterKey: " + masterKey);
 
             System.out.println("\n");
 
-            SecureChannelProtocol.debugByteArray(putEncKey.getKeyData(), " derived putEnc session key data: ");
-            SecureChannelProtocol.debugByteArray(putMacKey.getKeyData(), " derived putMac session key data: ");
-            SecureChannelProtocol.debugByteArray(putKekKey.getKeyData(), " derived putKek session key data: ");
-
-            System.out.println("\n");
 
             SecureChannelProtocol.debugByteArray(encKey.getKeyData(), " derived enc session key data: ");
             SecureChannelProtocol.debugByteArray(macKey.getKeyData(), " derived mac session key data: ");
             SecureChannelProtocol.debugByteArray(kekKey.getKeyData(), " derived kek session key data: ");
 
-            ByteArrayOutputStream contextStream = new ByteArrayOutputStream();
-            try {
-                contextStream.write(test_host_challenge);
-                contextStream.write(test_card_challenge);
-            } catch (IOException e) {
-            }
-
-            StandardKDF standard = new StandardKDF(prot);
 
             ByteArrayOutputStream testContext = new ByteArrayOutputStream();
 
-            testContext.write(test_host_challenge);
-            testContext.write(test_card_challenge);
+            testContext.write(test_host_challenge_1);
+            testContext.write(test_card_challenge_1);
+
+            SecureChannelProtocol.debugByteArray(testContext.toByteArray(), "Test context bytes: ");
 
-            NistSP800_108KDF  nistKdf = new NistSP800_108KDF(prot);
 
-            byte[] finalEncBytes = nistKdf.kdf_AES_CMAC_SCP03(encKey, testContext.toByteArray(), (byte) 0x04, 16);
-            byte[] finalMacBytes = nistKdf.kdf_AES_CMAC_SCP03(macKey, testContext.toByteArray(), (byte) 0x06, 16);
+            NistSP800_108KDF  nistKdf = new NistSP800_108KDF(prot);
 
-            SymmetricKey sEnc  = prot.unwrapAESSymKeyOnToken(token, finalEncBytes, false);
-            SymmetricKey sMac  = macKey = prot.unwrapAESSymKeyOnToken(token, finalMacBytes, false);
 
-            byte[] cardCryptoVerify = nistKdf.kdf_AES_CMAC_SCP03(sMac, testContext.toByteArray(), CARD_CRYPTO_KDF_CONSTANT, 8);
+            byte[] cardCryptoVerify = nistKdf.kdf_AES_CMAC_SCP03(macKey, testContext.toByteArray(), CARD_CRYPTO_KDF_CONSTANT, 8);
             SecureChannelProtocol.debugByteArray(cardCryptoVerify, " calculated card cryptogram");
 
-            byte[] hostCrypto = nistKdf.kdf_AES_CMAC_SCP03(sMac, testContext.toByteArray(), HOST_CRYPTO_KDF_CONSTANT, 8);
+            byte[] hostCrypto = nistKdf.kdf_AES_CMAC_SCP03(macKey, testContext.toByteArray(), HOST_CRYPTO_KDF_CONSTANT, 8);
             SecureChannelProtocol.debugByteArray(hostCrypto, " calculated host cryptogram");
 
         } catch (AlreadyInitializedException e) {
diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
index 371e734..ef0c61b 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
@@ -36,6 +36,7 @@ public class SecureChannelProtocol {
     static String sharedSecretKeyName = null;
     static String masterKeyPrefix = null;
 
+    static final int DEF_AES_KEYLENGTH = 16;
     static final int KEYLENGTH = 16;
     static final int PREFIXLENGHT = 128;
     static final int DES2_LENGTH = 16;
@@ -288,7 +289,9 @@ public class SecureChannelProtocol {
 
         {
             String finalKeyType = keyType;
-            SymmetricKey devSymKey = returnDeveloperSymKey(token, finalKeyType, keySet, devKeyArray);
+            String devKeyType = params.getDevKeyType();
+            CMS.debug(method + " Developer key set case: incoming dev key type: " + devKeyType);
+            SymmetricKey devSymKey = returnDeveloperSymKey(token, finalKeyType, keySet, devKeyArray,devKeyType);
 
             StandardKDF standard = new StandardKDF(this);
             SymmetricKey divKey = null;
@@ -297,22 +300,31 @@ public class SecureChannelProtocol {
 
             //Consult the config to determine with diversification method to use.
             if (params.isVer1DiversNone()) {
+                CMS.debug(method + " No diversifcation requested. ");
                 noDivers = true;
             } else if (params.isVer1DiversEmv()) {
+                CMS.debug(method + " EMV diversification requested. ");
                 keyDiversified = KDF.getDiversificationData_EMV(xKDD, keyType);
             } else if (params.isVer1DiversVisa2()) {
+                CMS.debug(method + " Visa2 diversification requested.");
                 keyDiversified = KDF.getDiversificationData_VISA2(xKDD, keyType);
             } else {
                 throw new EBaseException(method + " Invalid diversification method!");
             }
 
             //Obtain the card key,it may just be the raw developer key
-            if (noDivers == true) {
-                divKey = unwrapAESSymKeyOnToken(token, devKeyArray, false);
+            if (noDivers == true || GPParams.AES.equalsIgnoreCase(devKeyType)) {
+                divKey = devSymKey;
             } else {
 
                 // The g&d calls for computing the aes card key with DES, it will then be treated as aes
-                divKey = standard.computeCardKey_SCP03_WithDES3(devSymKey, keyDiversified, token);
+                // Right now if the dev key type is AES, we do not support any diversification
+
+                if (GPParams.DES3.equalsIgnoreCase(devKeyType)) {
+                    divKey = standard.computeCardKey_SCP03_WithDES3(devSymKey, keyDiversified, token);
+                } else {
+                    throw new EBaseException(method + " Invalid devolper key type. Does not support diversification: "+ devKeyType);
+                }
             }
 
             NistSP800_108KDF nistKdf = new NistSP800_108KDF(this);
@@ -338,22 +350,35 @@ public class SecureChannelProtocol {
 
             masterKey = getSymKeyByName(token, keyNameStr);
 
+            String masterKeyType = params.getMasterKeyType();
+
+            CMS.debug(method + " Master key case: requested master key type: " + masterKeyType);
+
             StandardKDF standard = new StandardKDF(this);
 
             byte[] keyDiversified = null;
 
             if (params.isDiversNone()) {
-                throw new EBaseException(method + " No diversification requested in master key mode. Aborting...");
+                if (GPParams.AES.equalsIgnoreCase(masterKeyType)) {
+                    CMS.debug(method + " Master key case: no diversification requested: With master key type of AES ");
+                }
+                else {
+                    throw new EBaseException(method + " No diversification requested in master key mode. With master key type of DES3: Aborting...");
+                }
             } //Allow choice of emv or standard diversification
             else if (params.isDiversEmv()) {
                 keyDiversified = KDF.getDiversificationData_EMV(xKDD, keyType);
             } else if (params.isDiversVisa2()) {
                 keyDiversified = KDF.getDiversificationData_VISA2(xKDD, keyType);
             }
-
             SymmetricKey divKey = null;
 
-            divKey = standard.computeCardKey_SCP03_WithDES3(masterKey, keyDiversified, token);
+            if(GPParams.AES.equalsIgnoreCase(masterKeyType)) {
+                CMS.debug(method + " master key case with AES type.");
+                divKey = masterKey;
+            } else {
+                divKey = standard.computeCardKey_SCP03_WithDES3(masterKey, keyDiversified, token);
+            }
 
             NistSP800_108KDF nistKdf = new NistSP800_108KDF(this);
             // The kek session key does not call for derivation
@@ -488,11 +513,11 @@ public class SecureChannelProtocol {
 
             String finalKeyType = keyType;
 
-            SymmetricKey devSymKey = returnDeveloperSymKey(token, finalKeyType, keySet, devKeyArray);
+            SymmetricKey devSymKey = returnDeveloperSymKey(token, finalKeyType, keySet, devKeyArray,"DES3");
 
             // Create the auth with is the same as enc, might need it later.
             if (keyType.equals(encType)) {
-                returnDeveloperSymKey(token, authType, keySet, devKeyArray);
+                returnDeveloperSymKey(token, authType, keySet, devKeyArray,"DES3");
             }
 
             if (noDerive == true) {
@@ -672,14 +697,25 @@ public class SecureChannelProtocol {
     From that point it is a simple matter of retrieving  the desired key from the token.
     No security advantage is implied or desired here.
     */
-    public SymmetricKey returnDeveloperSymKey(CryptoToken token, String keyType, String keySet, byte[] inputKeyArray)
+    public SymmetricKey returnDeveloperSymKey(CryptoToken token, String keyType, String keySet, byte[] inputKeyArray, String keyAlg)
             throws EBaseException {
 
         SymmetricKey devKey = null;
 
         String method = "SecureChannelProtocol.returnDeveloperSymKey:";
 
-        String devKeyName = keySet + "-" + keyType + "Key";
+        boolean isAES = false;
+        String finalAlg = null;
+        if(keyAlg == null) {
+            finalAlg = "DES3";
+        }
+
+        if(keyAlg.equalsIgnoreCase("AES")) {
+            isAES = true;
+            finalAlg = "AES";
+        }
+
+        String devKeyName = keySet + "-" + keyType + "Key"  + "-" + finalAlg;
         CMS.debug(method + " entering.. searching for key: " + devKeyName);
 
         if (token == null || keyType == null || keySet == null) {
@@ -706,22 +742,31 @@ public class SecureChannelProtocol {
 
             CMS.debug(method + " inputKeyArray.length: " + inputLen);
 
-            if (inputLen != DES3_LENGTH && inputLen != DES2_LENGTH) {
-                throw new EBaseException(method + "invalid input key length!");
-            }
+            if (!isAES) {
+                if (inputLen != DES3_LENGTH && inputLen != DES2_LENGTH) {
+                    throw new EBaseException(method + "invalid input key length!");
+                }
+
+                if (inputLen == DES2_LENGTH) {
+                    des3InputKey = new byte[DES3_LENGTH];
+                    System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES2_LENGTH);
+                    System.arraycopy(inputKeyArray, 0, des3InputKey, DES2_LENGTH, EIGHT_BYTES);
+
+                } else {
+                    System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES3_LENGTH);
+                }
+
+                SecureChannelProtocol.debugByteArray(des3InputKey, "Developer key to import: " + keyType + ": ");
 
-            if (inputLen == DES2_LENGTH) {
-                des3InputKey = new byte[DES3_LENGTH];
-                System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES2_LENGTH);
-                System.arraycopy(inputKeyArray, 0, des3InputKey, DES2_LENGTH, EIGHT_BYTES);
+                devKey = unwrapSymKeyOnToken(token, des3InputKey, true);
 
             } else {
-                System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES3_LENGTH);
-            }
 
-            SecureChannelProtocol.debugByteArray(des3InputKey, "Developer key to import: " + keyType + ": ");
+                if(inputLen == DEF_AES_KEYLENGTH) { // support 128 bits for now
+                    devKey = unwrapAESSymKeyOnToken(token, inputKeyArray, true);
+                }
+            }
 
-            devKey = unwrapSymKeyOnToken(token, des3InputKey, true);
             devKey.setNickName(devKeyName);
         } else {
             CMS.debug(method + " Found sym key: " + devKeyName);
@@ -1823,9 +1868,9 @@ public class SecureChannelProtocol {
             //This is the case where we revert to the original developer key set or key set 1
             if (protocol == PROTOCOL_ONE) {
                 CMS.debug(method + " Special case returning to the dev key set (1) for DiversifyKey, protocol 1!");
-                encKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.encType, keySet, null);
-                macKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.macType, keySet, null);
-                kekKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.kekType, keySet, null);
+                encKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.encType, keySet, null,"DES3");
+                macKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.macType, keySet, null,"DES3");
+                kekKey = returnDeveloperSymKey(newToken, SecureChannelProtocol.kekType, keySet, null,"DES3");
             } else if (protocol == PROTOCOL_THREE) {
                 CMS.debug(method + " Special case or returning to the dev key set (or ver 1) for DiversifyKey, protocol 3!");
                 encKey = this.computeSessionKey_SCP03(tokenName, newMasterKeyName, newKeyInfo,
@@ -1920,7 +1965,15 @@ public class SecureChannelProtocol {
 
             CMS.debug(method + " old kek sym key is null");
 
-            old_kek_sym_key = returnDeveloperSymKey(token, SecureChannelProtocol.kekType, keySet, kekKeyArray);
+            String devKeyType = null;
+
+            if(protocol == PROTOCOL_THREE) {
+                devKeyType = params.getDevKeyType();
+            } else {
+                devKeyType = "DES3";
+            }
+
+            old_kek_sym_key = returnDeveloperSymKey(token, SecureChannelProtocol.kekType, keySet, kekKeyArray, devKeyType);
 
             output = createKeySetDataWithSymKeys(newKeyVersion, (byte[]) null,
                     old_kek_sym_key,
@@ -2070,7 +2123,7 @@ public class SecureChannelProtocol {
             throw new EBaseException(method + " Can't compose final output byte array!");
         }
 
-        //SecureChannelProtocol.debugByteArray(output, " Final output to createKeySetData: ");
+        SecureChannelProtocol.debugByteArray(output, " Final output to createKeySetData: ");
         CMS.debug(method + " returning output");
 
         return output;
diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
index 6a17466..fe4aeee 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -3219,6 +3219,26 @@ public class TokenServlet extends CMSServlet {
         params.setVersion1DiversificationScheme(diversVer1Keys);
         CMS.debug(method + " Version 1 keys Divers: " + divers);
 
+        String keyType = null;
+        try {
+            keyType = CMS.getConfigStore().getString(gp3Settings + ".devKeyType","DES3");
+        } catch (EBaseException e) {
+        }
+
+        CMS.debug(method + " devKeyType: " + keyType);
+
+        params.setDevKeyType(keyType);
+
+        try {
+            keyType = CMS.getConfigStore().getString(gp3Settings + ".masterKeyType","DES3");
+        } catch (EBaseException e) {
+        }
+
+        params.setMasterKeyType(keyType);
+
+        CMS.debug(method + " masterKeyType: " + keyType);
+
+
         return params;
     }
 
diff --git a/base/tks/shared/conf/CS.cfg b/base/tks/shared/conf/CS.cfg
index 0eea3e9..45716d2 100644
--- a/base/tks/shared/conf/CS.cfg
+++ b/base/tks/shared/conf/CS.cfg
@@ -340,11 +340,35 @@ tks.defKeySet._001=## Axalto default key set:
 tks.defKeySet._002=##
 tks.defKeySet._003=## tks.defKeySet.mk_mappings.#02#01=<tokenname>:<nickname>
 tks.defKeySet._004=##
+tks.defKeySet._005=## tks.prot3   , protocol 3 specific settings
+tks.defKeySet._006=## divers= emv,visa2 : Values for the master key case, or > version one.
+tks.defKeySet._007=## diversVer1 = emv,visa2, or none. This is for developer or version one keyset
+tks.defKeySet._008=## devKeyType = DES3or AES. This is for the key type of developer or version one keys.
+tks.defKeySet._009=## masterKeyType = DES3 or AES. This is for the type of key for the master key.
+tks.defKeySet._010=##
+tks.defKeySet._011=## Only supports two tokens now: G&D Smart Cafe 6 and Smart Cafe 7, use these exact settings
+tks.defKeySet._013=## Smart Cafe 6 settings:
+tks.defKeySet._014=##    tks.defKeySet.prot3.divers=emv
+tks.defKeySet._015=##    tks.defKeySet.prot3.diversVer1Keys=emv
+tks.defKeySet._016=##    tks.defKeySet.prot3.devKeyType=DES3
+tks.defKeySet._017=##    tks.defKeySet.prot3.masterKeyType=DES3
+tks.defKeySet._018=##Smart Cafe 7 settings:
+tks.defKeySet._019=##    tks.defKeySet.prot3.divers=none
+tks.defKeySet._020=##    tks.defKeySet.prot3.diversVer1Keys=none
+tks.defKeySet._021=##    tks.defKeySet.prot3.devKeyType=AES
+tks.defKeySet._022=##    tks.defKeySet.prot3.masterKeyType=AES
+tks.defKeySet._023=##
+tks.defKeySet._024=##
 tks.defKeySet.auth_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
 tks.defKeySet.mac_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
 tks.defKeySet.kek_key=#40#41#42#43#44#45#46#47#48#49#4a#4b#4c#4d#4e#4f
 tks.defKeySet.nistSP800-108KdfOnKeyVersion=00
 tks.defKeySet.nistSP800-108KdfUseCuidAsKdd=false
+tks.defKeySet.prot3.divers=emv
+tks.defKeySet.prot3.diversVer1Keys=emv
+tks.defKeySet.prot3.devKeyType=DES3
+tks.defKeySet.prot3.masterKeyType=DES3
+
 tks.jForte._000=##
 tks.jForte._001=## SAFLink's jForte default key set:
 tks.jForte._002=##
diff --git a/base/tps/shared/conf/CS.cfg b/base/tps/shared/conf/CS.cfg
index 8d667f5..2d9057a 100644
--- a/base/tps/shared/conf/CS.cfg
+++ b/base/tps/shared/conf/CS.cfg
@@ -10,7 +10,7 @@ applet._001=# applet information
 applet._002=# SAF Key:
 applet._003=# applet.aid.cardmgr_instance=A0000001510000
 applet._004=# Stock RSA,KeyRecover applet : 1.4.58768072.ijc 
-applet._005=# Beta RSA/KeyRecovery/GP211/SCP02 applet : 1.5.558cdcff.ijc
+applet._005=# RSA/KeyRecovery/GP211/SCP02, SCP03 applet : 1.5.558cdcff.ijc
 applet._006=# Use GP211 applet only with SCP02 card
 applet._007=#########################################
 applet.aid.cardmgr_instance=A0000000030000
-- 
2.5.0

