CAS-Framework

Das Media CAS-Framework (Media Conditional Access Systems) bietet Standard-APIs, um CA-Dienste (Conditional Access, bedingter Zugriff) auf einer Reihe von Digital-TV-Hardware zu ermöglichen, darunter digitale Kabel-, Satelliten-, terrestrische und IPTV-Systeme. Das Framework funktioniert mit dem Android TV Input Framework und dem Android TV Tuner Framework und bietet Java-APIs, die von der TIS-App (TV Input Service) aufgerufen werden.

Die Hauptziele von Media CAS sind:

  • Bereitstellung einer öffentlichen Java-API und eines nativen Plug-in-Frameworks, die von Drittentwicklern und OEMs verwendet werden können, um CAS für Broadcast-TV in Android zu unterstützen.
  • Ein CAS-Framework in Android, das ATV-OEMs die Interaktion mit einer Vielzahl von CAS-Anbietern auf konsistente Weise ermöglicht.
  • Unterstützung mehrerer Drittanbieter für CAS über native Plug-ins CAS-Plug-ins verwenden möglicherweise anbieterspezifische Netzwerkprotokolle, EMM- (Entitlement Management Message) bzw. ECM-Formate (Entitlement Control Message) und Entschlüsseler.
  • Unterstützung von Hardwaresicherheit wie Schlüsselhierarchien.
  • Unterstützung von vertrauenswürdigen Ausführungsumgebungen (Trusted Execution Environments, TEEs) wie TrustZone.

Unterstützte Konfigurationen

Konfiguration des Hardware-Tuners

Wenn die Hardware für das Demultiplexing und Entschlüsseln von MPEG-Transportstreams zuständig ist, stellt das Tuner-Framework der TIS-App programmspezifische Informationen (PSI) für den bedingten Zugriff zur Verfügung, um eine Schnittstelle zu hardwarebasierten TV-Tunern zu schaffen.

Zu den PSI-Daten für den bedingten Zugriff gehören CA-Deskriptoren, ECMs und EMMs. Diese Strukturen ermöglichen es dem CAS-Plug-in, die zum Entschlüsseln der Content-Streams erforderlichen Schlüssel abzurufen.

Diagramm der Hardware-Tuner-Konfiguration.

Abbildung 1. Konfiguration des Hardware-Tuners

Die Hardwarekonfiguration kann eine TEE-Ebene wie TrustZone haben, wie in Abbildung 1 dargestellt. Wenn es keine TEE-Ebene gibt, kann ein CAS-Client-Plug-in mit Hardware-Schlüsselhierarchiediensten kommunizieren, die von der Plattform bereitgestellt werden. Aufgrund anbieterspezifischer Variationen dieser Schnittstellen werden sie von Media CAS nicht standardisiert.

Software­konfiguration

Vor Android 11 konnte das Media CAS-Framework weiterhin zur Verarbeitung von softwarebasierten Inhalten wie IPTV aus IP-Multicast/Unicast verwendet werden. Die TIS-App ist für die Instanziierung und ordnungsgemäße Bereitstellung des Media CAS-Java-Objekts verantwortlich.

Die App verwendet möglicherweise MediaExtractor oder andere MPEG2-TS-Parser, um CA-bezogene PSI-Daten wie CA-Deskriptoren, ECMs und EMMs zu extrahieren. Wenn die App das Framework MediaExtractor verwendet, kann sie die CAS-Sitzungsverwaltung, z. B. das Öffnen einer Sitzung und die Verarbeitung von EMM/ECM, an das Framework MediaExtractor delegieren. MediaExtractor konfiguriert die CAS-Sitzung dann direkt über die native API.

Andernfalls ist die App dafür verantwortlich, die CA-bezogenen PSI-Daten zu extrahieren und die CAS-Sitzung mit den Media CAS Java APIs zu konfigurieren (z. B. wenn die App ihren eigenen MPEG2-TS-Parser verwendet).

Diagramm der Tuner-Konfiguration.

Abbildung 2: IPTV-Eingabe, CAS und Descrambler-Konfiguration mit dem MediaExtractor-Framework

Im Szenario mit dem Software-Extractor benötigt der Extractor für jeden verschlüsselten Track ein Software- oder hardwarebasiertes Entschlüsselungsobjekt, unabhängig davon, ob für den Track sichere Decoder erforderlich sind. Das hat folgende Gründe:

  • Wenn für den Track keine sichere Decodierung erforderlich ist, entschlüsselt der Extractor die Zugriffseinheit, um Puffer zu leeren, und extrahiert Samples wie aus einem unverschlüsselten Stream. So muss MediaCodec nicht in die Entschlüsselung einbezogen werden.
  • Wenn für den Track eine sichere Decodierung erforderlich ist, benötigt der Extractor möglicherweise weiterhin einen Descrambler. Dies geschieht, wenn der Transportstream auf Transportpaketebene verschlüsselt wird und der PES-Header (Packetized Elementary Stream) verschlüsselt ist. Der Extractor muss auf den PES-Header zugreifen, um bestimmte Informationen (z. B. den Präsentations-Zeitstempel) weiterzugeben.

    Der Descrambler wird vom Extractor nicht verwendet, wenn der Transportstream auf PES-Paketebene verschlüsselt ist und der PES-Header unverschlüsselt bleibt. Es ist jedoch erst möglich, den Zeitpunkt der Verschlüsselung zu bestätigen, wenn das verschlüsselte Paket tatsächlich eintrifft. Der Einfachheit halber wird davon ausgegangen, dass ein Entschlüssler verwendet wird, wenn der Track anhand der Program Mapping Table (PMT) als verschlüsselt erkannt wird.

Einschränkungen der Softwarekonfiguration

Wenn für den Track eine sichere Decodierung erforderlich ist, muss der Descrambler vorsichtig sein, wenn er einen Descramble-Vorgang in Clear-Puffer zulässt. Da eine unsichere Audio-Decodierung erforderlich ist, sollte die Video-Decodierung in einer anderen Sitzung als die Audio-Decodierung erfolgen, wenn für die Video-Decodierung sichere Decoder erforderlich sind. Das ECM für die Sitzung muss dem Plug-in signalisieren, dass ein sicherer Decoder erforderlich ist.

Alternativ muss das Plug-in einen Schlüssel zuverlässig mit seiner Sicherheitsrichtlinie verknüpfen können. Andernfalls kann die App mit dem Audio-Descrambler ganz einfach Videoframes abrufen.

Auch wenn für die Sitzung ein sicherer Decoder erforderlich ist, kann es sein, dass der Extraktor eine kleine Menge an Daten ausgeben muss, um Puffer zu leeren und den PES-Header zu verarbeiten. Damit eine schädliche App nicht das gesamte Zugriffsmodul zurückgeben kann, muss das Plug-in die Transportnutzlast parsen, um sicherzustellen, dass die Nutzlast mit einem PES-Header des entsprechenden Streamtyps beginnt. Andernfalls sollte das Plug-in die Anfrage ablehnen.

CA-Abstimmungssequenz

Beim Umschalten auf einen neuen Kanal registriert sich das TIS-Modul, um CA-Deskriptoren, ECMs und EMMs vom PSI Tuner-Framework zu empfangen. Ein CA-Deskriptor enthält die CA-System-ID, die einen bestimmten CA-Anbieter eindeutig identifiziert, sowie andere anbieterspezifische Daten. TIS fragt das Media CAS ab, um festzustellen, ob ein CAS-Plug-in vorhanden ist, das den CA-Deskriptor verarbeiten kann.

Diagramm zur Optimierung von CAS-Inhalten.

Abbildung 3: CAS-Inhalte anpassen

Wenn die CA-System-ID unterstützt wird, wird eine Instanz des Media CAS erstellt und die privaten Anbieterdaten aus dem CA-Deskriptor werden dem Plug‑in zur Verfügung gestellt. Anschließend werden neue Sitzungen in Media CAS geöffnet, um die Audio- und Videostreams zu verarbeiten. Die neu geöffneten Sitzungen empfangen ECMs und EMMs für das Plug-in.

Beispiel für den CAS-Plug‑in-Ablauf

TIS stellt ECMs über Media CAS APIs an das CAS-Plug-in bereit. Ein ECM enthält das verschlüsselte Kontrollwort, das mit Informationen aus einem EMM entschlüsselt werden muss. Das CAS-Plug-in bestimmt, wie ein EMM für das Asset anhand anbieterspezifischer Informationen im CA-Deskriptor abgerufen wird, der von der Methode setPrivateData() bereitgestellt wird.

EMMs können im Contentstream (inband) oder außerhalb des Contentstreams (out-of-band) über eine vom CA-Plug-in initiierte Netzwerkanfrage bereitgestellt werden. TIS verwendet die processEMM()-Methode, um In-Band-EMMs an das CA-Plug-in zu senden.

Wenn eine Netzwerkanfrage zum Abrufen eines EMM erforderlich ist, ist das CA-Plug-in für die Durchführung der Netzwerktransaktion mit einem Lizenzserver verantwortlich.

Diagramm eines Beispiel-CAS.

Abbildung 4: Beispiel für ein CAS-Plug-in für die EMM- und ECM-Verarbeitung

Wenn das EMM empfangen wird, parst das CA-Plug-in es, um den verschlüsselten Schlüssel zum Entschlüsseln des Kontrollworts zu erhalten. Der verschlüsselte EMM-Schlüssel und das verschlüsselte Kontrollwort können in eine Schlüsselkette oder eine vertrauenswürdige Umgebung geladen werden, um das Kontrollwort zu entschlüsseln und den Contentstream anschließend zu entschlüsseln.

Media CAS Java API

Die Media CAS Java API enthält die folgenden Methoden.

  • Alle verfügbaren CA-Plug-ins auf dem Gerät auflisten.

    class MediaCas.PluginDescriptor {
      public String getName();
      public int getSystemId();
    }
    static PluginDescriptor[] enumeratePlugins();
    
  • Erstellt eine Media CAS-Instanz für das angegebene CA-System. Das bedeutet, dass das Media CAS-Framework mehrere CAS-Systeme gleichzeitig verarbeiten kann.

    MediaCas(int CA_system_id);
    MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint);
    
  • Registrieren Sie einen Event-Listener und erlauben Sie der App, einen Handler anzugeben, dessen Looper verwendet wird.

    interface MediaCas.EventListener {
      void onEvent(MediaCas, int event, int arg, byte[] data);
      void onSessionEvent(@NonNull MediaCas mediaCas, @NonNull Session session, int event, int arg, @Nullable byte[] data);
      void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status, int arg);
      void onResourceLost(@NonNull MediaCas mediaCas);
    }
    void setEventListener(MediaCas.EventListener listener, Handler handler);
    
  • Senden Sie die privaten Daten für das CA-System. Die privaten Daten können aus dem CA-Deskriptor, der Tabelle für bedingten Zugriff oder Out-of-Band-Quellen stammen. Das ist nicht mit einer bestimmten Sitzung verknüpft.

    void setPrivateData(@NonNull byte[] data);
    
  • EMM-Paket verarbeiten

    void processEmm(@NonNull byte[] data, int offset, int length);
    
  • Senden Sie ein Ereignis an ein CA-System. Das Format des Ereignisses ist spezifisch für das Schema und für das Framework nicht transparent.

    void sendEvent(int event, int arg, @Nullable byte[] data);
    
  • Initiieren Sie einen Bereitstellungsvorgang des angegebenen Typs für ein CA-System. Wenn sich ein Gerät zum ersten Mal für einen Pay-TV-Dienst registriert, muss es zuerst auf dem CAS-Server bereitgestellt werden. Geben Sie eine Reihe von zugehörigen Parametern für die Bereitstellung des Geräts an.

    void provision(String provisionString);
    
  • Aktualisierung von Berechtigungen auslösen Wenn ein Nutzer einen neuen Kanal abonniert (z. B. durch Reaktion auf eine Anzeige oder durch Hinzufügen eines Kanals in der elektronischen Programmübersicht (EPG)), sollte die App die CA-Clients anweisen können, Berechtigungsschlüssel zu aktualisieren.

    void refreshEntitlements(int refreshType);
    
  • Schließen Sie das Media CAS-Objekt.

    void close();
    
  • Öffnen Sie eine Sitzung.

    Session openSession();
    Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);
    
  • Schließen Sie eine zuvor geöffnete Sitzung.

    void Session#close();
    
  • Stellen Sie die privaten CA-Daten aus einem CA-Deskriptor im PMT (Program Map Table) für eine CAS-Sitzung bereit. Diese Daten können aus dem Abschnitt mit den Programminformationen oder den ES-Informationen (Elementary Stream) stammen.

    void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);
    
  • Verarbeiten eines ECM-Pakets für eine Sitzung.

    void Session#processEcm(@NonNull byte[] data, int offset, int length);
    
  • Rufen Sie die Sitzungs-ID ab.

    byte[] Session#getSessionId();
    
  • Senden Sie ein Sitzungsereignis an ein CA-System. Das Format des Ereignisses ist spezifisch für das Schema und für das Framework nicht sichtbar.

    void Session#sendSessionEvent(int event, int arg, @Nullable byte[] data);