private GPKeySet DeriveSessionKeysSCP01(GPKeySet staticKeys, byte[] host_challenge, byte[] card_challenge) { GPKeySet sessionKeys = new GPKeySet(); byte[] derivationData = new byte[16]; Array.Copy(card_challenge, 4, derivationData, 0, 4); Array.Copy(host_challenge, 0, derivationData, 4, 4); Array.Copy(card_challenge, 0, derivationData, 8, 4); Array.Copy(host_challenge, 4, derivationData, 12, 4); try { //Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding"); foreach (KeySessionType v in KeyTypeList.Values) { if (v == KeySessionType.RMAC) // skip RMAC key { continue; } //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(v)); //GPKey nk = new GPKey(cipher.doFinal(derivationData), Type.DES3); byte[] result = GPCrypto.DoEncrypt_DES3_ECB(staticKeys.GetKeyFor(v).GetEncoded(), derivationData); GPKey nk = new GPKey(result, KeyType.DES3); sessionKeys.SetKey(v, nk); } // KEK is the same sessionKeys.SetKey(KeySessionType.KEK, staticKeys.GetKey(KeySessionType.KEK)); return(sessionKeys); } //catch (NoSuchAlgorithmException e) //{ // throw new IllegalStateException("Session keys calculation failed.", e); //} //catch (NoSuchPaddingException e) //{ // throw new IllegalStateException("Session keys calculation failed.", e); //} //catch (InvalidKeyException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} //catch (IllegalBlockSizeException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} //catch (BadPaddingException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} catch (Exception e) { throw new Exception("Session keys calculation failed.", e); } }
private GPKeySet DeriveSessionKeysSCP02(GPKeySet staticKeys, byte[] sequence, bool implicitChannel) { GPKeySet sessionKeys = new GPKeySet(); try { //Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding"); byte[] derivationData = new byte[16]; Array.Copy(sequence, 0, derivationData, 2, 2); byte[] constantMAC = new byte[] { (byte)0x01, (byte)0x01 }; Array.Copy(constantMAC, 0, derivationData, 0, 2); //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.MAC), GPCrypto.iv_null_des); //GPKey nk = new GPKey(cipher.doFinal(derivationData), Type.DES3); byte[] result = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.MAC).GetEncoded(), derivationData); GPKey nk = new GPKey(result, KeyType.DES3); sessionKeys.SetKey(KeySessionType.MAC, nk); // TODO: is this correct? - increment by one for all other than C-MAC if (implicitChannel) { Buffer_increment(derivationData, 2, 2); } byte[] constantRMAC = new byte[] { (byte)0x01, (byte)0x02 }; Array.Copy(constantRMAC, 0, derivationData, 0, 2); //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.MAC), GPCrypto.iv_null_des); //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3); byte[] result2 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.MAC).GetEncoded(), derivationData); nk = new GPKey(result2, KeyType.DES3); sessionKeys.SetKey(KeySessionType.RMAC, nk); byte[] constantENC = new byte[] { (byte)0x01, (byte)0x82 }; Array.Copy(constantENC, 0, derivationData, 0, 2); //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.ENC), GPCrypto.iv_null_des); //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3); byte[] result3 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.ENC).GetEncoded(), derivationData); nk = new GPKey(result3, KeyType.DES3); sessionKeys.SetKey(KeySessionType.ENC, nk); byte[] constantDEK = new byte[] { (byte)0x01, (byte)0x81 }; Array.Copy(constantDEK, 0, derivationData, 0, 2); //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.KEK), GPCrypto.iv_null_des); //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3); byte[] result4 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.KEK).GetEncoded(), derivationData); nk = new GPKey(result4, KeyType.DES3); sessionKeys.SetKey(KeySessionType.KEK, nk); return(sessionKeys); } //catch (NoSuchAlgorithmException e) //{ // throw new IllegalStateException("Session keys calculation failed.", e); //} //catch (NoSuchPaddingException e) //{ // throw new IllegalStateException("Session keys calculation failed.", e); //} //catch (InvalidKeyException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} //catch (IllegalBlockSizeException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} //catch (BadPaddingException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} //catch (InvalidAlgorithmParameterException e) //{ // throw new RuntimeException("Session keys calculation failed.", e); //} catch (Exception e) { throw new Exception("Session keys calculation failed.", e); } }