private byte[] decryptUpperTransportPDU(@NonNull final AccessMessage accessMessage) throws InvalidCipherTextException {
        byte[] decryptedUpperTransportPDU;
        byte[] key;
        final int transportMicLength = accessMessage.getAszmic() == SZMIC ? MAXIMUM_TRANSMIC_LENGTH : MINIMUM_TRANSMIC_LENGTH;
        //Check if the key used for encryption is an application key or a device key
        final byte[] nonce;
        if (APPLICATION_KEY_IDENTIFIER == accessMessage.getAkf()) {
            key = mMeshNode.getDeviceKey();
            //If its a device key that was used to encrypt the message we need to create a device nonce to decrypt it
            nonce = createDeviceNonce(accessMessage.getAszmic(), accessMessage.getSequenceNumber(), accessMessage.getSrc(), accessMessage.getDst(), accessMessage.getIvIndex());
            decryptedUpperTransportPDU = SecureUtils.decryptCCM(accessMessage.getUpperTransportPdu(), key, nonce, transportMicLength);
        } else {
            final List<ApplicationKey> keys = mUpperTransportLayerCallbacks.getApplicationKeys(accessMessage.getNetworkKey().getKeyIndex());
            if (keys.isEmpty())
                throw new IllegalArgumentException("Unable to find the app key to decrypt the message");

            nonce = createApplicationNonce(accessMessage.getAszmic(), accessMessage.getSequenceNumber(), accessMessage.getSrc(),
                    accessMessage.getDst(), accessMessage.getIvIndex());

            if (MeshAddress.isValidVirtualAddress(accessMessage.getDst())) {
                decryptedUpperTransportPDU = decrypt(accessMessage, mUpperTransportLayerCallbacks.gerVirtualGroups(), keys, nonce, transportMicLength);
            } else {
                decryptedUpperTransportPDU = decrypt(accessMessage, keys, nonce, transportMicLength);
            }
        }

        if (decryptedUpperTransportPDU == null)
            throw new IllegalArgumentException("Unable to decrypt the message, invalid application key identifier!");

        final byte[] tempBytes = new byte[decryptedUpperTransportPDU.length];
        ByteBuffer decryptedBuffer = ByteBuffer.wrap(tempBytes);
        decryptedBuffer.order(ByteOrder.LITTLE_ENDIAN);
        decryptedBuffer.put(decryptedUpperTransportPDU);
        decryptedUpperTransportPDU = decryptedBuffer.array();
        return decryptedUpperTransportPDU;
    }
Returns the decrypted upper transport pdu

@param accessMessage Access message object containing the upper transport pdu
mesh/src/main/java/no/nordicsemi/android/mesh/transport/UpperTransportLayer.java