diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index ae23c5c9..48acd4d5 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -4,6 +4,14 @@ * OEMCryptoCENC.h * * Reference APIs needed to support Widevine's crypto algorithms. + * + * See the document "WV Modular DRM Security Integration Guide for Common + * Encryption (CENC) -- version 12" for a description of this API. You + * can find this document in the widevine repository as + * docs/WidevineModularDRMSecurityIntegrationGuideforCENC.pdf + * Changes between different versions of this API are documented in the files + * docs/Widevine_Modular_DRM_Version_*_Delta.pdf + * *********************************************************************/ #ifndef OEMCRYPTO_CENC_H_ @@ -20,45 +28,46 @@ extern "C" { typedef uint32_t OEMCrypto_SESSION; typedef enum OEMCryptoResult { - OEMCrypto_SUCCESS = 0, - OEMCrypto_ERROR_INIT_FAILED = 1, - OEMCrypto_ERROR_TERMINATE_FAILED = 2, - OEMCrypto_ERROR_OPEN_FAILURE = 3, - OEMCrypto_ERROR_CLOSE_FAILURE = 4, - OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5, - OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, - OEMCrypto_ERROR_SHORT_BUFFER = 7, - OEMCrypto_ERROR_NO_DEVICE_KEY = 8, - OEMCrypto_ERROR_NO_ASSET_KEY = 9, - OEMCrypto_ERROR_KEYBOX_INVALID = 10, - OEMCrypto_ERROR_NO_KEYDATA = 11, - OEMCrypto_ERROR_NO_CW = 12, - OEMCrypto_ERROR_DECRYPT_FAILED = 13, - OEMCrypto_ERROR_WRITE_KEYBOX = 14, - OEMCrypto_ERROR_WRAP_KEYBOX = 15, - OEMCrypto_ERROR_BAD_MAGIC = 16, - OEMCrypto_ERROR_BAD_CRC = 17, - OEMCrypto_ERROR_NO_DEVICEID = 18, - OEMCrypto_ERROR_RNG_FAILED = 19, - OEMCrypto_ERROR_RNG_NOT_SUPPORTED = 20, - OEMCrypto_ERROR_SETUP = 21, - OEMCrypto_ERROR_OPEN_SESSION_FAILED = 22, - OEMCrypto_ERROR_CLOSE_SESSION_FAILED = 23, - OEMCrypto_ERROR_INVALID_SESSION = 24, - OEMCrypto_ERROR_NOT_IMPLEMENTED = 25, - OEMCrypto_ERROR_NO_CONTENT_KEY = 26, - OEMCrypto_ERROR_CONTROL_INVALID = 27, - OEMCrypto_ERROR_UNKNOWN_FAILURE = 28, - OEMCrypto_ERROR_INVALID_CONTEXT = 29, - OEMCrypto_ERROR_SIGNATURE_FAILURE = 30, - OEMCrypto_ERROR_TOO_MANY_SESSIONS = 31, - OEMCrypto_ERROR_INVALID_NONCE = 32, - OEMCrypto_ERROR_TOO_MANY_KEYS = 33, - OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED = 34, - OEMCrypto_ERROR_INVALID_RSA_KEY = 35, - OEMCrypto_ERROR_KEY_EXPIRED = 36, - OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37, - OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38, + OEMCrypto_SUCCESS = 0, + OEMCrypto_ERROR_INIT_FAILED = 1, + OEMCrypto_ERROR_TERMINATE_FAILED = 2, + OEMCrypto_ERROR_OPEN_FAILURE = 3, + OEMCrypto_ERROR_CLOSE_FAILURE = 4, + OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5, + OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, + OEMCrypto_ERROR_SHORT_BUFFER = 7, + OEMCrypto_ERROR_NO_DEVICE_KEY = 8, + OEMCrypto_ERROR_NO_ASSET_KEY = 9, + OEMCrypto_ERROR_KEYBOX_INVALID = 10, + OEMCrypto_ERROR_NO_KEYDATA = 11, + OEMCrypto_ERROR_NO_CW = 12, + OEMCrypto_ERROR_DECRYPT_FAILED = 13, + OEMCrypto_ERROR_WRITE_KEYBOX = 14, + OEMCrypto_ERROR_WRAP_KEYBOX = 15, + OEMCrypto_ERROR_BAD_MAGIC = 16, + OEMCrypto_ERROR_BAD_CRC = 17, + OEMCrypto_ERROR_NO_DEVICEID = 18, + OEMCrypto_ERROR_RNG_FAILED = 19, + OEMCrypto_ERROR_RNG_NOT_SUPPORTED = 20, + OEMCrypto_ERROR_SETUP = 21, + OEMCrypto_ERROR_OPEN_SESSION_FAILED = 22, + OEMCrypto_ERROR_CLOSE_SESSION_FAILED = 23, + OEMCrypto_ERROR_INVALID_SESSION = 24, + OEMCrypto_ERROR_NOT_IMPLEMENTED = 25, + OEMCrypto_ERROR_NO_CONTENT_KEY = 26, + OEMCrypto_ERROR_CONTROL_INVALID = 27, + OEMCrypto_ERROR_UNKNOWN_FAILURE = 28, + OEMCrypto_ERROR_INVALID_CONTEXT = 29, + OEMCrypto_ERROR_SIGNATURE_FAILURE = 30, + OEMCrypto_ERROR_TOO_MANY_SESSIONS = 31, + OEMCrypto_ERROR_INVALID_NONCE = 32, + OEMCrypto_ERROR_TOO_MANY_KEYS = 33, + OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED = 34, + OEMCrypto_ERROR_INVALID_RSA_KEY = 35, + OEMCrypto_ERROR_KEY_EXPIRED = 36, + OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37, + OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38, + OEMCrypto_ERROR_BUFFER_TOO_LARGE = 39, } OEMCryptoResult; /* @@ -69,19 +78,19 @@ typedef enum OEMCryptoResult { * The OEMCrypto API supports a range of client device architectures. * Different architectures have different methods for acquiring and securing * buffers that will hold portions of the audio or video stream after - * decryption. Three basic strategies are recognized for handling decrypted + * decryption. Three basic strategies are recognized for handling decrypted * stream data: * 1. Return the decrypted data in the clear into normal user memory * (ClearBuffer). The caller uses normal memory allocation methods to * acquire a buffer, and supplies the memory address of the buffer in the * descriptor. - * 2. Place the decrypted data into protected memory (SecureBuffer). The + * 2. Place the decrypted data into protected memory (SecureBuffer). The * caller uses a platform-specific method to acquire the protected buffer - * and a user-memory handle that references it. The handle is supplied + * and a user-memory handle that references it. The handle is supplied * to the decrypt call in the descriptor. * 3. Place the decrypted data directly into the audio or video decoder fifo * (Direct). The caller will use platform-specific methods to initialize - * the fifo and the decoders. The decrypted stream data is not accessible + * the fifo and the decoders. The decrypted stream data is not accessible * to the caller. * * Specific fields are as follows: @@ -94,56 +103,58 @@ typedef enum OEMCryptoResult { * max_length - Size of platform-specific secure buffer. * (type == OEMCrypto_BufferType_Direct) * is_video - If true, decrypted bytes are routed to the video - * decoder. If false, decrypted bytes are routed to the + * decoder. If false, decrypted bytes are routed to the * audio decoder. */ typedef enum OEMCryptoBufferType { - OEMCrypto_BufferType_Clear, - OEMCrypto_BufferType_Secure, - OEMCrypto_BufferType_Direct + OEMCrypto_BufferType_Clear, + OEMCrypto_BufferType_Secure, + OEMCrypto_BufferType_Direct } OEMCryptoBufferType; typedef struct { - OEMCryptoBufferType type; - union { - struct { // type == OEMCrypto_BufferType_Clear - uint8_t* address; - size_t max_length; - } clear; - struct { // type == OEMCrypto_BufferType_Secure - void* handle; - size_t max_length; - size_t offset; - } secure; - struct { // type == OEMCrypto_BufferType_Direct - bool is_video; - } direct; - } buffer; + OEMCryptoBufferType type; + union { + struct { // type == OEMCrypto_BufferType_Clear + uint8_t* address; + size_t max_length; + } clear; + struct { // type == OEMCrypto_BufferType_Secure + void* handle; + size_t max_length; + size_t offset; + } secure; + struct { // type == OEMCrypto_BufferType_Direct + bool is_video; + } direct; + } buffer; } OEMCrypto_DestBufferDesc; /** OEMCryptoCipherMode is used in LoadKeys to prepare a key for either CTR * decryption or CBC decryption. */ typedef enum OEMCryptoCipherMode { - OEMCrypto_CipherMode_CTR, - OEMCrypto_CipherMode_CBC, + OEMCrypto_CipherMode_CTR, + OEMCrypto_CipherMode_CBC, } OEMCryptoCipherMode; /* * OEMCrypto_KeyObject - * Points to the relevant fields for a content key. The fields are extracted - * from the License Response message offered to OEMCrypto_LoadKeys(). Each - * field points to one of the components of the key. Key data, key control, + * Points to the relevant fields for a content key. The fields are extracted + * from the License Response message offered to OEMCrypto_LoadKeys(). Each + * field points to one of the components of the key. Key data, key control, * and both IV fields are 128 bits (16 bytes): * key_id - the unique id of this key. - * key_id_length - the size of key_id. + * key_id_length - the size of key_id. OEMCrypto may assume this is at + * most 16. However, OEMCrypto shall correctly handle key id lengths + * from 1 to 16 bytes. * key_data_iv - the IV for performing AES-128-CBC decryption of the * key_data field. - * key_data - the key data. It is encrypted (AES-128-CBC) with the + * key_data - the key data. It is encrypted (AES-128-CBC) with the * session's derived encrypt key and the key_data_iv. * key_control_iv - the IV for performing AES-128-CBC decryption of the * key_control field. - * key_control - the key control block. It is encrypted (AES-128-CBC) with + * key_control - the key control block. It is encrypted (AES-128-CBC) with * the content key from the key_data field. * cipher_mode - whether the key should be prepared for CTR mode or CBC mode * when used in later calls to DecryptCENC. @@ -152,26 +163,26 @@ typedef enum OEMCryptoCipherMode { * by the caller of OEMCrypto_LoadKeys(). */ typedef struct { - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_data_iv; - const uint8_t* key_data; - size_t key_data_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; - OEMCryptoCipherMode cipher_mode; + const uint8_t* key_id; + size_t key_id_length; + const uint8_t* key_data_iv; + const uint8_t* key_data; + size_t key_data_length; + const uint8_t* key_control_iv; + const uint8_t* key_control; + OEMCryptoCipherMode cipher_mode; } OEMCrypto_KeyObject; /* * OEMCrypto_KeyRefreshObject - * Points to the relevant fields for renewing a content key. The fields are + * Points to the relevant fields for renewing a content key. The fields are * extracted from the License Renewal Response message offered to - * OEMCrypto_RefreshKeys(). Each field points to one of the components of + * OEMCrypto_RefreshKeys(). Each field points to one of the components of * the key. * key_id - the unique id of this key. * key_control_iv - the IV for performing AES-128-CBC decryption of the * key_control field. 16 bytes. - * key_control - the key control block. It is encrypted (AES-128-CBC) with + * key_control - the key control block. It is encrypted (AES-128-CBC) with * the content key from the key_data field. 16 bytes. * * The key_data is unchanged from the original OEMCrypto_LoadKeys() call. Some @@ -182,10 +193,10 @@ typedef struct { * by the caller of OEMCrypto_RefreshKeys(). */ typedef struct { - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; + const uint8_t* key_id; + size_t key_id_length; + const uint8_t* key_control_iv; + const uint8_t* key_control; } OEMCrypto_KeyRefreshObject; /* @@ -194,15 +205,15 @@ typedef struct { * Some are valid for encryption/decryption, and some for signing/verifying. */ typedef enum OEMCrypto_Algorithm { - OEMCrypto_AES_CBC_128_NO_PADDING = 0, - OEMCrypto_HMAC_SHA256 = 1, + OEMCrypto_AES_CBC_128_NO_PADDING = 0, + OEMCrypto_HMAC_SHA256 = 1, } OEMCrypto_Algorithm; /* * Flags indicating data endpoints in OEMCrypto_DecryptCENC. */ #define OEMCrypto_FirstSubsample 1 -#define OEMCrypto_LastSubsample 2 +#define OEMCrypto_LastSubsample 2 /* OEMCrypto_CENCEncryptPatternDesc * This is used in OEMCrypto_DecryptCENC to indicate the encrypt/skip pattern @@ -228,7 +239,7 @@ typedef enum OEMCrypto_Usage_Entry_Status { * OEMCrypto_PST_Report is used to report an entry from the Usage Table. */ typedef struct { - uint8_t signature[20]; // -- HMAC SHA1 of the rest of the report. + uint8_t signature[20]; // -- HMAC SHA1 of the rest of the report. uint8_t status; // current status of entry. (OEMCrypto_Usage_Entry_Status) uint8_t clock_security_level; uint8_t pst_length; @@ -251,8 +262,8 @@ typedef enum OEMCrypto_Clock_Security_Level { } OEMCrypto_Clock_Security_Level; typedef enum RSA_Padding_Scheme { - kSign_RSASSA_PSS = 0x1, // RSASSA-PSS with SHA1. - kSign_PKCS1_Block1 = 0x2, // PKCS1 with block type 1 padding (only). + kSign_RSASSA_PSS = 0x1, // RSASSA-PSS with SHA1. + kSign_PKCS1_Block1 = 0x2, // PKCS1 with block type 1 padding (only). } RSA_Padding_Scheme; /* @@ -260,14 +271,23 @@ typedef enum RSA_Padding_Scheme { * level, and in GetHDCPCapability for reporting. */ typedef enum OEMCrypto_HDCP_Capability { - HDCP_NONE = 0, // No HDCP supported, no secure data path. - HDCP_V1 = 1, // HDCP version 1.0 - HDCP_V2 = 2, // HDCP version 2.0 - HDCP_V2_1 = 3, // HDCP version 2.1 - HDCP_V2_2 = 4, // HDCP version 2.2 Type 1. + HDCP_NONE = 0, // No HDCP supported, no secure data path. + HDCP_V1 = 1, // HDCP version 1.0 + HDCP_V2 = 2, // HDCP version 2.0 + HDCP_V2_1 = 3, // HDCP version 2.1 + HDCP_V2_2 = 4, // HDCP version 2.2 Type 1. HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output. } OEMCrypto_HDCP_Capability; +/* Return value for OEMCrypto_GetProvisioningMethod(). */ +typedef enum OEMCrypto_ProvisioningMethod { + OEMCrypto_ProvisioningError = 0, // Device cannot be provisioned. + OEMCrypto_DrmCertificate = 1, // Device has baked in DRM certificate + // (level 3 only) + OEMCrypto_Keybox = 2, // Device has factory installed unique keybox. + OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate. +} OEMCrypto_ProvisioningMethod; + /* * Obfuscation Renames. */ @@ -319,6 +339,9 @@ typedef enum OEMCrypto_HDCP_Capability { #define OEMCrypto_Security_Patch_Level _oecc46 #define OEMCrypto_LoadKeys _oecc47 #define OEMCrypto_DecryptCENC _oecc48 +#define OEMCrypto_GetProvisioningMethod _oecc49 +#define OEMCrypto_GetOEMPublicCertificate _oecc50 +#define OEMCrypto_RewrapDeviceRSAKey30 _oecc51 /* @@ -353,9 +376,9 @@ OEMCryptoResult OEMCrypto_Initialize(void); * N/A * * Threading: - * No other OEMCrypto calls are made while this function is running. After - * this function is called, no other OEMCrypto calls will be made until another - * call to OEMCrypto_Initialize is made. + * No other OEMCrypto calls are made while this function is running. After + * this function is called, no other OEMCrypto calls will be made until + * another call to OEMCrypto_Initialize is made. * * Returns: * OEMCrypto_SUCCESS success @@ -370,18 +393,18 @@ OEMCryptoResult OEMCrypto_Terminate(void); * OEMCrypto_OpenSession * * Description: - * Open a new crypto security engine context. The security engine hardware and - * firmware shall acquire resources that are needed to support the session, and - * return a session handle that identifies that session in future calls. + * Open a new crypto security engine context. The security engine hardware and + * firmware shall acquire resources that are needed to support the session, + * and return a session handle that identifies that session in future calls. * * Parameters: - * session (out) - an opaque handle that the crypto firmware uses to identify the - * session. + * session (out) - an opaque handle that the crypto firmware uses to identify + * the session. * * Threading: * No other Open/Close session calls will be made while this function is - * running. Functions on existing sessions may be called while this function - * is active. + * running. Functions on other existing sessions may be called while this + * function is active. * * Returns: * OEMCrypto_SUCCESS success @@ -391,7 +414,7 @@ OEMCryptoResult OEMCrypto_Terminate(void); * Version: * This method changed in API version 5. */ -OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session); +OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session); /* * OEMCrypto_CloseSession @@ -405,8 +428,8 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session); * * Threading: * No other Open/Close session calls will be made while this function is - * running. Functions on existing sessions may be called while this function - * is active. + * running. Functions on other existing sessions may be called while this + * function is active. * * Returns: * OEMCrypto_SUCCESS success @@ -427,10 +450,10 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * license server protocol for AES CTR mode. * * Refer to document "Widevine Modular DRM Security Integration Guide for - * CENC" for details. This function computes the AES-128-CMAC of the - * enc_key_context and stores it in secure memory as the encrypt_key. It + * CENC" for details. This function computes the AES-128-CMAC of the + * enc_key_context and stores it in secure memory as the encrypt_key. It * then computes four cycles of AES-128-CMAC of the mac_key_context and - * stores it in the mac_keys. The first two cycles are used for + * stores it in the mac_keys. The first two cycles are used for * mac_key_server and the second two cycles are used for mac_key_client. * These three keys will be stored until the next call to LoadKeys. * @@ -438,7 +461,8 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * session (in) - handle for the session to be used. * mac_key_context (in) - pointer to memory containing context data for * computing the HMAC generation key. - * mac_key_context_length (in) - length of the HMAC key context data, in bytes. + * mac_key_context_length (in) - length of the HMAC key context data, in + * bytes. * enc_key_context (in) - pointer to memory containing context data for * computing the encryption key. * enc_key_context_length (in) - length of the encryption key context data, in @@ -446,13 +470,16 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * * * Results: - * mac_key_server: the 256 bit mac key is generated and stored in secure memory. - * mac_key_client: the 256 bit mac key is generated and stored in secure memory. - * enc_key: the 128 bit encryption key is generated and stored in secure memory. + * mac_key_server: the 256 bit mac key is generated and stored in secure + * memory. + * mac_key_client: the 256 bit mac key is generated and stored in secure + * memory. + * enc_key: the 128 bit encryption key is generated and stored in secure + * memory. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -461,31 +488,36 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 8. */ -OEMCryptoResult OEMCrypto_GenerateDerivedKeys( - OEMCrypto_SESSION session, - const uint8_t *mac_key_context, - uint32_t mac_key_context_length, - const uint8_t *enc_key_context, - uint32_t enc_key_context_length); +OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session, + const uint8_t* mac_key_context, + uint32_t mac_key_context_length, + const uint8_t* enc_key_context, + uint32_t enc_key_context_length); /* * OEMCrypto_GenerateNonce * * Description: * Generates a 32-bit nonce to detect possible replay attack on the key - * control block. The nonce is stored in secure memory and will be used + * control block. The nonce is stored in secure memory and will be used * for the next call to LoadKeys. * * Because the nonce will be used to prevent replay attacks, it is desirable * that a rogue application cannot rapidly call this function until a - * repeated nonce is created randomly. With this in mind, if more than 20 + * repeated nonce is created randomly. With this in mind, if more than 20 * nonces are requested within one second, OEMCrypto will return an error * after the 20th and not generate any more nonces for the rest of the - * second. After an error, if the application waits at least one second + * second. After an error, if the application waits at least one second * before requesting more nonces, then OEMCrypto will reset the error * condition and generate valid nonces again. * @@ -494,12 +526,12 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( * nonce (out) - pointer to memory to received the computed nonce. * * Results: - * nonce: the nonce is also stored in secure memory. At least 4 nonces should be - * stored for each session. + * nonce: the nonce is also stored in secure memory. At least 4 nonces should + * be stored for each session. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -510,9 +542,8 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( * Version: * This method changed in API version 5. */ -OEMCryptoResult OEMCrypto_GenerateNonce( - OEMCrypto_SESSION session, - uint32_t* nonce); +OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, + uint32_t* nonce); /* * OEMCrypto_GenerateSignature @@ -527,36 +558,45 @@ OEMCryptoResult OEMCrypto_GenerateNonce( * Refer to document "Widevine Modular DRM Security Integration Guide for * CENC" for details. * + * NOTE: if signature pointer is null and/or input signature_length set to + * zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output + * signature_length to the size needed to receive the output signature. + * * Parameters: * session (in) - crypto session identifier. * message (in) - pointer to memory containing message to be signed. * message_length (in) - length of the message, in bytes. - * signature (out) - pointer to memory to received the computed signature. May be - * null on the first call in order to find required buffer size. + * signature (out) - pointer to memory to received the computed signature. May + * be null (see note above). * signature_length (in/out) - (in) length of the signature buffer, in bytes. * (out) actual length of the signature, in bytes. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to hold - * buffer. + * OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to + * hold the buffer. * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 5. */ -OEMCryptoResult OEMCrypto_GenerateSignature( - OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - uint8_t* signature, - size_t* signature_length); +OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session, + const uint8_t* message, + size_t message_length, + uint8_t* signature, + size_t* signature_length); /* * OEMCrypto_LoadKeys @@ -568,28 +608,28 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * message, but the entire message and associated signature are provided so * the message can be verified (using HMAC-SHA256 with the derived * mac_key_server). If the signature verification fails, ignore all other - * arguments and return OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the + * arguments and return OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the * keys to the session context. * * The keys will be decrypted using the current encrypt_key (AES-128-CBC) and - * the IV given in the KeyObject. Each key control block will be decrypted + * the IV given in the KeyObject. Each key control block will be decrypted * using the first 128 bits of the corresponding content key (AES-128-CBC) and * the IV given in the KeyObject. * - * If it is not null, enc_mac_keys will be used to create new mac_keys. After + * If it is not null, enc_mac_keys will be used to create new mac_keys. After * all keys have been decrypted and validated, the new mac_keys are decrypted - * with the current encrypt_key and the offered IV. The new mac_keys replaces - * the current mac_keys for future calls to OEMCrypto_RefreshKeys(). The first + * with the current encrypt_key and the offered IV. The new mac_keys replaces + * the current mac_keys for future calls to OEMCrypto_RefreshKeys(). The first * 256 bits of the mac_keys become the mac_key[server] and the following 256 - * bits of the mac_keys become the mac_key[client]. If enc_mac_keys is null, + * bits of the mac_keys become the mac_key[client]. If enc_mac_keys is null, * then there will not be a call to OEMCrypto_RefreshKeys for this session and * the current mac_keys should remain unchanged. * * The mac_key and encrypt_key were generated and stored by the previous call - * to OEMCrypto_GenerateDerivedKeys(). The nonce was generated and stored by + * to OEMCrypto_GenerateDerivedKeys(). The nonce was generated and stored by * the previous call to OEMCrypto_GenerateNonce(). * - * This session’s elapsed time clock is started at 0. The clock will be used + * This session’s elapsed time clock is started at 0. The clock will be used * in OEMCrypto_DecryptCENC(). * * NOTE: The calling software must have previously established the mac_keys @@ -600,25 +640,30 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * Refer to document "Widevine Modular DRM Security Integration Guide for * CENC" for details. * + * OEMCrypto shall handle at least 20 keys per session. This allows a + * single license to contain separate keys for 3 key rotations (previous + * interval, current interval, next interval) times 4 content keys (audio, + * SD, HD, UHD) plus up to 8 keys for watermarks. + * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and none of the keys are loaded. * - * 1. The signature of the message shall be computed, and the API shall verify - * the computed signature matches the signature passed in. If not, return - * OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature verification shall use a - * constant-time algorithm (a signature mismatch will always take the same time - * as a successful comparison). + * 1. The signature of the message shall be computed, and the API shall + * verify the computed signature matches the signature passed in. If not, + * return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature verification shall + * use a constant-time algorithm (a signature mismatch will always take the + * same time as a successful comparison). * * 2. The enc_mac_keys pointer must be either null, or point inside the * message. If the pointer enc_mac_keys is not null, the API shall verify - * that the two pointers enc_mac_keys_iv and enc_mac_keys point to locations in - * the message. I.e. (message <= p && p < message+message_length)for p in + * that the two pointers enc_mac_keys_iv and enc_mac_keys point to locations + * in the message. I.e. (message <= p && p < message+message_length)for p in * each of enc_mac_keys_iv, enc_mac_keys. If not, return * OEMCrypto_ERROR_INVALID_CONTEXT. * * 3. The API shall verify that each pointer in each KeyObject points to a - * location in the message. I.e. (message <= p && p < message+message_length) + * location in the message. I.e. (message <= p && p < message+message_length) * for p in each of key_id, key_data_iv, key_data, key_control_iv, * key_control. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * @@ -626,9 +671,9 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * * 5. If any key control block has the Nonce_Enabled bit set, that key’s Nonce - * field shall match the nonce generated by the current nonce. If not, return - * OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that nonce from - * the cache. Note that all the key control blocks in a particular call shall + * field shall match the nonce generated by the current nonce. If not, return + * OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that nonce from + * the cache. Note that all the key control blocks in a particular call shall * have the same nonce value. * * 6. If any key control block has the Require_AntiRollback_Hardware bit set, @@ -642,21 +687,21 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * * Usage Table and Provider Session Token (pst): * - * If a key control block has a nonzero value for Replay_Control, then all keys - * in this license will have the same value. In this case, the following + * If a key control block has a nonzero value for Replay_Control, then all + * keys in this license will have the same value. In this case, the following * additional checks are performed. * * The pointer pst must not be null, and must point to a location in the - * message. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. + * message. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * * - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a - * nonce check as described above. OEMCrypto will verify that the table does - * not already have an entry for the value of pst passed in as a parameter --- - * if an entry already exists, an error OEMCrypto_ERROR_INVALID_CONTEXT is - * returned and no keys are loaded. OEMCrypto will then create a new entry in - * the table, and mark this session as using this new entry. This prevents the - * license from being loaded more than once, and will be used for online - * streaming. + * nonce check as described above. OEMCrypto will verify that the table + * does not already have an entry for the value of pst passed in as a + * parameter. If an entry already exists, an error + * OEMCrypto_ERROR_INVALID_CONTEXT is returned and no keys are + * loaded. OEMCrypto will then create a new entry in the table, and mark + * this session as using this new entry. This prevents the license from + * being loaded more than once, and will be used for online streaming. * * - If Replay_Control is 2 = "Require existing Session Usage table entry or * Nonce", then OEMCrypto will check the Session Usage table for an existing @@ -667,16 +712,16 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * will be verified for each key. * * --- If an existing usage table entry is found, then this session will use - * that entry. In that case, the nonce will not be verified for each key. + * that entry. In that case, the nonce will not be verified for each key. * Also, the entry’s mac keys will be verified against the current - * session’s mac keys. This allows an offline license to be reloaded but + * session’s mac keys. This allows an offline license to be reloaded but * maintain continuity of the playback times from one session to the next. * * - If the nonce is not valid and an existing entry is not found, the return * error is OEMCrypto_ERROR_INVALID_NONCE. * * Note: If LoadKeys updates the mac keys, then the new updated mac keys will - * be used in the Usage Table. If LoadKeys does not update the mac keys, the + * be used in the Usage Table. If LoadKeys does not update the mac keys, the * existing session mac keys are stored in the usage table. * * Sessions that are associated with an entry will need to be able to update @@ -695,7 +740,7 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * message_length (in) - length of the message, in bytes. * signature (in) - pointer to memory containing the signature. * signature_length (in) - length of the signature, in bytes. - * enc_mac_keys_iv (in) - IV for decrypting new mac_key. Size is 128 bits. + * enc_mac_keys_iv (in) - IV for decrypting new mac_key. Size is 128 bits. * enc_mac_keys (in) - encrypted mac_keys for generating new mac_keys. Size is * 512 bits. * num_keys (in) - number of keys present. @@ -704,8 +749,8 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * pst_length (in) - the length of pst. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -716,21 +761,22 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * OEMCrypto_ERROR_INVALID_NONCE * OEMCrypto_ERROR_TOO_MANY_KEYS * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 11. */ -OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, - const uint8_t* enc_mac_keys_iv, - const uint8_t* enc_mac_keys, - size_t num_keys, - const OEMCrypto_KeyObject* key_array, - const uint8_t* pst, - size_t pst_length); +OEMCryptoResult OEMCrypto_LoadKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, + const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, const uint8_t* pst, + size_t pst_length); /* * OEMCrypto_RefreshKeys @@ -740,46 +786,48 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, * current session. * * The relevant fields have been extracted from the Renewal Response protocol - * message, but the entire message and associated signature are provided so the - * message can be verified (using HMAC-SHA256 with the current + * message, but the entire message and associated signature are provided so + * the message can be verified (using HMAC-SHA256 with the current * mac_key[server]). If any verification step fails, an error is returned. - * Otherwise, the key table in trusted memory is updated using the key_control - * block. When updating an entry in the table, only the duration, nonce, and - * nonce_enabled fields are used. All other key control bits are not modified. + * Otherwise, the key table in trusted memory is updated using the + * key_control block. When updating an entry in the table, only the duration, + * nonce, and nonce_enabled fields are used. All other key control bits are + * not modified. * - * NOTE: OEMCrypto_GenerateDerivedKeys() or OEMCrypto_LoadKeys() must be called - * first to establish the mac_key[server]. + * NOTE: OEMCrypto_GenerateDerivedKeys() or OEMCrypto_LoadKeys() must be + * called first to establish the mac_key[server]. * - * This session’s elapsed time clock is reset to 0 when this function is called. - * The elapsed time clock is used in OEMCrypto_DecryptCENC(). + * This session’s elapsed time clock is reset to 0 when this function is + * called. The elapsed time clock is used in OEMCrypto_DecryptCENC(). * - * This function does not add keys to the key table. It is only used to update a - * key control block license duration. Refer to the License Signing and - * Verification section above for more details. This function is used to update - * the duration of a key, only. It is not used to update key control bits. + * This function does not add keys to the key table. It is only used to + * update a key control block license duration. Refer to the License Signing + * and Verification section above for more details. This function is used to + * update the duration of a key, only. It is not used to update key control + * bits. * - * If the KeyRefreshObject’s key_control_iv is null, then the key_control is not - * encrypted. If the key_control_iv is specified, then key_control is encrypted - * with the first 128 bits of the corresponding content key. + * If the KeyRefreshObject’s key_control_iv is null, then the key_control is + * not encrypted. If the key_control_iv is specified, then key_control is + * encrypted with the first 128 bits of the corresponding content key. * - * If the KeyRefreshObject’s key_id is null, then this refresh object should be - * used to update the duration of all keys for the current session. In this - * case, key_control_iv will also be null and the control block will not be - * encrypted. + * If the KeyRefreshObject’s key_id is null, then this refresh object should + * be used to update the duration of all keys for the current session. In + * this case, key_control_iv will also be null and the control block will not + * be encrypted. * * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and none of the keys are loaded. * - * 1. The signature of the message shall be computed, and the API shall verify - * the computed signature matches the signature passed in. If not, return - * OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature verification shall use a - * constant-time algorithm (a signature mismatch will always take the same time - * as a successful comparison). + * 1. The signature of the message shall be computed, and the API shall + * verify the computed signature matches the signature passed in. If not, + * return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature verification shall + * use a constant-time algorithm (a signature mismatch will always take the + * same time as a successful comparison). * * 2. The API shall verify that each pointer in each KeyObject points to a - * location in the message, or is null. I.e. (message <= p && p < + * location in the message, or is null. I.e. (message <= p && p < * message+message_length) for p in each of key_id,key_control_iv, * key_control. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * @@ -787,10 +835,10 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, * return OEMCrypto_ERROR_INVALID_CONTEXT. * * 4. If the key control block has the Nonce_Enabled bit set, the Nonce field - * shall match one of the nonces in the cache. If not, return - * OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that nonce from the - * cache. Note that all the key control blocks in a particular call shall have - * the same nonce value. + * shall match one of the nonces in the cache. If not, return + * OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that nonce from + * the cache. Note that all the key control blocks in a particular call shall + * have the same nonce value. * * Parameters: * session (in) - crypto session identifier. @@ -802,8 +850,8 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, * key_array (in) - set of key updates. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -814,24 +862,26 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, * OEMCrypto_ERROR_SIGNATURE_FAILURE * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 8. */ -OEMCryptoResult -OEMCrypto_RefreshKeys(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, - size_t num_keys, - const OEMCrypto_KeyRefreshObject* key_array); +OEMCryptoResult OEMCrypto_RefreshKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, size_t num_keys, + const OEMCrypto_KeyRefreshObject* key_array); /* * OEMCrypto_QueryKeyControl * * Description: - * Returns the decrypted key control block for the given key_id. This function + * Returns the decrypted key control block for the given key_id. This function * is for application developers to debug license server and key timelines. * It only returns a key control block if LoadKeys was successful, otherwise * it returns OEMCrypto_ERROR_NO_CONTENT_KEY. The developer of the OEMCrypto @@ -847,16 +897,19 @@ OEMCrypto_RefreshKeys(OEMCrypto_SESSION session, * Verification * The following checks should be performed. * 1) If key_id is null, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 2) If key_control_block_length is null, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 3) If *key_control_block_length is less than the length of a key control block, - * set it to the correct value, and return OEMCrypto_ERROR_SHORT_BUFFER. + * 2) If key_control_block_length is null, return + * OEMCrypto_ERROR_INVALID_CONTEXT. + * 3) If *key_control_block_length is less than the length of a key control + * block, set it to the correct value, and return + * OEMCrypto_ERROR_SHORT_BUFFER. * 4) If key_control_block is null, return OEMCrypto_ERROR_INVALID_CONTEXT. * 5) If the specified key has not been loaded, return * OEMCrypto_ERROR_NO_CONTENT_KEY. * * Parameters * key_id (in) - The unique id of the key of interest. - * key_id_length (in) - The length of key_id, in bytes. + * key_id_length (in) - The length of key_id, in bytes. From 1 to 16 + * inclusive. * key_control_block(out) - A caller-owned buffer. * key_control_block_length (in/out) - The length of key_control_block buffer. * @@ -866,55 +919,70 @@ OEMCrypto_RefreshKeys(OEMCrypto_SESSION session, * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_NO_CONTENT_KEY * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Threading - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Version * This method is added in API version 10. */ -OEMCryptoResult -OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, - const uint8_t* key_id, - size_t key_id_length, - uint8_t* key_control_block, - size_t* key_control_block_length); +OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, + const uint8_t* key_id, + size_t key_id_length, + uint8_t* key_control_block, + size_t* key_control_block_length); /* * OEMCrypto_SelectKey * * Description: * Select a content key and install it in the hardware key ladder for - * subsequent decryption operations (OEMCrypto_DecryptCENC()) for this session. - * The specified key must have been previously "installed" via + * subsequent decryption operations (OEMCrypto_DecryptCENC()) for this + * session. The specified key must have been previously "installed" via * OEMCrypto_LoadKeys() or OEMCrypto_RefreshKeys(). * * A key control block is associated with the key and the session, and is used - * to configure the session context. The Key Control data is documented in + * to configure the session context. The Key Control data is documented in * "Key Control Block Definition". * - * Step 1: Lookup the content key data via the offered key_id. The key data + * Step 1: Lookup the content key data via the offered key_id. The key data * includes the key value, and the key control block. * - * Step 2: Latch the content key into the hardware key ladder. Set + * Step 2: Latch the content key into the hardware key ladder. Set * permission flags and timers based on the key's control block. * - * Step 3: use the latched content key to decrypt (AES-128-CTR) buffers passed in - * via OEMCrypto_DecryptCENC(). If the key is 256 bits it will be used for - * OEMCrypto_Generic_Sign or OEMCrypto_Generic_Verify as specified in the key - * control block. Continue to use this key until OEMCrypto_SelectKey() is called - * again, or until OEMCrypto_CloseSession() is called. + * Step 3: use the latched content key to decrypt (AES-128-CTR) buffers + * passed in via OEMCrypto_DecryptCENC(). If the key is 256 bits it + * will be used for OEMCrypto_Generic_Sign or + * OEMCrypto_Generic_Verify as specified in the key control + * block. Continue to use this key until OEMCrypto_SelectKey() is + * called again, or until OEMCrypto_CloseSession() is called. + * + * Verification: + * The following checks should be performed if is_encrypted is true. If any + * check fails, an error is returned, and no decryption is performed. + * + * 1. If the current key’s control block has a nonzero duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. * * * Parameters: * session (in) - crypto session identifier * key_id (in) - pointer to the Key ID - * key_id_length (in) - length of the Key ID in bytes + * key_id_length (in) - length of the Key ID in bytes. From 1 to 16 + * inclusive. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -940,24 +1008,25 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * Description: * Decrypts or copies the payload in the buffer referenced by the *data_addr * parameter into the buffer referenced by the out_buffer parameter, using - * the session context indicated by the session parameter. Decryption mode + * the session context indicated by the session parameter. Decryption mode * is AES-128-CTR or AES-128-CBC depending on the value of cipher_mode set in - * the OEMCrypto_KeyObject passed in to OEMCrypto_LoadKeys. If is_encrypted + * the OEMCrypto_KeyObject passed in to OEMCrypto_LoadKeys. If is_encrypted * is true, the content key associated with the session is latched in the - * active hardware key ladder and is used for the decryption operation. If + * active hardware key ladder and is used for the decryption operation. If * is_encrypted is false, the data is simply copied. * - * After decryption, the data_length bytes are copied to the location described - * by out_buffer. This could be one of + * After decryption, the data_length bytes are copied to the location + * described by out_buffer. This could be one of * - * 1. The structure out_buffer contains a pointer to a clear text buffer. The - * OEMCrypto library shall verify that key control allows data to be returned in - * clear text. If it is not authorized, this method should return an error. + * 1. The structure out_buffer contains a pointer to a clear text buffer. The + * OEMCrypto library shall verify that key control allows data to be returned + * in clear text. If it is not authorized, this method should return an + * error. * * 2. The structure out_buffer contains a handle to a secure buffer. * - * 3. The structure out_buffer indicates that the data should be sent directly to - * the decoder and rendered. + * 3. The structure out_buffer indicates that the data should be sent + * directly to the decoder and rendered. * * NOTES: * For CTR mode, IV points to the counter value to be used for the initial @@ -968,92 +1037,117 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * value (0xFFFFFFFFFFFFFFFF). The upper 64 bits (byte 0-7) of the IV do not * change. * + * For CBC mode, IV points to the initialization vector for cipher block + * chaining. Within each subsample, OEMCrypto is responsible for updating + * the IV as prescribed by CBC mode. The calling layer above is responsible + * for updating the IV from one subsample to the next if needed. + * * This method may be called several times before the decrypted data is used. * For this reason, the parameter subsample_flags may be used to optimize - * decryption. The first buffer in a chunk of data will have the - * OEMCrypto_FirstSubsample bit set in subsample_flags. The last buffer in a + * decryption. The first buffer in a chunk of data will have the + * OEMCrypto_FirstSubsample bit set in subsample_flags. The last buffer in a * chunk of data will have the OEMCrypto_LastSubsample bit set in - * subsample_flags. The decrypted data will not be used until after - * OEMCrypto_LastSubsample has been set. If an implementation decrypts data + * subsample_flags. The decrypted data will not be used until after + * OEMCrypto_LastSubsample has been set. If an implementation decrypts data * immediately, it may ignore subsample_flags. * - * If the destination buffer is secure, an offset may be specified. DecryptCENC - * begins storing data out_buffer->secure.offset bytes after the beginning of the - * secure buffer. + * If the destination buffer is secure, an offset may be specified. + * DecryptCENC begins storing data out_buffer->secure.offset bytes after the + * beginning of the secure buffer. * - * If the session has an entry in the Usage Table, then OEMCrypto will update the - * time_of_last_decrypt. If the status of the entry is "unused", then change the - * status to "active" and set the time_of_first_decrypt. + * If the session has an entry in the Usage Table, then OEMCrypto will update + * the time_of_last_decrypt. If the status of the entry is "unused", then + * change the status to "active" and set the time_of_first_decrypt. * * The decryption mode, either OEMCrypto_CipherMode_CTR or * OEMCrypto_CipherMode_CBC, was specified in the call to OEMCrypto_LoadKeys. - * The encryption pattern is specified in by the parameter pattern. A - * description of partial encryption patterns can be found in the document - * Draft International Standard ISO/IEC DIS 23001-7. Search for the codes - * "cenc", "cbc1", "cens" or "cbcs". + * The encryption pattern is specified by the fields in the parameter + * pattern. A description of partial encryption patterns can be found in the + * document Draft International Standard ISO/IEC DIS 23001-7. Search for the + * codes "cenc", "cbc1", "cens" or "cbcs". * + * The most common mode is "cenc", which is OEMCrypto_CipherMode_CTR without + * a pattern. The entire subsample is either encrypted or clear, depending + * on the flag is_encrypted. In the structure pattern, both encrypt and skip + * will be 0. This is the only mode that allows for a nonzero block_offset. + * + * A less common mode is "cens", which is OEMCrypto_CipherMode_CTR with an + * encryption pattern. For this mode, OEMCrypto may assume that an encrypted + * subsample will have a length that is a multiple of 16, the AES block + * length. + * + * The mode "cbc1" is OEMCrypto_CipherMode_CBC without a pattern. In the + * structure pattern, both encrypt and skip will be 0. If an encrypted + * subsample has a length that is not a multiple of 16, the final partial + * block will be in the clear. + * + * The mode "cbcs" is OEMCrypto_CipherMode_CBC with an encryption pattern. + * This mode allows devices to decrypt HLS content. If an encrypted + * subsample has a length that is not a multiple of 16, the final partial + * block will be in the clear. * * Verification: - * The following checks should be performed if is_encrypted is true. If any + * The following checks should be performed if is_encrypted is true. If any * check fails, an error is returned, and no decryption is performed. * - * 1. If the current key’s control block has a nonzero Duration field, then the - * API shall verify that the duration is greater than the session’s elapsed time - * clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. + * 1. If the current key’s control block has a nonzero Duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. * - * 2. If the current key’s control block has the Data_Path_Type bit set, then the - * API shall verify that the output buffer is secure or direct. If not, return - * OEMCrypto_ERROR_DECRYPT_FAILED. + * 2. If the current key’s control block has the Data_Path_Type bit set, then + * the API shall verify that the output buffer is secure or direct. If not, + * return OEMCrypto_ERROR_DECRYPT_FAILED. * - * 3. If the current key’s control block has the HDCP bit set, then the API shall - * verify that the buffer will be output using HDCP only. If not, return - * OEMCrypto_ERROR_DECRYPT_FAILED. + * 3. If the current key’s control block has the HDCP bit set, then the API + * shall verify that the buffer will be output using HDCP only. If not, + * return OEMCrypto_ERROR_DECRYPT_FAILED. * - * 4. If the current key’s control block has a nonzero value for HDCP_Version, - * then the current version of HDCP for the device and the display combined will - * be compared against the version specified in the control block. If the - * current version is not at least as high as that in the control block, then - * return OEMCrypto_ERROR_INSUFFICIENT_HDCP. + * 4. If the current key’s control block has a nonzero value for + * HDCP_Version, then the current version of HDCP for the device and the + * display combined will be compared against the version specified in the + * control block. If the current version is not at least as high as that in + * the control block, then return OEMCrypto_ERROR_INSUFFICIENT_HDCP. * - * 5. If the current session has an entry in the Usage Table, and the status of - * that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. + * 5. If the current session has an entry in the Usage Table, and the status + * of that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. * - * If the flag is_encrypted is false, then no verification is performed. This - * call shall copy clear data even when there are no keys loaded, or there is no - * selected key. + * If the flag is_encrypted is false, then no verification is performed. This + * call shall copy clear data even when there are no keys loaded, or there is + * no selected key. * * Parameters: * session (in) - crypto session identifier. * data_addr (in) - An unaligned pointer to this segment of the stream. * data_length (in) - The length of this segment of the stream, in bytes. - * is_encrypted (in) - True if the buffer described by data_addr, data_length is - * encrypted. If is_encrypted is false, only the data_addr - * and data_length parameters are used. The iv and offset - * arguments are ignored. + * is_encrypted (in) - True if the buffer described by data_addr, data_length + * is encrypted. If is_encrypted is false, only the + * data_addr and data_length parameters are used. The iv + * and offset arguments are ignored. * iv (in) - The initial value block to be used for content decryption. - * block_offset (in) - If non-zero, the decryption block boundary is different - * from the start of the data. block_offset should be - * subtracted from data_addr to compute the starting address - * of the first decrypted block. The bytes between the - * decryption block start address and data_addr are discarded - * after decryption. It does not adjust the beginning of the - * source or destination data. This parameter satisfies - * 0 <= block_offset < 16. This paramater is only used - * for CTR mode. - * out_buffer (in) - A caller-owned descriptor that specifies the handling of the - * decrypted byte stream. See OEMCrypto_DestbufferDesc for details. + * block_offset (in) - If non-zero, the decryption block boundary is + * different from the start of the data. block_offset + * should be subtracted from data_addr to compute the + * starting address of the first decrypted block. The + * bytes between the decryption block start address and + * data_addr are discarded after decryption. It does not + * adjust the beginning of the source or destination + * data. This parameter satisfies 0 <= block_offset < + * 16. This paramater is only used for CTR mode. + * out_buffer (in) - A caller-owned descriptor that specifies the handling of + * the decrypted byte stream. See OEMCrypto_DestbufferDesc + * for details. * pattern (in) - A caller-owned structure indicating the encrypt/skip * pattern as specified in the CENC standard. - * subsample_flags (in) - bitwise flags indicating if this is the first, middle, - * or last subsample in a chunk of data. + * subsample_flags (in) - bitwise flags indicating if this is the first, + * middle, or last subsample in a chunk of data. * 0 = neither first nor last subsample, * 1 = first subsample, * 2 = last subsample, * 3 = both first and last subsample. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS @@ -1065,46 +1159,52 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * OEMCrypto_ERROR_INSUFFICIENT_HDCP * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support subsample sizes (i.e. data_length) of at least + * 100 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. If OEMCrypto returns + * OEMCrypto_ERROR_BUFFER_TOO_LARGE, the calling function must break the buffer + * into smaller chunks. For high performance devices, OEMCrypto should handle + * larger buffers. * * Version: * This method changed in API version 11. * This method changed its name in API version 11. */ -OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session, - const uint8_t *data_addr, - size_t data_length, - bool is_encrypted, - const uint8_t *iv, - size_t block_offset, - OEMCrypto_DestBufferDesc* out_buffer, - const OEMCrypto_CENCEncryptPatternDesc* pattern, - uint8_t subsample_flags); - +OEMCryptoResult OEMCrypto_DecryptCENC( + OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, + bool is_encrypted, const uint8_t* iv, size_t block_offset, + OEMCrypto_DestBufferDesc* out_buffer, + const OEMCrypto_CENCEncryptPatternDesc* pattern, uint8_t subsample_flags); /* * OEMCrypto_CopyBuffer * * Description: - * Copies the payload in the buffer referenced by the *data_addr parameter into - * the buffer referenced by the out_buffer parameter. The data is simply + * Copies the payload in the buffer referenced by the *data_addr parameter + * into the buffer referenced by the out_buffer parameter. The data is simply * copied. The definition of OEMCrypto_DestBufferDesc and subsample_flags are * the same as in OEMCrypto_DecryptCENC, above. * - * The main difference between this and DecryptCENC is that this function does - * not need an open session, and it may be called concurrently with other - * session functions on a multithreaded system. In particular, an application - * will use this to copy the clear leader of a video to a secure buffer while - * the license request is being generated, sent to the server, and the response - * is being processed. This functionality is needed because an application may - * not have read or write access to a secure destination buffer. + * The main difference between this and DecryptCENC is that this function + * does not need an open session, and it may be called concurrently with + * other session functions on a multithreaded system. In particular, an + * application will use this to copy the clear leader of a video to a secure + * buffer while the license request is being generated, sent to the server, + * and the response is being processed. This functionality is needed because + * an application may not have read or write access to a secure destination + * buffer. * * NOTES: * - * This method may be called several times before the data is used. The + * This method may be called several times before the data is used. The * first buffer in a chunk of data will have the OEMCrypto_FirstSubsample bit - * set in subsample_flags. The last buffer in a chunk of data will have the - * OEMCrypto_LastSubsample bit set in subsample_flags. The data will not be - * used until after OEMCrypto_LastSubsample has been set. If an + * set in subsample_flags. The last buffer in a chunk of data will have the + * OEMCrypto_LastSubsample bit set in subsample_flags. The data will not be + * used until after OEMCrypto_LastSubsample has been set. If an * implementation copies data immediately, it may ignore subsample_flags. * * If the destination buffer is secure, an offset may be specified. @@ -1119,10 +1219,11 @@ OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session, * Parameters * data_addr (in) - An unaligned pointer to the buffer to be copied. * data_length (in) - The length of the buffer, in bytes. - * out_buffer (out) - A caller-owned descriptor that specifies the handling of - * the byte stream. See OEMCrypto_DestbufferDesc for details. - * subsample_flags (in) - bitwise flags indicating if this is the first, middle, - * or last subsample in a chunk of data. + * out_buffer (out) - A caller-owned descriptor that specifies the handling + * of the byte stream. See OEMCrypto_DestbufferDesc for + * details. + * subsample_flags (in) - bitwise flags indicating if this is the first, + * middle, or last subsample in a chunk of data. * 0 = neither first nor last subsample, * 1 = first subsample, * 2 = last subsample, @@ -1132,13 +1233,23 @@ OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session, * OEMCrypto_SUCCESS * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support subsample sizes (i.e. data_length) of at least + * 100 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. If OEMCrypto returns + * OEMCrypto_ERROR_BUFFER_TOO_LARGE, the calling function must break the buffer + * into smaller chunks. For high performance devices, OEMCrypto should handle + * larger buffers. * * Threading * This function may be called simultaneously with any other functions. * Version * This method is added in API version 10. */ -OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t *data_addr, +OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags); @@ -1147,32 +1258,36 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t *data_addr, * OEMCrypto_WrapKeybox * * Description: - * During manufacturing, the keybox should be encrypted with the OEM root key and - * stored on the file system in a region that will not be erased during factory - * reset. As described in section 5.5.4, the keybox may be directly encrypted - * and stored on the device in a single step, or it may use the two-step - * WrapKeybox/InstallKeybox approach. When the Widevine DRM plugin initializes, - * it will look for a wrapped keybox in the file /factory/wv.keys and install it - * into the security processor by calling OEMCrypto_InstallKeybox(). + * During manufacturing, the keybox should be encrypted with the OEM root key + * and stored on the file system in a region that will not be erased during + * factory reset. As described in section 5.5.4, the keybox may be directly + * encrypted and stored on the device in a single step, or it may use the + * two-step WrapKeybox/InstallKeybox approach. When the Widevine DRM plugin + * initializes, it will look for a wrapped keybox in the file + * /factory/wv.keys and install it into the security processor by calling + * OEMCrypto_InstallKeybox(). * - * OEMCrypto_WrapKeybox() is used to generate an OEM-encrypted keybox that may be - * passed to OEMCrypto_InstallKeybox() for provisioning. The keybox may be - * either passed in the clear or previously encrypted with a transport key. If a - * transport key is supplied, the keybox is first decrypted with the transport - * key before being wrapped with the OEM root key. This function is only needed - * if the provisioning method involves saving the keybox to the file system. + * OEMCrypto_WrapKeybox() is used to generate an OEM-encrypted keybox that + * may be passed to OEMCrypto_InstallKeybox() for provisioning. The keybox + * may be either passed in the clear or previously encrypted with a transport + * key. If a transport key is supplied, the keybox is first decrypted with + * the transport key before being wrapped with the OEM root key. This + * function is only needed if the provisioning method involves saving the + * keybox to the file system. * * Parameters: - * keybox (in) - pointer to Keybox data to encrypt. May be NULL on the first - * call to test size of wrapped keybox. The keybox may either be clear or - * previously encrypted. - * keyboxLength (in) - length the keybox data in bytes - * wrappedKeybox (out) – Pointer to wrapped keybox - * wrappedKeyboxLength (out) – Pointer to the length of the wrapped keybox in bytes - * transportKey (in) – Optional. AES transport key. If provided, the keybox - * parameter was previously encrypted with this key. The keybox will be - * decrypted with the transport key using AES-CBC and a null IV. - * transportKeyLength (in) – Optional. Number of bytes in the transportKey, if used. + * keybox (in) - pointer to Keybox data to encrypt. May be NULL on the first + * call to test size of wrapped keybox. The keybox may either be clear or + * previously encrypted. + * keyboxLength (in) - length the keybox data in bytes + * wrappedKeybox (out) – Pointer to wrapped keybox + * wrappedKeyboxLength (out) – Pointer to the length of the wrapped keybox in + * bytes + * transportKey (in) – Optional. AES transport key. If provided, the keybox + * parameter was previously encrypted with this key. The keybox will be + * decrypted with the transport key using AES-CBC and a null IV. + * transportKeyLength (in) – Optional. Number of bytes in the transportKey, if + * used. * * Threading: * This function is not called simultaneously with any other functions @@ -1180,30 +1295,28 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t *data_addr, * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_WRAP_KEYBOX failed to wrap Keybox - * OEMCrypto_ERROR_SHORT_BUFFER if keybox is provided as NULL, to determine the - * size of the wrapped keybox + * OEMCrypto_ERROR_SHORT_BUFFER if keybox is provided as NULL, to determine + * the size of the wrapped keybox * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_NOT_IMPLEMENTED * * Version: * This method is supported by all API versions. */ -OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox, - size_t keyBoxLength, - uint8_t *wrappedKeybox, - size_t *wrappedKeyBoxLength, - const uint8_t *transportKey, +OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox, size_t keyBoxLength, + uint8_t* wrappedKeybox, + size_t* wrappedKeyBoxLength, + const uint8_t* transportKey, size_t transportKeyLength); - /* * OEMCrypto_InstallKeybox * * Description: - * Decrypts a wrapped keybox and installs it in the security processor. The - * keybox is unwrapped then encrypted with the OEM root key. This function is + * Decrypts a wrapped keybox and installs it in the security processor. The + * keybox is unwrapped then encrypted with the OEM root key. This function is * called from the Widevine DRM plugin at initialization time if there is no - * valid keybox installed. It looks for a wrapped keybox in the file + * valid keybox installed. It looks for a wrapped keybox in the file * /factory/wv.keys and if it is present, will read the file and call * OEMCrypto_InstallKeybox() with the contents of the file. * @@ -1224,19 +1337,81 @@ OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox, * Version: * This method is supported in all API versions. */ -OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t *keybox, +OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, size_t keyBoxLength); +/* + * OEMCrypto_GetProvisioningMethod + * + * Description: + * This function is for OEMCrypto to tell the layer above what provisioning + * method it uses: keybox or OEM certificate. + * + * Parameters: + * none + * + * Returns: + * OEMCrypto_DrmCertificate - means the device has a DRM certificate built + * into the system. This cannot be used by level 1 devices. + * OEMCrypto_Keybox - means the device has a unique keybox. For level 1 + * devices this keybox must be securely installed by the device manufacturer. + * OEMCrypto_OEMCertificate - means the device has a factory installed OEM + * certificate. This is also called Provisioning 3.0. + * + * Threading: + * This function may be called simultaneously with any session functions. + * + * Version: + * This method is new API version 12. + */ +OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(); + +/* + * OEMCrypto_GetOEMPublicCertificate + * + * Description: + * This function should place the OEM public certificate in the buffer + * public_cert. After a call to this function, all methods using an RSA key + * should use the OEM certificate’s private RSA key. See the discussion of + * Provisioning 3.0 in the document "WV Modular DRM Security Itegration Guide + * for Common Encryption (CENC)". + * + * If the buffer is not large enough, OEMCrypto should update + * public_cert_length and return OEMCrypto_ERROR_SHORT_BUFFER. + * + * Parameters: + * session (in) - this function affects the specified session only. + * public_cert (out) - the buffer where the public certificate is stored. + * public_cert_length (in/out) - on input, this is the available size of the + * buffer. On output, this is the number of bytes needed for the + * certificate. + * + * Returns: + * OEMCrypto_SUCCESS + * OEMCrypto_ERROR_NOT_IMPLEMENTED + * OEMCrypto_ERROR_SHORT_BUFFER + * + * Threading: + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. + * + * Version: + * This method is new API version 12. + */ +OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(OEMCrypto_SESSION session, + uint8_t* public_cert, + size_t* public_cert_length); + /* * OEMCrypto_LoadTestKeybox * * Description: - * Temporarily use the standard test keybox in place of the factory provisioned - * keybox for all functions that use keybox keys or data. This allows a - * standard suite of unit tests to be run on a production device without - * permanently changing the keybox. This keybox will persist until the next - * call to OEMCrypto_Terminate or OEMCrypto_Initialize. Upon initialization, - * revert to using the factory provisioned keybox. + * Temporarily use the standard test keybox in place of the factory + * provisioned keybox for all functions that use keybox keys or data. This + * allows a standard suite of unit tests to be run on a production device + * without permanently changing the keybox. This keybox will persist until + * the next call to OEMCrypto_Terminate or OEMCrypto_Initialize. Upon + * initialization, revert to using the factory provisioned keybox. * * The test keybox can be found in the reference implementation. * @@ -1306,8 +1481,7 @@ OEMCryptoResult OEMCrypto_IsKeyboxValid(void); * Version: * This method is supported by all API versions. */ -OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, - size_t *idLength); +OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength); /* * OEMCrypto_GetKeyData @@ -1324,7 +1498,7 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, * Parameters: * keyData (out) - pointer to a caller-managed buffer to hold the Key Data * field from the Keybox - * dataLength (in/out) - on input, the allocated buffer size. On output, + * dataLength (in/out) - on input, the allocated buffer size. On output, * the number of bytes in KeyData. * * Threading: @@ -1334,12 +1508,12 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER the buffer is too small to return the KeyData * OEMCrypto_ERROR_NO_KEYDATA failed to return KeyData + * OEMCrypto_ERROR_NOT_IMPLEMENTED - device does not use keybox * * Version: * This method is supported by all API versions. */ -OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, - size_t *keyDataLength); +OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength); /* * OEMCrypto_GetRandom @@ -1360,64 +1534,218 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_RNG_FAILED failed to generate random number * OEMCrypto_ERROR_RNG_NOT_SUPPORTED function not supported + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support dataLength of at least 32 bytes for random number + * generation. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * too large. * * Version: * This method is supported by all API versions. */ -OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, - size_t dataLength); +OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength); + +/* + * OEMCrypto_RewrapDeviceRSAKey30 + * + * Description: + * This function is similar to RewrapDeviceRSAKey, except it uses the private + * key from an OEM certificate to decrypt the message key instead of keys + * derived from a keybox. Verifies an RSA provisioning response is valid and + * corresponds to the previous provisioning request by checking the nonce. + * The RSA private key is decrypted and stored in secure memory. The RSA key + * is then re-encrypted and signed for storage on the filesystem. We + * recommend that the OEM use an encryption key and signing key generated + * using an algorithm at least as strong as that in GenerateDerivedKeys. + * + * After decrypting enc_rsa_key, If the first four bytes of the buffer are + * the string “SIGN”, then the actual RSA key begins on the 9th byte of the + * buffer. The second four bytes of the buffer is the 32 bit field + * “allowed_schemes”, of type RSA_Padding_Scheme, which is used in + * OEMCrypto_GenerateRSASignature. The value of allowed_schemes must also + * be wrapped with RSA key. We recommend storing the magic string “SIGN” with + * the key to distinguish keys that have a value for allowed_schemes from + * those that should use the default allowed_schemes. Devices that do not + * support the alternative signing algorithms may refuse to load these keys + * and return an error of OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case + * for these alternative signing algorithms is to support devices that use + * x509 certificates for authentication when acting as a ChromeCast receiver. + * This is not needed for devices that wish to send data to a ChromeCast. + * + * If the first four bytes of the buffer enc_rsa_key are not the string + * “SIGN”, then the default value of allowed_schemes = 1 (kSign_RSASSA_PSS) + * will be used. + * + * Verification and Algorithm: + * The following checks should be performed. If any check fails, an error is + * returned, and the key is not loaded. + * 1. Verify that in_wrapped_rsa_key_length is large enough to hold the + * rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise. + * 2. Verify that the nonce matches one generated by a previous call to + * OEMCrypto_GenerateNonce(). The matching nonce shall be removed from the + * nonce table. If there is no matching nonce, return + * OEMCRYPTO_ERROR_INVALID_NONCE. + * 3. Decrypt encrypted_message_key with the OEM certificate’s private RSA key + * using RSA-OAEP into the buffer message_key. This message key is a 128 bit + * AES key used only in step 4. This message_key should be kept in secure + * memory and protected from the user. + * 4. Decrypt enc_rsa_key into the buffer rsa_key using the message_key, which + * was found in step 3. Use enc_rsa_key_iv as the initial vector for + * AES_128-CBC mode, with PKCS#5 padding. The rsa_key should be kept in + * secure memory and protected from the user. + * 5. If the first four bytes of the buffer rsa_key are the string “SIGN”, + * then the actual RSA key begins on the 9th byte of the buffer. The second + * four bytes of the buffer is the 32 bit field “allowed_schemes”, of type + * RSA_Padding_Scheme, which is used in OEMCrypto_GenerateRSASignature. + * The value of allowed_schemes must also be wrapped with RSA key. We + * recommend storing the magic string “SIGN” with the key to distinguish keys + * that have a value for allowed_schemes from those that should use the + * default allowed_schemes. Devices that do not support the alternative + * signing algorithms may refuse to load these keys and return an error of + * OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these alternative + * signing algorithms is to support devices that use X.509 certificates for + * authentication when acting as a ChromeCast receiver. This is not needed + * for devices that wish to send data to a ChromeCast. + * 6. If the first four bytes of the buffer rsa_key are not the string “SIGN”, + * then the default value of allowed_schemes = 1 (kSign_RSASSA_PSS) will be + * used. + * 7. After possibly skipping past the first 8 bytes signifying the allowed + * signing algorithm, the rest of the buffer rsa_key contains an RSA device + * key in PKCS#8 binary DER encoded format. The OEMCrypto library shall + * verify that this RSA key is valid. + * 8. Re-encrypt the device RSA key with an internal key (such as the OEM key + * or Widevine Keybox key) and the generated IV using AES-128-CBC with PKCS#5 + * padding. + * 9. Copy the rewrapped key to the buffer specified by wrapped_rsa_key and + * the size of the wrapped key to wrapped_rsa_key_length. + * + * Parameters: + * session (in) - crypto session identifier. + * nonce (in) - The nonce provided in the provisioning response. + * encrypted_message_key (in) - message_key encrypted by private key + * - from OEM cert. + * encrypted_message_key_length (in) - length of encrypted_message_key in + * - bytes. + * enc_rsa_key (in) - Encrypted device private RSA key received from + * - the provisioning server. Format is PKCS#8 + * - binary DER encoded, encrypted with message_key, + * - using AES-128-CBC with PKCS#5 + * - padding. Encrypted by message_key. + * enc_rsa_key_length (in) - length of the encrypted RSA key, in bytes. + * enc_rsa_key_iv (in) - IV for decrypting RSA key. Size is 128 bits. + * wrapped_rsa_key (out) - pointer to buffer in which encrypted RSA key + * - should be stored. May be null on the first call + * - in order to find required buffer size. + * wrapped_rsa_key_length (in/out) - length of the encrypted RSA key, in + * - bytes. + * + * Threading: + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. + * + * Returns: + * OEMCrypto_SUCCESS success + * OEMCrypto_ERROR_NO_DEVICE_KEY + * OEMCrypto_ERROR_INVALID_SESSION + * OEMCrypto_ERROR_INVALID_RSA_KEY + * OEMCrypto_ERROR_SIGNATURE_FAILURE + * OEMCrypto_ERROR_INVALID_NONCE + * OEMCrypto_ERROR_SHORT_BUFFER + * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. + * + * Version: + * This method is new in API version 12. + */ +OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( + OEMCrypto_SESSION session, const uint32_t* nonce, + const uint8_t* encrypted_message_key, size_t encrypted_message_key_length, + const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, + const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, + size_t* wrapped_rsa_key_length); /* * OEMCrypto_RewrapDeviceRSAKey * * Description: - * Verifies an RSA provisioning response is valid and corresponds to the previous - * provisioning request by checking the nonce. The RSA private key is decrypted - * and stored in secure memory. The RSA key is then re-encrypted and signed for - * storage on the filesystem. We recommend that the OEM use an encryption key - * and signing key generated using an algorithm at least as strong as that in - * GenerateDerivedKeys. + * This function is similar to RewrapDeviceRSAKey30, except it uses session + * keys derived from the keybox instead of the OEM certificate. Verifies an + * RSA provisioning response is valid and corresponds to the previous + * provisioning request by checking the nonce. The RSA private key is + * decrypted and stored in secure memory. The RSA key is then re-encrypted + * and signed for storage on the filesystem. We recommend that the OEM use + * an encryption key and signing key generated using an algorithm at least as + * strong as that in GenerateDerivedKeys. * - * After decrypting enc_rsa_key, If the first four bytes of the buffer are the - * string "SIGN", then the actual RSA key begins on the 9th byte of the buffer. - * The second four bytes of the buffer is the 32 bit field "allowed_schemes", - * of type RSA_Padding_Scheme, which is used in OEMCrypto_GenerateRSASignature. The - * value of allowed_schemes must also be wrapped with RSA key. We recommend - * storing the magic string "SIGN" with the key to distinguish keys that have a - * value for allowed_schemes from those that should use the default - * allowed_schemes. Devices that do not support the alternative signing - * algorithms may refuse to load these keys and return an error of - * OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these alternative - * signing algorithms is to support devices that use x509 certificates for - * authentication when acting as a ChromeCast receiver. This is not needed for - * devices that wish to send data to a ChromeCast. + * After decrypting enc_rsa_key, If the first four bytes of the buffer are + * the string “SIGN”, then the actual RSA key begins on the 9th byte of the + * buffer. The second four bytes of the buffer is the 32 bit field + * “allowed_schemes”, of type RSA_Padding_Scheme, which is used in + * OEMCrypto_GenerateRSASignature. The value of allowed_schemes must also + * be wrapped with RSA key. We recommend storing the magic string “SIGN” with + * the key to distinguish keys that have a value for allowed_schemes from + * those that should use the default allowed_schemes. Devices that do not + * support the alternative signing algorithms may refuse to load these keys + * and return an error of OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case + * for these alternative signing algorithms is to support devices that use + * x509 certificates for authentication when acting as a ChromeCast receiver. + * This is not needed for devices that wish to send data to a ChromeCast. * - * If the first four bytes of the buffer enc_rsa_key are not the string "SIGN", - * then the default value of allowed_schemes = 1 will be used. + * If the first four bytes of the buffer enc_rsa_key are not the string + * “SIGN”, then the default value of allowed_schemes = 1 (kSign_RSASSA_PSS) + * will be used. * - * Verification: - * The following checks should be performed. If any check fails, an error is + * Verification and Algorithm: + * The following checks should be performed. If any check fails, an error is * returned, and the key is not loaded. - * 1. Check that all the pointer values passed into it are within the buffer - * specified by message and message_length. - * 2. Verify that in_wrapped_rsa_key_length is large enough to hold the rewrapped - * key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise. - * 3. Verify that the nonce matches one generated by a previous call to - * OEMCrypto_GenerateNonce(). The matching nonce shall be removed from the nonce - * table. If there is no matching nonce, return OEMCRYPTO_ERROR_INVALID_NONCE. - * 4. Verify the message signature, using the derived signing key - * (mac_key[server]). - * 5. Decrypt enc_rsa_key using the derived encryption key (enc_key), and - * enc_rsa_key_iv. - * 6. Validate the decrypted RSA device key by verifying that it can be loaded by - * the RSA implementation. - * 7. Generate a random initialization vector and store it in - * wrapped_rsa_key_iv. - * 8. Re-encrypt the device RSA key with an internal key (such as the OEM key or - * Widevine Keybox key) and the generated IV using AES-128-CBC with PKCS#5 + * 1. Check that all the pointer values passed into it are within the buffer + * specified by message and message_length. + * 2. Verify that in_wrapped_rsa_key_length is large enough to hold the + * rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise. + * 3. Verify that the nonce matches one generated by a previous call to + * OEMCrypto_GenerateNonce(). The matching nonce shall be removed from the + * nonce table. If there is no matching nonce, return + * OEMCRYPTO_ERROR_INVALID_NONCE. + * 4. Verify the message signature, using the derived signing key + * (mac_key[server]) from a previous call to OEMCrypto_GenerateDerivedKeys. + * 5. Decrypt enc_rsa_key in the buffer rsa_key using the derived encryption + * key (enc_key) from a previous call to OEMCrypto_GenerateDerivedKeys. Use + * enc_rsa_key_iv as the initial vector for AES_128-CBC mode, with PKCS#5 + * padding. The rsa_key should be kept in secure memory and protected from + * the user. + * 6. If the first four bytes of the buffer rsa_key are the string “SIGN”, then + * the actual RSA key begins on the 9th byte of the buffer. The second four + * bytes of the buffer is the 32 bit field “allowed_schemes”, of type + * RSA_Padding_Scheme, which is used in OEMCrypto_GenerateRSASignature. + * The value of allowed_schemes must also be wrapped with RSA key. We + * recommend storing the magic string “SIGN” with the key to distinguish keys + * that have a value for allowed_schemes from those that should use the + * default allowed_schemes. Devices that do not support the alternative + * signing algorithms may refuse to load these keys and return an error of + * OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these alternative + * signing algorithms is to support devices that use X.509 certificates for + * authentication when acting as a ChromeCast receiver. This is not needed + * for devices that wish to send data to a ChromeCast. + * 7. If the first four bytes of the buffer rsa_key are not the string “SIGN”, + * then the default value of allowed_schemes = 1 (kSign_RSASSA_PSS) will be + * used. + * 8. After possibly skipping past the first 8 bytes signifying the allowed + * signing algorithm, the rest of the buffer rsa_key contains an RSA device + * key in PKCS#8 binary DER encoded format. The OEMCrypto library shall + * verify that this RSA key is valid. + * 9. Re-encrypt the device RSA key with an internal key (such as the OEM key + * or Widevine Keybox key) and the generated IV using AES-128-CBC with PKCS#5 * padding. - * 9. Copy the rewrapped key to the buffer specified by wrapped_rsa_key and the - * size of the wrapped key to wrapped_rsa_key_length. + * 10. Copy the rewrapped key to the buffer specified by wrapped_rsa_key and + * the size of the wrapped key to wrapped_rsa_key_length. * * Parameters: * session (in) - crypto session identifier. @@ -1435,15 +1763,16 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, * - encryption key, using AES-128-CBC with PKCS#5 * - padding. * enc_rsa_key_length (in) - length of the encrypted RSA key, in bytes. - * enc_rsa_key_iv (in) - IV for decrypting RSA key. Size is 128 bits. + * enc_rsa_key_iv (in) - IV for decrypting RSA key. Size is 128 bits. * wrapped_rsa_key (out) - pointer to buffer in which encrypted RSA key - * - should be stored. May be null on the first call + * - should be stored. May be null on the first call * - in order to find required buffer size. - * wrapped_rsa_key_length (in/out) - length of the encrypted RSA key, in bytes. + * wrapped_rsa_key_length (in/out) - length of the encrypted RSA key, in + * - bytes. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -1455,41 +1784,43 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, - const uint32_t *nonce, - const uint8_t* enc_rsa_key, - size_t enc_rsa_key_length, - const uint8_t* enc_rsa_key_iv, - uint8_t* wrapped_rsa_key, - size_t *wrapped_rsa_key_length); +OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, const uint32_t* nonce, + const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, + const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, + size_t* wrapped_rsa_key_length); /* * OEMCrypto_LoadDeviceRSAKey * * Description: - * Loads a wrapped RSA private key to secure memory for use by this session in - * future calls to OEMCrypto_GenerateRSASignature. The wrapped RSA key will be - * the one verified and wrapped by OEMCrypto_RewrapDeviceRSAKey. The RSA private - * key should be stored in secure memory. + * Loads a wrapped RSA private key to secure memory for use by this session + * in future calls to OEMCrypto_GenerateRSASignature. The wrapped RSA key + * will be the one verified and wrapped by OEMCrypto_RewrapDeviceRSAKey. The + * RSA private key should be stored in secure memory. * - * If the bit field "allowed_schemes" was wrapped with this RSA key, its value - * will be loaded and stored with the RSA key. If there was not bit field - * wrapped with the RSA key, the key will use a default value of 1 = RSASSA-PSS - * with SHA1. + * If the bit field "allowed_schemes" was wrapped with this RSA key, its + * value will be loaded and stored with the RSA key. If there was not bit + * field wrapped with the RSA key, the key will use a default value of 1 = + * RSASSA-PSS with SHA1. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and the RSA key is not loaded. - * 1. The wrapped key has a valid signature, as described in RewrapDeviceRSAKey. + * 1. The wrapped key has a valid signature, as described in + * RewrapDeviceRSAKey. * 2. The decrypted key is a valid private RSA key. * 3. If a value for allowed_schemes is included with the key, it is a valid * value. @@ -1498,15 +1829,15 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, * session (in) - crypto session identifier. * wrapped_rsa_key (in) - wrapped device RSA key stored on the device. * - Format is PKCS#8, binary DER encoded, and - * - encrypted with a key internal to the OEMCrypto - * - instance, using AES-128-CBC with PKCS#5 - * - padding. This is the wrapped key generated - * - by OEMCrypto_RewrapDeviceRSAKey. + * - encrypted with a key internal to the + * - OEMCrypto instance, using AES-128-CBC with + * - PKCS#5 padding. This is the wrapped key + * - generated by OEMCrypto_RewrapDeviceRSAKey. * wrapped_rsa_key_length (in) - length of the wrapped key buffer, in bytes. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -1528,10 +1859,10 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, * * Description: - * Temporarily use the standard test RSA key. This function is only required + * Temporarily use the standard test RSA key. This function is only required * for platforms that do not use a keybox, but have an RSA certificate baked - * in. This allows a standard suite of unit tests to be run on a production - * device without permanently changing the certificate. This RSA key will + * in. This allows a standard suite of unit tests to be run on a production + * device without permanently changing the certificate. This RSA key will * persist until the next call to OEMCrypto_Terminate or * OEMCrypto_Initialize. * @@ -1546,7 +1877,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, * * Threading * This function is not called simultaneously with any other functions. - * It will be called just after OEMCrypto_Initialize(). + * It will be called just after OEMCrypto_OpenSession(). * * Version * This method is added in API version 10. @@ -1557,35 +1888,44 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey(); * OEMCrypto_GenerateRSASignature * * Description: - * The OEMCrypto_GenerateRSASignature method is used to sign messages using the - * device private RSA key, specifically, it is used to sign the initial license - * request. Refer to the License Request Signed by RSA Certificate section above - * for more details. + * The OEMCrypto_GenerateRSASignature method is used to sign messages using + * the device private RSA key, specifically, it is used to sign the initial + * license request. Refer to the License Request Signed by RSA Certificate + * section above for more details. * - * For devices that wish to be CAST receivers, there is a new RSA padding scheme. - * The padding_scheme parameter indicates which hashing and padding is to be - * applied to the message so as to generate the encoded message (the + * If this function is called after OEMCrypto_LoadDeviceRSAKey for the same + * session, then this function should use the device RSA key that was loaded. + * If this function is called after a call to + * OEMCrypto_GetOEMPublicCertificate for the same session, then this function + * should use the RSA private key associated with the OEM certificate. The + * only padding scheme that is valid for the OEM certificate is + * 0x1 - RSASSA-PSS with SHA1. Any other padding scheme must generate an + * error. + * + * For devices that wish to be CAST receivers, there is a new RSA padding + * scheme. The padding_scheme parameter indicates which hashing and padding + * is to be applied to the message so as to generate the encoded message (the * modulus-sized block to which the integer conversion and RSA decryption is * applied). The following values are defined: * 0x1 - RSASSA-PSS with SHA1. * 0x2 - PKCS1 with block type 1 padding (only). * - * In the first case, a hash algorithm (SHA1) is first applied to the message, - * whose length is not otherwise restricted. In the second case, the "message" is - * already a digest, so no further hashing is applied, and the message_length can - * be no longer than 83 bytes. If the message_length is greater than 83 bytes - * OEMCrypto_ERROR_SIGNATURE_FAILURE shall be returned. + * In the first case, a hash algorithm (SHA1) is first applied to the + * message, whose length is not otherwise restricted. In the second case, the + * "message" is already a digest, so no further hashing is applied, and the + * message_length can be no longer than 83 bytes. If the message_length is + * greater than 83 bytes OEMCrypto_ERROR_SIGNATURE_FAILURE shall be returned. * * The second padding scheme is for devices that use x509 certificates for - * authentication. The main example is devices that work as a Cast receiver, like - * a ChromeCast, not for devices that wish to send to the Cast device, such as - * almost all Android devices. OEMs that do not support x509 certificate - * authentication need not implement the second scheme and can return - * OEMCrypto_ERROR_NOT_IMPLEMENTED. + * authentication. The main example is devices that work as a Cast receiver, + * like a ChromeCast, not for devices that wish to send to the Cast device, + * such as almost all Android devices. OEMs that do not support x509 + * certificate authentication need not implement the second scheme and can + * return OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Verification: * The bitwise AND of the parameter padding_scheme and the RSA key’s - * allowed_schemes is computed. If this value is 0, then the signature is not + * allowed_schemes is computed. If this value is 0, then the signature is not * computed and the error OEMCrypto_ERROR_INVALID_RSA_KEY is returned. * * Parameters: @@ -1602,8 +1942,8 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey(); * padding_scheme (in) - specify which scheme to use for the signature. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -1615,16 +1955,20 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey(); * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_NOT_IMPLEMENTED - if algorithm > 0, and the device does not * support that algorithm. + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - uint8_t* signature, - size_t *signature_length, - RSA_Padding_Scheme padding_scheme); +OEMCryptoResult OEMCrypto_GenerateRSASignature( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + uint8_t* signature, size_t* signature_length, + RSA_Padding_Scheme padding_scheme); /* * OEMCrypto_DeriveKeysFromSessionKey @@ -1636,34 +1980,37 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session, * * This function is similar to OEMCrypto_GenerateDerivedKeys, except that it * uses a session key to generate the secondary keys instead of the Widevine - * Keybox device key. These two keys will be stored in secure memory until - * the next call to LoadKeys. The session key is passed in encrypted by the + * Keybox device key. These two keys will be stored in secure memory until + * the next call to LoadKeys. The session key is passed in encrypted by the * device RSA public key, and must be decrypted with the RSA private key - * before use. Once the enc_key and mac_keys have been generated, all calls + * before use. Once the enc_key and mac_keys have been generated, all calls * to LoadKeys and RefreshKeys proceed in the same manner for license * requests using RSA or using a Widevine keybox token. * * Verification: * If the RSA key’s allowed_schemes is not kSign_RSASSA_PSS, then no keys are - * derived and the error OEMCrypto_ERROR_INVALID_RSA_KEY is returned. An RSA key - * cannot be used for both deriving session keys and also for PKCS1 signatures. + * derived and the error OEMCrypto_ERROR_INVALID_RSA_KEY is returned. An RSA + * key cannot be used for both deriving session keys and also for PKCS1 + * signatures. * * Parameters: * session (in) - crypto session identifier. - * enc_session_key (in) - session key, encrypted with the device RSA key - * - (from the device certifcate) using RSA-OAEP. + * enc_session_key (in) - session key, encrypted with the device RSA + * - key (from the device certifcate) using + * - RSA-OAEP. * enc_session_key_length (in) - length of session_key, in bytes. * mac_key_context (in) - pointer to memory containing context data for * - computing the HMAC generation key. - * mac_key_context_length (in) - length of the HMAC key context data, in bytes. + * mac_key_context_length (in) - length of the HMAC key context data, in + * - bytes. * enc_key_context (in) - pointer to memory containing context data for * - computing the encryption key. * enc_key_context_length (in) - length of the encryption key context data, in * - bytes. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -1672,32 +2019,35 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session, * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support message sizes of at least 8 KiB. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(OEMCrypto_SESSION session, - const uint8_t* enc_session_key, - size_t enc_session_key_length, - const uint8_t *mac_key_context, - size_t mac_key_context_length, - const uint8_t *enc_key_context, - size_t enc_key_context_length); - +OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( + OEMCrypto_SESSION session, const uint8_t* enc_session_key, + size_t enc_session_key_length, const uint8_t* mac_key_context, + size_t mac_key_context_length, const uint8_t* enc_key_context, + size_t enc_key_context_length); /* * OEMCrypto_APIVersion() * * Description: - * This function returns the current API version number. Because this + * This function returns the current API version number. Because this * API is part of a shared library, the version number allows the calling * application to avoid version mis-match errors. * * There is a possibility that some API methods will be backwards compatible, * or backwards compatible at a reduced security level. * - * There is no plan to introduce forward-compatibility. Applications will reject - * a library with a newer version of the API. + * There is no plan to introduce forward-compatibility. Applications will + * reject a library with a newer version of the API. * * Parameters: * none @@ -1742,10 +2092,10 @@ uint8_t OEMCrypto_Security_Patch_Level(); * This function returns the security level of the OEMCrypto library. * * Since this function is spoofable, it is not relied on for security - * purposes. It is for information only. + * purposes. It is for information only. * * Returns: - * A null terminated string. Useful values are "L1", "L2" or "L3". + * A null terminated string. Useful values are "L1", "L2" or "L3". * * Threading: * This function may be called simultaneously with any other functions. @@ -1759,12 +2109,12 @@ const char* OEMCrypto_SecurityLevel(); * OEMCrypto_GetHDCPCapability() * * Description: - * Returns the maximum HDCP version supported by the device, and the HDCP version - * supported by the device and any connected display. + * Returns the maximum HDCP version supported by the device, and the HDCP + * version supported by the device and any connected display. * * Parameters: - * current (out) - this is the current HDCP version, based on the device itself, - * and the display to which it is connected. + * current (out) - this is the current HDCP version, based on the device + * itself, and the display to which it is connected. * maximum (out) - this is the maximum supported HDCP version for the device, * ignoring any attached device. * @@ -1778,16 +2128,17 @@ const char* OEMCrypto_SecurityLevel(); * Version: * This method changed in API version 10. */ -OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, - OEMCrypto_HDCP_Capability *maximum); +OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability* current, + OEMCrypto_HDCP_Capability* maximum); /* * OEMCrypto_SupportsUsageTable() * * Description: - * This is used to determine if the device can support a usage table. Since this - * function is spoofable, it is not relied on for security purposes. It is for - * information only. The usage table is described in the section above. + * This is used to determine if the device can support a usage table. Since + * this function is spoofable, it is not relied on for security purposes. It + * is for information only. The usage table is described in the section + * above. * * Parameters: * none @@ -1796,7 +2147,8 @@ OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, * This function may be called simultaneously with any other functions. * * Returns: - * Returns true if the device can maintain a usage table. Returns false otherwise. + * Returns true if the device can maintain a usage table. Returns false + * otherwise. * * Version: * This method changed in API version 9. @@ -1809,7 +2161,7 @@ bool OEMCrypto_SupportsUsageTable(); * Description: * Indicate whether there is hardware protection to prevent the rollback of - * the usage table. For example, this is true if the usage table is stored + * the usage table. For example, this is true if the usage table is stored * entirely on a secure file system that the user cannot read or write to. * Another example is if the usage table has a generation number and the * generation number is stored in secure memory that is not user accessible. @@ -1850,7 +2202,7 @@ bool OEMCrypto_IsAntiRollbackHwPresent(); * Version: * This method is added in API version 10. */ -OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t *count); +OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count); /* * OEMCRYPTO_GetMaxNumberOfSessions() @@ -1862,6 +2214,10 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t *count); * depends on a dynamically allocated shared resource, the returned value * should be a best estimate of the maximum number of sessions. * + * OEMCrypto shall support a minimum of 10 sessions. Some applications use + * multiple sessions to pre-fetch licenses, so high end devices should + * support more sessions -- we recommend a minimum of 50 sessions. + * * Parameters: * maximum (out) - the maximum number of OEMCrypto sessions supported by the * device. @@ -1876,7 +2232,7 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t *count); * Version: * This method is added in API version 10. */ -OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max); +OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* max); /* * OEMCrypto_Generic_Encrypt @@ -1884,29 +2240,30 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max); * Description: * This function encrypts a generic buffer of data using the current key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update the - * time_of_last_decrypt. If the status of the entry is "unused", then change the - * status to "active" and set the time_of_first_decrypt. + * If the session has an entry in the Usage Table, then OEMCrypto will update + * the time_of_last_decrypt. If the status of the entry is "unused", then + * change the status to "active" and set the time_of_first_decrypt. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and the data is not encrypted. - * 1. The control bit for the current key shall have the Allow_Encrypt set. If - * not, return OEMCrypto_ERROR_UNKNOWN_FAILURE. - * 2. If the current key’s control block has a nonzero Duration field, then the - * API shall verify that the duration is greater than the session’s elapsed time - * clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. - * 3. If the current session has an entry in the Usage Table, and the status of - * that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. + * 1. The control bit for the current key shall have the Allow_Encrypt + * set. If not, return OEMCrypto_ERROR_UNKNOWN_FAILURE. + * 2. If the current key’s control block has a nonzero Duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. + * 3. If the current session has an entry in the Usage Table, and the status + * of that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. * * Parameters: * session (in) - crypto session identifier. * in_buffer (in) - pointer to memory containing data to be encrypted. * buffer_length (in) - length of the buffer, in bytes. - * iv (in) - IV for encrypting data. Size is specified by the algorithm. + * iv (in) - IV for encrypting data. Size is specified by the algorithm. * algorithm (in) - Specifies which encryption algorithm to use. See * OEMCrypto_Algorithm for valid values. - * out_buffer (out) - pointer to buffer in which encrypted data should be stored. + * out_buffer (out) - pointer to buffer in which encrypted data should be + * stored. * * Returns: * OEMCrypto_SUCCESS success @@ -1915,6 +2272,13 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max); * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic + * crypto operations. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Threading: * This function may be called simultaneously with functions on other sessions, @@ -1923,12 +2287,9 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max); * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, - const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer); +OEMCryptoResult OEMCrypto_Generic_Encrypt( + OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, + const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer); /* * OEMCrypto_Generic_Decrypt @@ -1936,35 +2297,37 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, * Description: * This function decrypts a generic buffer of data using the current key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update the - * time_of_last_decrypt. If the status of the entry is "unused", then change the - * status to "active" and set the time_of_first_decrypt. + * If the session has an entry in the Usage Table, then OEMCrypto will update + * the time_of_last_decrypt. If the status of the entry is "unused", then + * change the status to "active" and set the time_of_first_decrypt. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and the data is not decrypted. - * 1. The control bit for the current key shall have the Allow_Decrypt set. If + * 1. The control bit for the current key shall have the Allow_Decrypt set. If * not, return OEMCrypto_ERROR_DECRYPT_FAILED. * 2. If the current key’s control block has the Data_Path_Type bit set, then * return OEMCrypto_ERROR_DECRYPT_FAILED. - * 3. If the current key’s control block has a nonzero Duration field, then the - * API shall verify that the duration is greater than the session’s elapsed time + * 3. If the current key’s control block has a nonzero Duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time * clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. - * 4. If the current session has an entry in the Usage Table, and the status of - * that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. + * 4. If the current session has an entry in the Usage Table, and the status + * of that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. * * Parameters: * session (in) - crypto session identifier. * in_buffer (in) - pointer to memory containing data to be encrypted. - * buffer_length (in) - length of the buffer, in bytes. The algorithm may + * buffer_length (in) - length of the buffer, in bytes. The algorithm may * restrict buffer_length to be a multiple of block size. - * iv (in) - IV for encrypting data. Size is 128 bits. + * iv (in) - IV for encrypting data. Size is 128 bits. * algorithm (in) - Specifies which encryption algorithm to use. - * out_buffer (out) - pointer to buffer in which decrypted data should be stored. + * out_buffer (out) - pointer to buffer in which decrypted data should be + * stored. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -1974,16 +2337,20 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic + * crypto operations. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, - const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer); +OEMCryptoResult OEMCrypto_Generic_Decrypt( + OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, + const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer); /* * OEMCrypto_Generic_Sign @@ -1991,17 +2358,17 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, * Description: * This function signs a generic buffer of data using the current key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update the - * time_of_last_decrypt. If the status of the entry is "unused", then change the - * status to "active" and set the time_of_first_decrypt. + * If the session has an entry in the Usage Table, then OEMCrypto will update + * the time_of_last_decrypt. If the status of the entry is "unused", then + * change the status to "active" and set the time_of_first_decrypt. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned, and the data is not signed. * 1. The control bit for the current key shall have the Allow_Sign set. - * 2. If the current key’s control block has a nonzero Duration field, then the - * API shall verify that the duration is greater than the session’s elapsed time - * clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. + * 2. If the current key’s control block has a nonzero Duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. * 3. If the current session has an entry in the Usage Table, and the status of * that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. * @@ -2010,26 +2377,34 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, * in_buffer (in) - pointer to memory containing data to be encrypted. * buffer_length (in) - length of the buffer, in bytes. * algorithm (in) - Specifies which algorithm to use. - * signature (out) - pointer to buffer in which signature should be stored. May - * be null on the first call in order to find required buffer size. + * signature (out) - pointer to buffer in which signature should be + * stored. May be null on the first call in order to find required buffer + * size. * signature_length (in/out) - (in) length of the signature buffer, in bytes. * (out) actual length of the signature * * * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_KEY_EXPIRED - * OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to hold - * the output signature. + * OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to + * hold the output signature. * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic + * crypto operations. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. @@ -2048,24 +2423,25 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * This function verifies the signature of a generic buffer of data using the * current key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update the - * time_of_last_decrypt. If the status of the entry is "unused", then change the - * status to "active" and set the time_of_first_decrypt. + * If the session has an entry in the Usage Table, then OEMCrypto will update + * the time_of_last_decrypt. If the status of the entry is "unused", then + * change the status to "active" and set the time_of_first_decrypt. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned. * 1. The control bit for the current key shall have the Allow_Verify set. * 2. The signature of the message shall be computed, and the API shall verify - * the computed signature matches the signature passed in. If not, return + * the computed signature matches the signature passed in. If not, return * OEMCrypto_ERROR_SIGNATURE_FAILURE. - * 3. The signature verification shall use a constant-time algorithm (a signature - * mismatch will always take the same time as a successful comparison). - * 4. If the current key’s control block has a nonzero Duration field, then the - * API shall verify that the duration is greater than the session’s elapsed time - * clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. - * 5. If the current session has an entry in the Usage Table, and the status of - * that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. + * 3. The signature verification shall use a constant-time algorithm (a + * signature mismatch will always take the same time as a successful + * comparison). + * 4. If the current key’s control block has a nonzero Duration field, then + * the API shall verify that the duration is greater than the session’s + * elapsed time clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED. + * 5. If the current session has an entry in the Usage Table, and the status + * of that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION. * * Parameters: * session (in) - crypto session identifier. @@ -2076,8 +2452,8 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * signature_length (in) - length of the signature buffer, in bytes. * * Threading: - * This function may be called simultaneously with functions on other sessions, - * but not with other functions on this session. + * This function may be called simultaneously with functions on other + * sessions, but not with other functions on this session. * * Returns: * OEMCrypto_SUCCESS success @@ -2087,6 +2463,13 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic + * crypto operations. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. * * Version: * This method changed in API version 9. @@ -2098,15 +2481,14 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, const uint8_t* signature, size_t signature_length); - /* * OEMCrypto_UpdateUsageTable * * Description: - * OEMCrypto should propagate values from all open sessions to the Session Usage - * Table. If any values have changed, increment the generation number, sign, and - * save the table. During playback, this function will be called approximately - * once per minute. + * OEMCrypto should propagate values from all open sessions to the Session + * Usage Table. If any values have changed, increment the generation number, + * sign, and save the table. During playback, this function will be called + * approximately once per minute. * * Devices that do not implement a Session Usage Table may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. @@ -2131,10 +2513,11 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable(); * OEMCrypto_DeactivateUsageEntry * * Description: - * Find the entry in the Usage Table with a matching PST. Mark the status of - * that entry as "inactive". If it corresponds to an open session, the status of - * that session will also be marked as "inactive". Then OEMCrypto will increment - * Usage Table’s generation number, sign, encrypt, and save the Usage Table. + * Find the entry in the Usage Table with a matching PST. Mark the status of + * that entry as "inactive". If it corresponds to an open session, the status + * of that session will also be marked as "inactive". Then OEMCrypto will + * increment Usage Table’s generation number, sign, encrypt, and save the + * Usage Table. * * If no entry in the Usage Table has a matching PST, return the error * OEMCrypto_ERROR_INVALID_CONTEXT. @@ -2154,11 +2537,17 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable(); * OEMCrypto_ERROR_INVALID_CONTEXT - no entry has matching PST. * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support pst sizes of at least 255 bytes. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * too large. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, +OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst, size_t pst_length); /* @@ -2171,15 +2560,15 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, * If no entry in the Usage Table has a matching PST, return the error * OEMCrypto_ERROR_INVALID_CONTEXT. * - * OEMCrypto will increment Usage Table’s generation number, sign, encrypt, and - * save the Usage Table. This is done, even though the table has not changed, so - * that a single rollback cannot undo a call to DeactivateUsageEntry and still - * report that license as inactive. + * OEMCrypto will increment Usage Table’s generation number, sign, encrypt, + * and save the Usage Table. This is done, even though the table has not + * changed, so that a single rollback cannot undo a call to + * DeactivateUsageEntry and still report that license as inactive. * - * The pst_report is filled out by subtracting the times un the Usage Table from - * the current time on the secure clock. This is done in case the secure clock - * is not using UTC time, but is instead using something like seconds since clock - * installed. + * The pst_report is filled out by subtracting the times un the Usage Table + * from the current time on the secure clock. This is done in case the secure + * clock is not using UTC time, but is instead using something like seconds + * since clock installed. * * Valid values for status are: * 0 = kUnused -- the keys have not been used to decrypt. @@ -2188,25 +2577,25 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, * * The clock_security_level is reported as follows: * 0 = Insecure Clock - clock just uses system time. - * 1 = Secure Timer - clock uses secure timer, which cannot be modified by user - * software, when OEMCrypto is active and the system time when OEMCrypto is - * inactive. - * 2 = Software Secure Clock - clock cannot be modified by user software when - * OEMCrypto is active or inactive. - * 3 = Hardware Secure Clock - clock cannot be modified by user software and - * there are security features that prevent the user from modifying the clock - * in hardware, such as a tamper proof battery. + * 1 = Secure Timer - clock uses secure timer, which cannot be modified by + * user software, when OEMCrypto is active and the system time when + * OEMCrypto is inactive. + * 2 = Software Secure Clock - clock cannot be modified by user software + * when OEMCrypto is active or inactive. + * 3 = Hardware Secure Clock - clock cannot be modified by user software + * and there are security features that prevent the user from modifying the + * clock in hardware, such as a tamper proof battery. * - * After pst_report has been filled in, the HMAC SHA1 signature is computed for - * the buffer from bytes 20 to the end of the pst field. The signature is - * computed using the client_mac_key which is stored in the usage table. The + * After pst_report has been filled in, the HMAC SHA1 signature is computed + * for the buffer from bytes 20 to the end of the pst field. The signature is + * computed using the client_mac_key which is stored in the usage table. The * HMAC SHA1 signature is used to prevent a rogue application from using * OMECrypto_GenerateSignature to forge a Usage Report. * - * This function also copies the client_mac_key and server_mac_key from the Usage - * Table entry to the session. They will be used to verify a signature in - * OEMCrypto_DeleteUsageEntry below. This session will be associated with the - * entry in the Usage Table. + * This function also copies the client_mac_key and server_mac_key from the + * Usage Table entry to the session. They will be used to verify a signature + * in OEMCrypto_DeleteUsageEntry below. This session will be associated with + * the entry in the Usage Table. * * Devices that do not implement a Session Usage Table may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. @@ -2215,8 +2604,9 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, * session (in) - handle for the session to be used. * pst (in) - pointer to memory containing Provider Session Token. * pst_length (in) - length of the pst, in bytes. - * buffer (out) - pointer to buffer in which usage report should be stored. May - * be null on the first call in order to find required buffer size. + * buffer (out) - pointer to buffer in which usage report should be + * stored. May be null on the first call in order to find required buffer + * size. * buffer_length (in/out) - (in) length of the report buffer, in bytes. * (out) actual length of the report * @@ -2225,34 +2615,39 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, * * Returns: * OEMCrypto_SUCCESS success - * OEMCrypto_ERROR_SHORT_BUFFER if report buffer is not large enough to hold the - * output signature. + * OEMCrypto_ERROR_SHORT_BUFFER if report buffer is not large enough to hold + * the output signature. * OEMCrypto_ERROR_INVALID_SESSION no open session with that id. * OEMCrypto_ERROR_INVALID_CONTEXT - no entry has matching PST. * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support pst sizes of at least 255 bytes. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * too large. * * Version: * This method changed in API version 9. */ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, - const uint8_t *pst, - size_t pst_length, - OEMCrypto_PST_Report *buffer, - size_t *buffer_length); + const uint8_t* pst, size_t pst_length, + OEMCrypto_PST_Report* buffer, + size_t* buffer_length); /* * OEMCrypto_DeleteUsageEntry * * Description: - * This function verifies the signature of the given message using the sessions - * mac_key[server] and the algorithm HMAC-SHA256, and then deletes an entry from - * the session table. The session should already be associated with the given - * entry, from a previous call to OEMCrypto_ReportUsage. + * This function verifies the signature of the given message using the + * sessions mac_key[server] and the algorithm HMAC-SHA256, and then deletes + * an entry from the session table. The session should already be associated + * with the given entry, from a previous call to OEMCrypto_ReportUsage. * - * After performing all verification listed below, and deleting the entry from - * the Usage Table, OEMCrypto will increment Usage Table’s generation number, and - * then sign, encrypt, and save the Usage Table. + * After performing all verification listed below, and deleting the entry + * from the Usage Table, OEMCrypto will increment Usage Table’s generation + * number, and then sign, encrypt, and save the Usage Table. * * The signature verification shall use a constant-time algorithm (a signature * mismatch will always take the same time as a successful comparison). @@ -2261,18 +2656,18 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, * OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Verification: - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned. - * 1. The pointer pst is not null, and points inside the message. If not, return - * OEMCrypto_ERROR_UNKNOWN_FAILURE. - * 2. The signature of the message shall be computed, and the API shall verify - * the computed signature matches the signature passed in. The signature will be - * computed using HMAC-SHA256 and the mac_key_server. If they do not match, - * return OEMCrypto_ERROR_SIGNATURE_FAILURE. - * 3. If the session is not associated with an entry in the Usage Table, return - * OEMCrypto_ERROR_UNKNOWN_FAILURE. - * 4. If the pst passed in as a parameter does not match that in the Usage Table, + * 1. The pointer pst is not null, and points inside the message. If not, * return OEMCrypto_ERROR_UNKNOWN_FAILURE. + * 2. The signature of the message shall be computed, and the API shall + * verify the computed signature matches the signature passed in. The + * signature will be computed using HMAC-SHA256 and the mac_key_server. If + * they do not match, return OEMCrypto_ERROR_SIGNATURE_FAILURE. + * 3. If the session is not associated with an entry in the Usage Table, + * return OEMCrypto_ERROR_UNKNOWN_FAILURE. + * 4. If the pst passed in as a parameter does not match that in the Usage + * Table, return OEMCrypto_ERROR_UNKNOWN_FAILURE. * * Parameters: * session (in) - handle for the session to be used. @@ -2292,18 +2687,20 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, * OEMCrypto_ERROR_SIGNATURE_FAILURE * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support pst sizes of at least 255 bytes. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * too large. * * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, - const uint8_t* pst, - size_t pst_length, - const uint8_t *message, - size_t message_length, - const uint8_t *signature, - size_t signature_length); - +OEMCryptoResult OEMCrypto_DeleteUsageEntry( + OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length, + const uint8_t* message, size_t message_length, const uint8_t* signature, + size_t signature_length); /* * OEMCrypto_ForceDeleteUsageEntry @@ -2313,16 +2710,17 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, * used for stale entries without a signed request from the server. * * After performing all verification listed below, and deleting the entry from - * the Usage Table, OEMCrypto will increment the Usage Table’s generation number, - * and then sign, encrypt, and save the Usage Table. + * the Usage Table, OEMCrypto will increment the Usage Table’s generation + * number, and then sign, encrypt, and save the Usage Table. * * Devices that do not implement a Session Usage Table may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Verification - * The following checks should be performed. If any check fails, an error is + * The following checks should be performed. If any check fails, an error is * returned. - * 1) The pointer pst is not null. If not, return OEMCrypto_ERROR_UNKNOWN_FAILURE. + * 1) The pointer pst is not null. If not, return + * OEMCrypto_ERROR_UNKNOWN_FAILURE. * * Parameters * pst (in) - pointer to memory containing Provider Session Token. @@ -2332,6 +2730,12 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_BUFFER_TOO_LARGE + * + * Buffer Sizes + * OEMCrypto shall support pst sizes of at least 255 bytes. + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * too large. * * Threading * This function will not be called simultaneously with any session functions. @@ -2347,8 +2751,9 @@ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, * * Description: * This is called when the CDM system believes there are major problems or - * resource issues. The entire table should be cleaned and a new table should be - * created. + * resource issues. The entire table should be cleaned and a new table should + * be created. This is the same as calling ForceDeleteUsageEntry on all + * entries. * * Parameters: * none