diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp index 66a1bd8583..fa2962ac75 100644 --- a/drm/1.2/Android.bp +++ b/drm/1.2/Android.bp @@ -9,8 +9,10 @@ hidl_interface { srcs: [ "types.hal", "ICryptoFactory.hal", + "ICryptoPlugin.hal", "IDrmFactory.hal", "IDrmPlugin.hal", + "IDrmPluginListener.hal", ], interfaces: [ "android.hardware.drm@1.0", @@ -18,8 +20,8 @@ hidl_interface { "android.hidl.base@1.0", ], types: [ - "KeySetId", "OfflineLicenseState", + "Status", ], gen_java: false, } diff --git a/drm/1.2/ICryptoPlugin.hal b/drm/1.2/ICryptoPlugin.hal new file mode 100644 index 0000000000..07006768ce --- /dev/null +++ b/drm/1.2/ICryptoPlugin.hal @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.drm@1.2; + +import @1.0::DestinationBuffer; +import @1.0::ICryptoPlugin; +import @1.0::Mode; +import @1.0::Pattern; +import @1.0::SessionId; +import @1.0::SharedBuffer; +import @1.0::SubSample; + +/** + * ICryptoPlugin is the HAL for vendor-provided crypto plugins. + * It allows crypto sessions to be opened and operated on, to + * load crypto keys for a codec to decrypt protected video content. + */ +interface ICryptoPlugin extends @1.0::ICryptoPlugin { + + /** + * Decrypt an array of subsamples from the source memory buffer to the + * destination memory buffer. + * + * decrypt_1_2() only differs from decrypt() in that additional status + * codes must be returned. + * + * @param secure a flag to indicate if a secure decoder is being used. This + * enables the plugin to configure buffer modes to work consistently with + * a secure decoder. + * @param the keyId for the key that is used to do the the decryption. The + * keyId refers to a key in the associated MediaDrm instance. + * @param iv the initialization vector to use + * @param mode the crypto mode to use + * @param pattern the crypto pattern to use + * @param subSamples a vector of subsamples indicating the number + * of clear and encrypted bytes to process. This allows the decrypt + * call to operate on a range of subsamples in a single call + * @param source the input buffer for the decryption + * @param offset the offset of the first byte of encrypted data from + * the base of the source buffer + * @param destination the output buffer for the decryption + * @return status the status of the call. The status must be OK or one + * of the following errors: + * ERROR_DRM_NO_LICENSE if no license keys have been loaded + * ERROR_DRM_LICENSE_EXPIRED if the license keys have expired + * ERROR_DRM_RESOURCE_BUSY if the resources required to perform + * the decryption are not available + * ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION if required output + * protections are not active + * ERROR_DRM_INSUFFICIENT_SECURITY if the security level of the + * device is not sufficient to meet the requirements in + * the license policy + * ERROR_DRM_FRAME_TOO_LARGE if the frame being decrypted into + * the secure output buffer exceeds the size of the buffer + * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not + * opened + * ERROR_DRM_DECRYPT if the decrypt operation fails + * ERROR_DRM_INVALID_STATE if the device is in a state where it + * is not able to perform decryption + * ERROR_DRM_CANNOT_HANDLE in other failure cases. + * + * @return bytesWritten the number of bytes output from the decryption + * @return detailedError if the error is a vendor-specific error, the + * vendor's crypto HAL may provide a detailed error string to help + * describe the error. + */ + decrypt_1_2(bool secure, uint8_t[16] keyId, uint8_t[16] iv, Mode mode, + Pattern pattern, vec subSamples, + SharedBuffer source, uint64_t offset, DestinationBuffer destination) + generates(Status status, uint32_t bytesWritten, string detailedError); +}; diff --git a/drm/1.2/IDrmPlugin.hal b/drm/1.2/IDrmPlugin.hal index 88338d6af3..88ace0b7b6 100644 --- a/drm/1.2/IDrmPlugin.hal +++ b/drm/1.2/IDrmPlugin.hal @@ -15,13 +15,19 @@ */ package android.hardware.drm@1.2; -import @1.1::IDrmPlugin; +import @1.0::KeyedVector; +import @1.0::KeyType; +import @1.0::SessionId; import @1.0::Status; +import @1.1::IDrmPlugin; +import @1.1::KeyRequestType; +import @1.2::IDrmPluginListener; /** - * IDrmPlugin is used to interact with a specific drm plugin that was created by - * IDrm::createPlugin. A drm plugin provides methods for obtaining drm keys that - * may be used by a codec to decrypt protected video content. + * IDrmPlugin is used to interact with a specific drm plugin that was + * created by IDrm::createPlugin. A drm plugin provides methods for + * obtaining drm keys to be used by a codec to decrypt protected video + * content. */ interface IDrmPlugin extends @1.1::IDrmPlugin { @@ -32,24 +38,25 @@ interface IDrmPlugin extends @1.1::IDrmPlugin { * request/response exchange when the key request KeyType is * OFFLINE. Normally each app is responsible for keeping track of * the KeySetIds it has created. In some situations however, it - * may be necessary to request the list of stored offline license + * will be necessary to request the list of stored offline license * KeySetIds. If an app loses the KeySetId for any stored licenses * that it created, for example, it must be able to recover the - * stored KeySetIds so those licenses can be removed when they + * stored KeySetIds so those licenses will be removed when they * expire or when the app is uninstalled. *

* This method returns a list of the KeySetIds for all offline - * licenses. The offline license KeySetId may be used to query + * licenses. The offline license KeySetId allows an app to query * the status of an offline license or remove it. * - * @return status the status of the call. May be OK or + * @return status the status of the call. Must be OK or * ERROR_DRM_INVALID_STATE if the HAL is in a state where the * KeySetIds can't be returned. * @return a list of offline license keySetIds. If there are no offline * licenses, the list must be empty and OK must be returned as the * status. */ - getOfflineLicenseKeySetIds() generates (Status status, vec keySetIds); + getOfflineLicenseKeySetIds() generates (@1.0::Status status, + vec keySetIds); /** * Normally offline licenses are released using a key @@ -59,20 +66,20 @@ interface IDrmPlugin extends @1.1::IDrmPlugin { * removed and then adjust the count of offline licenses allocated * to the device. *

- * In some exceptional situations it may be necessary to directly - * remove offline licenses without notifying the server, which may - * be performed using this method. + * In some exceptional situations it will be necessary to directly + * remove offline licenses without notifying the server, which is + * performed by this method. * * @param keySetId the id of the offline license to remove - * @return status the status of the call. May be one of OK on + * @return status the status of the call. Must be one of OK on * success, BAD_VALUE if the license is not found or * ERROR_DRM_INVALID_STATE if the HAL is in a state where the * KeySetIds can't be returned. */ - removeOfflineLicense(KeySetId keySetId) generates (Status status); + removeOfflineLicense(KeySetId keySetId) generates (@1.0::Status status); /** - * Request the state of an offline license. An offline license may + * Request the state of an offline license. An offline license must * be usable or inactive. The keys in a usable offline license are * available for decryption. When the offline license state is * inactive, the keys have been marked for release using @@ -81,7 +88,7 @@ interface IDrmPlugin extends @1.1::IDrmPlugin { * usable for decryption. * * @param keySetId the id of the offline license - * @return status the status of the call. May be one of OK on + * @return status the status of the call. Must be one of OK on * success, BAD_VALUE if the license is not found or * ERROR_DRM_INVALID_STATE if the HAL is in a state where the * offline license state can't be queried. @@ -89,6 +96,100 @@ interface IDrmPlugin extends @1.1::IDrmPlugin { * If the return status is not OK then state must be set to * UNKNOWN. */ - getOfflineLicenseState(KeySetId keySetId) generates (Status status, - OfflineLicenseState state); + getOfflineLicenseState(KeySetId keySetId) generates ( + @1.0::Status status, OfflineLicenseState state); + + /** + * A key request/response exchange occurs between the app and a License + * Server to obtain the keys required to decrypt the content. + * getKeyRequest_1_2() is used to obtain an opaque key request blob that is + * delivered to the license server. + * + * getKeyRequest_1_2() only differs from getKeyRequest_1_1() in that + * additional status codes must be returned. + * + * @param scope either a sessionId or a keySetId, depending on the + * specified keyType. When the keyType is OFFLINE or STREAMING, scope + * must be set to the sessionId the keys will be provided to. When the + * keyType is RELEASE, scope must be set to the keySetId of the keys + * being released. + * @param initData container-specific data, its meaning is interpreted + * based on the mime type provided in the mimeType parameter. It could + * contain, for example, the content ID, key ID or other data obtained + * from the content metadata that is required to generate the key + * request. initData must be empty when keyType is RELEASE. + * @param mimeType identifies the mime type of the content + * @param keyType specifies if the keys are to be used for streaming, + * offline or a release + * @param optionalParameters included in the key request message to + * allow a client application to provide additional message parameters + * to the server. + * @return status the status of the call. The status must be OK or one of + * the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is + * not opened, ERROR_DRM_NOT_PROVISIONED if the device requires + * provisioning before it is able to generate a key request, + * ERROR_DRM_RESOURCE_CONTENTION if client applications using the hal + * are temporarily exceeding the available crypto resources such that a + * retry of the operation is likely to succeed, ERROR_DRM_CANNOT_HANDLE + * if getKeyRequest is not supported at the time of the call, BAD_VALUE + * if any parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL + * is in a state where a key request cannot be generated. + * @return request if successful, the opaque key request blob is returned + * @return requestType indicates type information about the returned + * request. The type must be one of INITIAL, RENEWAL, RELEASE, NONE or + * UPDATE. An INITIAL request is the first key request for a + * license. RENEWAL is a subsequent key request used to refresh the + * keys in a license. RELEASE corresponds to a keyType of RELEASE, + * which indicates keys are being released. NONE indicates that no + * request is needed because the keys are already loaded. UPDATE + * indicates that the keys need to be refetched after the initial + * license request. + * @return defaultUrl the URL that the request may be sent to, if + * provided by the drm HAL. The app can choose to override this URL. + */ + getKeyRequest_1_2(vec scope, vec initData, + string mimeType, KeyType keyType, KeyedVector optionalParameters) + generates (Status status, vec request, + KeyRequestType requestType, string defaultUrl); + + /** + * A provision request/response exchange occurs between the app and a + * provisioning server to retrieve a device certificate. getProvisionRequest + * is used to obtain an opaque provisioning request blob that is delivered + * to the provisioning server. + * + * getProvisionRequest_1_2() only differs from getProvisionRequest_1_0() in + * that additional status codes must be returned. + * + * @param certificateType the type of certificate requested, e.g. "X.509" + * @param certificateAuthority identifies the certificate authority. A + * certificate authority (CA) is an entity which issues digital + * certificates for use by other parties. It is an example of a trusted + * third party. + * @return status the status of the call. The status must be OK or one of + * the following errors: ERROR_DRM_RESOURCE_CONTENTION if client + * applications using the hal are temporarily exceeding the available + * crypto resources such that a retry of the operation is likely to + * succeed, ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require + * provisioning or ERROR_DRM_INVALID_STATE if the HAL is in a state + * where the provision request cannot be generated. + * @return request if successful the opaque certificate request blob + * is returned + * @return defaultUrl URL that the provisioning request may be + * sent to, if known by the HAL implementation. An app can choose to + * override this URL. If the HAL implementation does not provide a + * defaultUrl, the returned string must be empty. + */ + getProvisionRequest_1_2(string certificateType, string certificateAuthority) + generates (Status status, vec request, string defaultUrl); + + /** + * Send a session lost state event to the listener. This event + * indicates that a session's state has become invalid because the + * device crypto hardware is incapable of retaining crypto session + * state across suspend and resume cycles. + * + * @param sessionId identifies the session the event originated from + */ + sendSessionLostState(SessionId sessionId); }; diff --git a/drm/1.2/IDrmPluginListener.hal b/drm/1.2/IDrmPluginListener.hal new file mode 100644 index 0000000000..a6bd6c9ad4 --- /dev/null +++ b/drm/1.2/IDrmPluginListener.hal @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.drm@1.2; + +import @1.0::IDrmPluginListener; +import @1.0::SessionId; + +/** + * IDrmPluginListener is a listener interface for Drm events sent from an + * IDrmPlugin instance. + */ +interface IDrmPluginListener extends @1.0::IDrmPluginListener { + /** + * Some device crypto hardware is incapable of retaining crypto + * session state across suspend and resume cycles. A + * SessionLostState event must be signaled when a session has + * become invalid for this reason. This event must not be used to + * indicate a failure in the crypto system. Closing the session + * and opening a new one must allow the application to resume + * normal use of the drm hal module. + * + * @param sessionId identifies the session that has been invalidated + */ + oneway sendSessionLostState(SessionId sessionId); +}; diff --git a/drm/1.2/types.hal b/drm/1.2/types.hal index 8770c79fc5..6e1acde083 100644 --- a/drm/1.2/types.hal +++ b/drm/1.2/types.hal @@ -16,6 +16,8 @@ package android.hardware.drm@1.2; +import @1.0::Status; + enum OfflineLicenseState : uint32_t { /** * Offline license state is unknown @@ -23,7 +25,7 @@ enum OfflineLicenseState : uint32_t { UNKNOWN, /** - * Offline license state is usable, the keys may be used for decryption. + * Offline license state is usable, the keys are usable for decryption. */ USABLE, @@ -35,6 +37,40 @@ enum OfflineLicenseState : uint32_t { INACTIVE }; +enum Status : @1.0::Status { + /** + * The drm HAL module must return ERROR_DRM_INSUFFICIENT_SECURITY + * from the crypto plugin decrypt method when the security level + * of the device is not sufficient to meet the requirements in the + * license policy. + */ + ERROR_DRM_INSUFFICIENT_SECURITY, + + /** + * The drm HAL module must return ERROR_FRAME_TOO_LARGE from the + * decrypt method when the frame being decrypted into the secure + * output buffer exceeds the size of the buffer. + */ + ERROR_DRM_FRAME_TOO_LARGE, + + /** + * This error must be returned from any session method when an + * attempt is made to use the session after the crypto hardware + * state has been invalidated. Some devices are not able to + * retain crypto session state across device suspend/resume which + * results in invalid session state. + */ + ERROR_DRM_SESSION_LOST_STATE, + + /** + * The drm HAL module must return this error if client + * applications using the hal are temporarily exceeding the + * capacity of available crypto resources such that a retry of + * the operation is likely to succeed. + */ + ERROR_DRM_RESOURCE_CONTENTION, +}; + /** * KeySetId is an identifier that references a set of keys in an * offline license. The keySetId is created by the HAL implementation