31 August 2010

C-MAC java card GlobalPlatform Secure Channel

 How to make C-MAC
 the weirdest part of secure channel / authentication with a Card

 written with  javax.smartcardio and  ERACOM provider


    byte[] makeC_MAC(byte[] toauth, byte[] Sess_C_MAC, byte[] iv) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

 //       toauth = command less 8 bytes of MAc DATA AND WITHout Le
//       make the C_MAC   "Retail MAC"
//       plain = apdu  without the C_MAC tail...  pad it
//       key = Sess_C_MAC
//       Lc is set to +8 to allow for cmac

//    iv is the previous C_MAC
//    encrypt  1ST8 bytes of the 16bytes (padded) message using 1ST 8 bytes of the
//    C-MAC session key:
            toauth = padm16(toauth);  // pad the chopped message ie missing the 8 bytes where C-MAC will go
            byte[] plaina = new byte[8];
            byte[] bkeya  = new byte[8];
            System.arraycopy(toauth, 0, plaina, 0, 8);
            System.arraycopy(Sess_C_MAC, 0, bkeya, 0, 8);   // Sess_C_MAC I prepared earlier
            //   E(f8(Sess_C__MAC)) [f8 message]
            Cipher desCipher = Cipher.getInstance("DES/ECB/NoPadding", "ERACOM");  // eracom the classic from QUT
            SecretKey kca = makey8(bkeya);   // key factory stuff turns bytes into a key
            IvParameterSpec ivp = new IvParameterSpec(iv);  //  bytes into ivp
            desCipher.init(Cipher.ENCRYPT_MODE, kca,ivp);   //Care iv is chained....... from the previous C-MAC
            byte[] ciphert = desCipher.doFinal(plaina); 
            //xor the first 8bytes that were encrypted with the last 8bytes of "plain text"
            for (short i = 0; i < 8; i++) {
                ciphert[i] ^= toauth[i + 8];   // better: this could be done via ERACOM cbc??
            }        //       encrypt this 8bytes using the final TripleDES:
            Cipher enc = Cipher.getInstance("DESede/ECB/NoPadding", "ERACOM");
            SecretKey key3 = makey(Sess_C_MAC); // 16 bytes to 24  then keyfactory stuff
            //ERACOM  insists on a 24byte key so copy the first 8
            enc.init(Cipher.ENCRYPT_MODE, key3);  // do we use ivp? ecb ... would seem not
            C_MAC = enc.doFinal(ciphert);   //C_MAC
            //print("\n makeCMAC C_MAC " + Hex2String(C_MAC));
            return C_MAC;
    } // makec_mac______________________________










nb: Currently, I can establish a secure channel, but I currently can't carry on the chain of C-MACS,
so something is wrong.


I'm confused about the iv chaining from previous C-MAC, since both DES are ECB, so where does the iv go?  The first time its zeros, so it doesnt matter?

I'm pleased I can authenticate, since you only get 10 failed attempts, then the card is Terminated with extreme prejudice   - I've terminated 3 or 4.

1 comment:

  1. since iv is mentioned, I changed both ECB to CBC
    ("Electronic Code Book" to "Cipher Block Chaining")
    result:
    the authentication still works
    but subsequent attempt to add a C-MAC still get
    SE 6982
    - marginally more encouriging than a 6985...

    ReplyDelete