public byte[] generateMAC(byte commandClass,byte[] ciphertext,byte sendingNode,byte receivingNode,byte[] iv) throws GeneralSecurityException {
  traceHex("generateMAC ciphertext",ciphertext);
  traceHex("generateMAC iv",iv);
  int bufferSize=ciphertext.length + 4;
  byte[] buffer=new byte[bufferSize];
  byte[] tempAuth=new byte[16];
  buffer[0]=commandClass;
  buffer[1]=sendingNode;
  buffer[2]=receivingNode;
  buffer[3]=(byte)ciphertext.length;
  System.arraycopy(ciphertext,0,buffer,4,ciphertext.length);
  traceHex("generateMAC NetworkKey",networkKey.getEncoded());
  traceHex("generateMAC Raw Auth (minus IV)",buffer);
  Cipher encryptCipher=Cipher.getInstance("AES/ECB/NoPadding");
  encryptCipher.init(Cipher.ENCRYPT_MODE,authKey);
  tempAuth=encryptCipher.doFinal(iv);
  traceHex("generateMAC tmp1",tempAuth);
  byte[] encpck=new byte[16];
  int block=0;
  for (int i=0; i < bufferSize; i++) {
    encpck[block]=buffer[i];
    block++;
    if (block == 16) {
      for (int j=0; j < 16; j++) {
        tempAuth[j]=(byte)(encpck[j] ^ tempAuth[j]);
        encpck[j]=0;
      }
      Arrays.fill(encpck,(byte)0);
      block=0;
      encryptCipher.init(Cipher.ENCRYPT_MODE,authKey);
      tempAuth=encryptCipher.doFinal(tempAuth);
    }
  }
  if (block > 0) {
    for (int i=0; i < 16; i++) {
      tempAuth[i]=(byte)(encpck[i] ^ tempAuth[i]);
    }
    encryptCipher.init(Cipher.ENCRYPT_MODE,authKey);
    tempAuth=encryptCipher.doFinal(tempAuth);
  }
  traceHex("generateMAC Computed Auth",tempAuth);
  byte[] mac=new byte[8];
  System.arraycopy(tempAuth,0,mac,0,8);
  return mac;
}

public byte [ ] generateMAC ( byte commandClass , byte [ ] ciphertext , byte sendingNode , byte receivingNode , byte [ ] iv ) throws GeneralSecurityException { traceHex ( "generateMAC ciphertext" , ciphertext ) ; traceHex ( "generateMAC iv" , iv ) ; int bufferSize = ciphertext . length + 4 ; byte [ ] buffer = new byte [ bufferSize ] ; byte [ ] tempAuth = new byte [ 16 ] ; buffer [ 0 ] = commandClass ; buffer [ 1 ] = sendingNode ; buffer [ 2 ] = receivingNode ; buffer [ 3 ] = ( byte ) ciphertext . length ; System . arraycopy ( ciphertext , 0 , buffer , 4 , ciphertext . length ) ; traceHex ( "generateMAC NetworkKey" , networkKey . getEncoded ( ) ) ; traceHex ( "generateMAC Raw Auth (minus IV)" , buffer ) ; Cipher encryptCipher = Cipher . getInstance ( "AES/ECB/NoPadding" ) ; encryptCipher . init ( Cipher . ENCRYPT_MODE , authKey ) ; tempAuth = encryptCipher . doFinal ( iv ) ; traceHex ( "generateMAC tmp1" , tempAuth ) ; byte [ ] encpck = new byte [ 16 ] ; int block = 0 ; for ( int i = 0 ; i < bufferSize ; i ++ ) { encpck [ block ] = buffer [ i ] ; block ++ ; if ( block == 16 ) { for ( int j = 0 ; j < 16 ; j ++ ) { tempAuth [ j ] = ( byte ) ( encpck [ j ] ^ tempAuth [ j ] ) ; encpck [ j ] = 0 ; } Arrays . fill ( encpck , ( byte ) 0 ) ; block = 0 ; encryptCipher . init ( Cipher . ENCRYPT_MODE , authKey ) ; tempAuth = encryptCipher . doFinal ( tempAuth ) ; } } if ( block > 0 ) { for ( int i = 0 ; i < 16 ; i ++ ) { tempAuth [ i ] = ( byte ) ( encpck [ i ] ^ tempAuth [ i ] ) ; } encryptCipher . init ( Cipher . ENCRYPT_MODE , authKey ) ; tempAuth = encryptCipher . doFinal ( tempAuth ) ; } traceHex ( "generateMAC Computed Auth" , tempAuth ) ; byte [ ] mac = new byte [ 8 ] ; System . arraycopy ( tempAuth , 0 , mac , 0 , 8 ) ; return mac ; }
generate the mac ( message authentication code ) from a security - encrypted message todo : public for testing - look to remove
