Technical Note TN2454

Debugging FairPlay Streaming

This document is intended for AVFoundation clients and content owners that are debugging issues when playing FairPlay streaming (FPS) content. This document discusses the most common issues that can arise while during the development process for creating an FPS-aware application as well as how to debug them.

Debugging FairPlay Streaming Overview
Content Authoring and Content Playback Issues
Verifying Key Security Module (KSM) Implementation
Verifying Client FPS Playback Implementation
Helpful Resources
Document Revision History

Debugging FairPlay Streaming Overview

FairPlay Streaming (FPS) securely delivers keys to Apple mobile devices, Apple TV, and Safari on macOS, which will enable playback of encrypted video content. At a high level there are generally three different issues that can arise during the implementation process which are:

To better diagnose the issues you are seeing regarding FPS it helps to try and narrow down the scope of the problem. This document walks you through how to narrow down the nature of issues when creating FPS aware applications and provides debugging guidance.

Content Authoring and Content Playback Issues

If the issue you are seeing is that your content is unable to actually play on platforms that support FPS, the underlying issue may fall into one of two groups:

If the issue is related to how the content was authored, typically what you will observe on the client side is that it is unable to playback the content:

Figure 1  An example stream with a content authoring issue.

In the case of having an invalid content key or initialization vector you may be able to play the content. However, the system will be unable to properly render it:

Figure 2  An example stream with an invalid content key or initialization vector.

The following section goes over how you can quickly diagnose if the issue you are seeing is due to an invalid content key and/or initialization vector being sent by the KSM.

Quickly Diagnosing Content Key and IV Issues

To narrow down if the issue you are seeing is a content authoring issue or a key delivery issue, we recommend you do the following to your test content:

  1. In the m3u8 playlist, set the KEYFORMAT attribute under the EXT-X-KEY tag to value of "identity" instead of "com.apple.streamingkeydelivery". You can also remove the KEYFORMAT attribute since its absence indicates an implicit value of "identity". For example the following:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://key67",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"

    Would become:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://key67",KEYFORMAT="identity",KEYFORMATVERSIONS="1"
  2. Remove the KEYFORMATVERSIONS attribute from the EXT-X-KEY tag:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://key67",KEYFORMAT="identity"
  3. Add the initialization vector (IV) associated with the content key of the test content as an additional attribute called IV under the EXT-X-KEY tag:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://key67",KEYFORMAT="identity",IV=0xA30FE123ECBF1BE323A775A119C553BC
  4. Make the 16 byte content key associated with the test content available on your web server as a file that can be accessed and update the URI attribute under the EXT-X-KEY tag to point to the content key file:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://mysite.com/my16ByteKey.bin",KEYFORMAT="identity",IV=0xA30FE123ECBF1BE323A775A119C553BC
  5. Attempt to playback the content using the updated playlist.

Performing the above steps allows your client to receive the same content, but instead of decrypting it with FPS, the media framework decrypts it with a clear text AES key.

If after making the above changes your media still does not play, then you should continue to the "Investigating Content Authoring Issues" section of this document.

If the content does play, continue to the "Verifying Key Security Module (KSM) Implementation" section of this document.

Investigating Content Authoring Issues

If you were not able to play your content correctly after using the "identity" KEYFORMAT then you may be running into an issue related to how you authored your content. These issues typically fall into one of the following categories:

  • Verifying FPS m3u8 playlist

    • It is important to test the validity of any playlist streams using the Media Stream Validator tool. For more information about how to verify your content, see the Debugging HTTP Live Streaming technical note which covers this in great detail.

      • The mediastreamvalidator only supports regular HLS m3u8 playlists so you will need to run it against the unencrypted variant of your content instead of your encrypted variant.

  • Sample level encryption

    • There are two types of content that are supported for FairPlay Streaming, MPEG-2 transport stream (ts) and fragmented MPEG-4 (fMP4). Both of these types of content support sample level encryption which means that ranges of individual samples are encrypted with AES-128 CBC with no padding.

      • MPEG-2 TS sample encryption, which is specified in MPEG-2 Stream Encryption Format for HTTP Live Streaming. This document describes a sample-level encryption format for several types of elementary streams that can be carried in MPEG-2 Transport Streams "ISO/IEC 13818-1" and MPEG Elementary Audio streams.

      • fMP4 sample encryption which is specified in ISO/IEC 23001:7 2016, Common Encryption in ISO BMFF [CENC]. Apple devices only support 'cbcs', which is specified in CENC Section 10.4.

  • Program Association Table (PAT), Program Map Table (PMT) Audio Setup Information

  • Content Key rotation on HLS segments

    • Avoid rotating your content key on anything that isn't an HLS segment. We recommend that you rotate your keys on HLS segments at the most granular level. You can also change your content key value on a bitrate switch.

If, however the content does play successfully after performing the above changes, the issue is either an invalid Key Security Module (KSM) implementation or an invalid client FPS playback implementation.

Verifying Key Security Module (KSM) Implementation

If, after verifying your content is authored correctly you still are observing issues with playback, the next thing you should do is validate your KSM implementation.

Quickly Verifying KSM Implementation With Development Credentials

A good indicator of if your KSM is processing SPC payloads correctly is to temporarily configure it to do the following:

  • Use the development credentials that are included in the FairPlay Streaming Server SDK.

  • Use the hardcoded DASk value that is defined in the FairPlay Streaming Programming Guide.

  • Capture the CKC and save it to disk in a binary data format.

After making the above changes, do the following to validate your KSM implementation:

  • The FairPlay Streaming Server SDK includes multiple SPC test vectors and a verification utility called verify_ckc. This utility can be used to test your KSM implementation by verifying the validity of the CKC created by your KSM when using one of the SPC test vectors. For example here is what verify_ckc returns when a KSM produces a valid CKC for one of the included SPC test vectors:

    # For a CKC named "myValidCKC.bin"
            $ ./verify_ckc -s SPC\ CKC\ Tests/FPS/spc1.bin -c ~/Documents/myValidCKC.bin
            CKC/SPC Sanity Test v. 2.01
            ...
            Info: CKC decryption and parsing was successful.

    If, however your KSM generated an invalid CKC you would see the following:

    # For a CKC named "myValidCKC.bin"
            $ ./verify_ckc -s SPC\ CKC\ Tests/FPS/spc1.bin -c ~/Documents/myInvalidCKC.bin
            CKC/SPC Sanity Test v. 2.01
            ...
            CKC parsing error! Found a problem with the CKC TLLV structure.

    The verify_ckc tool can also output all the TLLV content of an SPC and CKC if you pass the -v flag. This is useful if you wish to confirm that your KSM implementation is parsing the TLLV blocks correctly from the SPC as well as if it is returning TLLV blocks correctly in the CKC. Here is an example of using the verify_ckc tool in this way:

    # For a CKC named "myCKC.bin"
            $ ./verify_ckc -s SPC\ CKC\ Tests/FPS/spc1.bin -c ~/Documents/myCKC.bin -v
            CKC/SPC Sanity Test v. 2.01
            ...

    Additional information regarding how to test your KSM can be found in the FairPlay Streaming Programming Guide under the section titled "Testing the Key Security Modules".

    The "FairPlay Streaming Programming Guide", verify_ckc utility, and pre-generated SPC test vectors are included in the FairPlay Streaming Server SDK which is available to download here: FairPlay Streaming - Apple Developer.

Verifying Content Key and Initialization Vector lookup

While you cannot use the development credentials to test actual playback of protected content, you can verify that your logic for providing the content key and initialization vector for content playback works as expected by using the test SPC vectors and the verify_ckc tool:

  1. Lookup the asset id for the SPC test vector you are using by running the verify_ckc tool:

    $ ./verify_ckc -s SPC\ CKC\ Tests/FPS/spc1.bin
    CKC/SPC Sanity Test v. 2.01
    ...
    Asset ID Tag -- 1bf7f53f5d5d5a1f
    Tag size: 0x12
    Tag length: 0x80
    Tag value:
                    aa bb cc dd   ee ff aa bb   cc dd ee ff   aa bb cc dd
                    ee ff -- -- -- -- -- -- -- -- -- -- -- -- -- --
    ...
  2. Using the same method you have implemented content key and initialization vector lookup for your actual content, create an entry for the asset id from the input SPC using any content key and initialization vector. For this example:

    • Our asset id is AABBCCDDEEFFAABBCCDDEEFFAABBCCDDEEFF.

    • The content key is 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B.

    • The initialization vector is D5FBD6B82ED93E4EF98AE40931EE33B7.

  3. Using the SPC test vector from step 1, process the SPC using your KSM with the development credential configuration discussed in the beginning of the "Quickly Verifying KSM Implementation With Development Credentials" section of this document.

  4. Run the verify_ckc tool using the SPC test vector and the captured CKC.

    # For a CKC named "myCKC.bin"
    $ ./verify_ckc -s SPC\ CKC\ Tests/FPS/spc1.bin -c ~/Documents/myCKC.bin
    CKC/SPC Sanity Test v. 2.01
    ...
    SPC SK Value:
        af b4 6e 7b   f5 f3 15 96   c1 c6 76 dc   15 e1 4d c6
    ...
    CK Tag -- 58b38165af0e3d5a
    Tag size: 0x20
    Tag length: 0x20
    Tag value:
                    d5 fb d6 b8   2e d9 3e 4e   f9 8a e4 09   31 ee 33 b7
                    3d 56 43 97   87 8b 70 43   e1 54 31 f1   f8 6b c5 62
    ...
    Info: CKC decryption and parsing was successful.

    There is a section called the SPC SK Value which contains a 16 byte value that is used to encrypt and decrypt the content key in the CKC response. In this example it is AFB46E7BF5F31596C1C676DC15E14DC6.

    There is a section called CK Tag -- 58b38165af0e3d5a which has a value that is 32 bytes long:

    • The first 16 bytes represent the initialization vector you specified in step 2. In this example it is D5FBD6B82ED93E4EF98AE40931EE33B7.

    • The second 16 bytes represent the content key from step 2 after it has been encrypted. In this example it is 3D564397878B7043E15431F1F86BC562.

  5. To get the decrypted version of the content key, we need to perform an additional decryption step using the SPC SK Value and encrypted content key. Here is an example using the openssl command line tool:

    # For an encrypted content key of '3D564397878B7043E15431F1F86BC562'
    # and an SPC SK value of 'AFB46E7BF5F31596C1C676DC15E14DC6'
     
    $ echo 3D564397878B7043E15431F1F86BC562 | xxd -p -r | openssl enc -d -aes-128-ecb -K AFB46E7BF5F31596C1C676DC15E14DC6 -nosalt -nopad | xxd -p
     
    3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B

    The unencrypted version of the content key in this example is 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B.

If the values for the actual initialization vector and/or content key match what you configured in step 2 then your KSM logic should be working as expected.

If the values are not the same, this is a good indicator that the issue is in your KSM implementation's content key and initialization vector lookup code.

Common KSM Implementation Issues With Deployment Credentials

If after verifying your KSM produces a valid CKC response for the SPC test vectors you are still encountering issues with your deployment credentials the next thing to do is to verify the parts of your KSM that are unique to using deployment credentials. The following are some common debugging tips related to the KSM workflow specific to deployment credentials:

  • Once you have confirmed that your KSM generates the expected CKC for the test vectors using the development credentials and fixed DASk, the next thing to verify is your D Function implementation. This is covered in the document titled "D Function Guide" that is in the FPS Deployment package that you received as part of your production FPS credentials.

  • Verifying that you are using the correct certificate and private key pair:

    • It is important to make sure that your FPS clients and KSM are using the correct certificate and private key pair. If you are not using the correct pair this can lead to your KSM improperly decrypting the SPC message or your client generating an SPC that you can not process.

    • To verify that you are using the correct certificate and private key pair you can use the openssl command line tool as demonstrated below:

    # For a certificate named fairplay.cer
                    $ openssl x509 -noout -modulus -in fairplay.cer -inform der | openssl md5
                    552349e40d222c8e01bbc74d08ceea6f
     
                    # For a private key named privatekey.pem. This may require you to enter the password protecting the private key file.
                    $ openssl rsa -noout -modulus -in privatekey.pem | openssl md5
                    552349e40d222c8e01bbc74d08ceea6f

    If the output of both commands matches then this means they belong to the same certificate and private key pair. If they do not match then it means you are not using a matching set and you should update your implementation to ensure you are using the correct credentials.

  • Verifying how you are using your ASk

    • It is important to make sure you are treating your ASk as a byte array and not as a string. If you do not treat the ASk as a byte array your KSM may fail to process the SPC correctly. This can lead to creating a CKC that cannot be decrypted by the client. For example:

    // For a theoretical ASk of 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' you should have a byte array of:
                    UInt8 ASk[] = { 0xFF, 0xFF, 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };
  • Content Key and Initialization Vector lookup

    • Verify that your KSM is looking up the correct key in your key database. Since you have verified that your content is playable using the "identity" KEYFORMAT, you should make sure that the correct content key and initialization vector are being returned by your KSM.

Verifying Client FPS Playback Implementation

To validate your client implementation please do the following:

Helpful Resources

The following resources available on the Apple Developer website contain helpful information that you may find useful:



Document Revision History


DateNotes
2018-01-08

Updated with additional debugging tips for FPS Content Authoring and KSM implementation.

2017-04-13

New document that new document that explains how to debug common issues related to FairPlay Streaming (FPS).