public synchronized byte[] sendMutualAuth(byte[] rndIFD, byte[] rndICC,
			byte[] kIFD, SecretKey kEnc, SecretKey kMac)
			throws CardServiceException {
		try {
			ResponseAPDU rapdu = transmit(createMutualAuthAPDU(rndIFD, rndICC,
					kIFD, kEnc, kMac));
			byte[] rapduBytes = rapdu.getBytes();
			if (rapduBytes == null) {
				throw new CardServiceException("Mutual authentication failed");
			}
			String errorCode = Hex.shortToHexString((short) rapdu.getSW());
			if (rapduBytes.length == 2) {
				throw new CardServiceException(
						"Mutual authentication failed: error code:  "
						+ errorCode);
			}

			if (rapduBytes.length != 42) {
				throw new CardServiceException(
						"Mutual authentication failed: expected length: 42, actual length: "
						+ rapduBytes.length + ", error code: "
						+ errorCode);
			}

			/* Decrypt the response. */
			cipher.init(Cipher.DECRYPT_MODE, kEnc, ZERO_IV_PARAM_SPEC);
			byte[] result = cipher.doFinal(rapduBytes, 0,
					rapduBytes.length - 8 - 2);
			if (result.length != 32) {
				throw new IllegalStateException("Cryptogram wrong length "
						+ result.length);
			}
			return result;
		} catch (GeneralSecurityException gse) {
			throw new CardServiceException(gse.toString());
		}
	}