Program: 48104
Project: 48104
Buggy source:
/** 
 * Encrypt the APDU.
 * @param apdu APDU
 * @param secureMessagingSSC Secure Messaging Send Sequence Counter
 * @return Encrypted APDU
 * @throws Exception
 */
private byte[] encrypt(byte[] apdu,byte[] secureMessagingSSC) throws Exception {
  ByteArrayOutputStream baos=new ByteArrayOutputStream();
  CardCommandAPDU cAPDU=new CardCommandAPDU(apdu);
  if (cAPDU.isSecureMessaging()) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  byte[] data=cAPDU.getData();
  byte[] header=cAPDU.getHeader();
  int lc=cAPDU.getLC();
  int le=cAPDU.getLE();
  if (data != null) {
    data=pad(data,16);
    Cipher c=getCipher(secureMessagingSSC,Cipher.ENCRYPT_MODE);
    byte[] dataEncrypted=c.doFinal(data);
    dataEncrypted=ByteUtils.concatenate((byte)0x01,dataEncrypted);
    TLV dataObject=new TLV();
    dataObject.setTagNumWithClass((byte)0x87);
    dataObject.setValue(dataEncrypted);
    baos.write(dataObject.toBER());
  }
  if (le >= 0) {
    TLV leObject=new TLV();
    leObject.setTagNumWithClass((byte)0x97);
    if (le == 0x100) {
      leObject.setValue(NULL);
    }
 else     if (le > 0x100) {
      leObject.setValue(new byte[]{(byte)((le >> 8) & 0xFF),(byte)(le & 0xFF)});
    }
 else {
      leObject.setValue(new byte[]{(byte)le});
    }
    baos.write(leObject.toBER());
  }
  header[0]|=0x0C;
  byte[] mac=new byte[16];
  CMac cmac=getCMAC(secureMessagingSSC);
  byte[] paddedHeader=pad(header,16);
  cmac.update(paddedHeader,0,paddedHeader.length);
  if (baos.size() > 0) {
    byte[] paddedData=pad(baos.toByteArray(),16);
    cmac.update(paddedData,0,paddedData.length);
    lc=baos.size();
  }
  cmac.doFinal(mac,0);
  mac=ByteUtils.copy(mac,0,8);
  ByteArrayOutputStream out=new ByteArrayOutputStream();
  out.write(header);
  lc+=10;
  if ((lc > 0xFF) || (le > 0x100)) {
    out.write(NULL);
    out.write((lc >> 8) & 0xFF);
    out.write(lc & 0xFF);
  }
 else {
    out.write(lc & 0xFF);
  }
  if (baos.size() > 0) {
    out.write(baos.toByteArray());
  }
  out.write(new byte[]{(byte)0x8E,(byte)0x08});
  out.write(mac);
  out.write(NULL);
  if ((lc > 0xFF) || (le > 0x100)) {
    out.write(NULL);
  }
  return out.toByteArray();
}

Fixed version (ground truth):
/** 
 * Encrypt the APDU.
 * @param apdu APDU
 * @param secureMessagingSSC Secure Messaging Send Sequence Counter
 * @return Encrypted APDU
 * @throws Exception
 */
private byte[] encrypt(byte[] apdu,byte[] secureMessagingSSC) throws Exception {
  ByteArrayOutputStream baos=new ByteArrayOutputStream();
  CardCommandAPDU cAPDU=new CardCommandAPDU(apdu);
  if (cAPDU.isSecureMessaging()) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  byte[] data=cAPDU.getData();
  byte[] header=cAPDU.getHeader();
  int lc=cAPDU.getLC();
  int le=cAPDU.getLE();
  if (data != null) {
    data=pad(data,16);
    Cipher c=getCipher(secureMessagingSSC,Cipher.ENCRYPT_MODE);
    byte[] dataEncrypted=c.doFinal(data);
    dataEncrypted=ByteUtils.concatenate((byte)0x01,dataEncrypted);
    TLV dataObject=new TLV();
    dataObject.setTagNumWithClass((byte)0x87);
    dataObject.setValue(dataEncrypted);
    baos.write(dataObject.toBER());
  }
  if (le >= 0) {
    TLV leObject=new TLV();
    leObject.setTagNumWithClass((byte)0x97);
    if (le == 0x100) {
      leObject.setValue(NULL);
    }
 else     if (le > 0x100) {
      leObject.setValue(new byte[]{(byte)((le >> 8) & 0xFF),(byte)(le & 0xFF)});
    }
 else {
      leObject.setValue(new byte[]{(byte)le});
    }
    baos.write(leObject.toBER());
  }
  header[0]|=0x0C;
  byte[] mac=new byte[16];
  CMac cmac=getCMAC(secureMessagingSSC);
  byte[] paddedHeader=pad(header,16);
  cmac.update(paddedHeader,0,paddedHeader.length);
  if (baos.size() > 0) {
    byte[] paddedData=pad(baos.toByteArray(),16);
    cmac.update(paddedData,0,paddedData.length);
  }
  cmac.doFinal(mac,0);
  mac=ByteUtils.copy(mac,0,8);
  TLV macStructure=new TLV();
  macStructure.setTagNumWithClass((byte)0x8E);
  macStructure.setValue(mac);
  byte[] secureData=ByteUtils.concatenate(baos.toByteArray(),macStructure.toBER());
  CardCommandAPDU secureCommand=new CardCommandAPDU(header[0],header[1],header[2],header[3],secureData);
  if ((lc > 0xFF) || (le > 0x100)) {
    secureCommand.setLE(65536);
  }
 else {
    secureCommand.setLE(256);
  }
  return secureCommand.toByteArray();
}