This adds: - Requires WB_RESULT_NOT_IMPLEMENTED for masked in CE - WB_License_RemoveEntitledContentKey - WB_License_Generic* methods
863 lines
34 KiB
C
863 lines
34 KiB
C
// Copyright 2020 Google LLC. All Rights Reserved.
|
|
|
|
#ifndef WHITEBOX_API_LICENSE_WHITEBOX_H_
|
|
#define WHITEBOX_API_LICENSE_WHITEBOX_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "api/result.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// The opaque type representing a single white-box instance.
|
|
typedef struct WB_License_Whitebox WB_License_Whitebox;
|
|
|
|
typedef enum {
|
|
WB_CIPHER_MODE_CTR,
|
|
WB_CIPHER_MODE_CBC,
|
|
} WB_CipherMode;
|
|
|
|
typedef enum {
|
|
WB_KEY_QUERY_TYPE_SIGNING_KEY,
|
|
WB_KEY_QUERY_TYPE_CONTENT_KEY,
|
|
WB_KEY_QUERY_TYPE_GENERIC_KEY,
|
|
} WB_KeyQueryType;
|
|
|
|
typedef enum {
|
|
WB_KCB_FLAGS_ALLOW_ENCRYPT = (1u << 8),
|
|
WB_KCB_FLAGS_ALLOW_DECRYPT = (1u << 7),
|
|
WB_KCB_FLAGS_ALLOW_SIGN = (1u << 6),
|
|
WB_KCB_FLAGS_ALLOW_VERIFY = (1u << 5),
|
|
|
|
WB_KCB_FLAGS_GENERIC_MASK = 0x1e0,
|
|
WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT = 26,
|
|
WB_KCB_FLAGS_SECURITY_LEVEL_MASK = 0x3 << WB_KCB_FLAGS_SECURITY_LEVEL_SHIFT,
|
|
} WB_KcbFlags;
|
|
|
|
typedef enum {
|
|
// The key was found in the license but there was something wrong it and could
|
|
// not be loaded.
|
|
WB_KEY_STATUS_INVALID,
|
|
|
|
// The key was found in the license and can be used with
|
|
// |WB_License_SignRenewalRequest()| and with
|
|
// |WB_License_VerifyRenewalResponse()|.
|
|
WB_KEY_STATUS_SIGNING_KEY_VALID,
|
|
|
|
// The key was found in the license. However, the permisions of the key are
|
|
// different depending on its status.
|
|
//
|
|
// | DECRYPT | MASKED DECRYPT |
|
|
// ---------------+---------+----------------+
|
|
// VALID | No | No |
|
|
// MASKED_DECRYPT | No | Yes |
|
|
// DECRYPT | Yes | Yes |
|
|
WB_KEY_STATUS_CONTENT_KEY_VALID,
|
|
WB_KEY_STATUS_CONTENT_KEY_MASKED_DECRYPT,
|
|
WB_KEY_STATUS_CONTENT_KEY_DECRYPT,
|
|
} WB_KeyStatus;
|
|
|
|
typedef enum {
|
|
// The license response uses single key - the license signing and encryption
|
|
// key are the same.
|
|
WB_LICENSE_KEY_MODE_SINGLE_KEY,
|
|
|
|
// The license response uses two keys - the license signing and encryption
|
|
// key are different.
|
|
WB_LICENSE_KEY_MODE_DUAL_KEY,
|
|
} WB_LicenseKeyMode;
|
|
|
|
// Creates a new white-box instance using the implementation's internal private
|
|
// key|. A pointer to the white-box instance will be returned via |whitebox|.
|
|
//
|
|
// Args:
|
|
// whitebox_init_data (in): The white-box initialization data for Provider
|
|
// Keys.
|
|
//
|
|
// whitebox_init_data_size (in): The number of bytes in whitebox_init_data.
|
|
//
|
|
// whitebox (out) : The output parameter used to return the new white-box
|
|
// instance.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the white-box instance was successfully created.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null.
|
|
//
|
|
// WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated.
|
|
WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
|
size_t whitebox_init_data_size,
|
|
WB_License_Whitebox** whitebox);
|
|
|
|
// Releases all resources used by the white-box instance pointed to by
|
|
// |whitebox|.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : A pointer to a white-box instance. Passing in null will
|
|
// result in a no-op.
|
|
void WB_License_Delete(WB_License_Whitebox* whitebox);
|
|
|
|
// Signs a license request using the CDM's private signing key.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : A pointer to the current white-box instance.
|
|
//
|
|
// license_request (in) : The license request in serialized form.
|
|
//
|
|
// license_request_size (in) : The number of bytes in the license_request.
|
|
//
|
|
// signature (out) : The generated signature for |license_request|. This can be
|
|
// null if |*signature_size| is 0; this should return
|
|
// WB_RESULT_BUFFER_TOO_SMALL and fill |signature_size|.
|
|
//
|
|
// signature_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |signature|. As output, |signature_size| is set to
|
|
// the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the signature was successfully generated.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |license_request| was
|
|
// null, if |license_request_size| was zero, if |signature| was null, or if
|
|
// |signature_size| was null.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |signature_size| (as input) was less than the
|
|
// required size.
|
|
WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* license_request,
|
|
size_t license_request_size,
|
|
uint8_t* signature,
|
|
size_t* signature_size);
|
|
|
|
// Verifies a license response using HMAC and the server signing key.
|
|
//
|
|
// Extracts and loads content and signing keys for use. Any content keys that
|
|
// exceed the security levels permitted by the instance, will be thrown away,
|
|
// but the key ids are retained (see WB_RESULT_INSUFFICIENT_PERMISSIONS ). All
|
|
// non-content keys and non-signing keys will be thrown away.
|
|
//
|
|
// This function can only be called once per white-box instance. To parse a new
|
|
// license response, a new white-box instance must be used.
|
|
//
|
|
// Args:
|
|
// whitebox (in/out) : The white-box instance that will load the keys.
|
|
//
|
|
// license_key_mode (in) : Signal for which private key to use when processing
|
|
// the license response. When |license_key_mode| is
|
|
// WB_LICENSE_KEY_MODE_SINGLE_KEY, the signing key should be used to decrypt
|
|
// the session key. When |license_key_mode| is WB_LICENSE_KEY_MODE_DUAL_KEY the
|
|
// encryption key should be used to decrypt the session key..
|
|
//
|
|
// core_message (in) : Serialized information communicating the structure of
|
|
// |message|. Signature verification should be done on |core_message| +
|
|
// |message|.
|
|
//
|
|
// core_message_size (in) : The number of bytes in |core_message|. If this is
|
|
// zero, it means that there was no meta message provided for the message.
|
|
//
|
|
// message (in) : The message field of the license response.
|
|
//
|
|
// message_size (in) : The number of bytes in |message|.
|
|
//
|
|
// signature (in) : The signature field of the license response.
|
|
//
|
|
// signature_size (in) : The number of bytes in |signature|.
|
|
//
|
|
// session_key (in) : The session key field of the license response.
|
|
//
|
|
// session_key_size (in) : The number of bytes in |session_key|.
|
|
//
|
|
// provider_key_id (in) : The Provider Key Id. If it is 0 or invalid, it falls
|
|
// back to no Provider Key; otherwise, the indexed Provider Key is used to
|
|
// decrypt the Content Key after it is decrypted by Key Encryption Key.
|
|
//
|
|
// license_request (in) : The license request that was sent in order to get the
|
|
// license response.
|
|
//
|
|
// license_request_size (in) : The number of bytes in |license_request|.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the response was verified and the keys were loaded into
|
|
// |whitebox|.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |core_message| was
|
|
// null, if |message| was null, if |message_size| was zero, if |message| did
|
|
// not conform to the expected format, if |signature| was null, if
|
|
// |signature_size| was incorrect, if |session_key| was null, if
|
|
// |session_key_size| was incorrect, if |license_request| was null, or if
|
|
// |license_request_size| was zero.
|
|
//
|
|
// WB_RESULT_INVALID_SIGNATURE if |message|'s signature does not match
|
|
// |signature| or if |session_key| could not be unwrapped correctly (and
|
|
// interferes with verification).
|
|
//
|
|
// WB_RESULT_INVALID_STATE if a license has already been loaded.
|
|
//
|
|
// Notes:
|
|
// We allow a modified session key to be used. Using it will cause message
|
|
// verification to fail (therefore we return WB_RESULT_INVALID_SIGNATURE).
|
|
// Doing this was found to allow for better hardening of the license processing
|
|
// code.
|
|
//
|
|
// When using proto-buf parsing, if a key is missing the key control block,
|
|
// the behaviour is undefined. The two preferrable results are:
|
|
// 1. The key is considered value and is loaded.
|
|
// 2. The key is considered invalid and is not loaded.
|
|
WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
|
WB_LicenseKeyMode license_key_mode,
|
|
const uint8_t* core_message,
|
|
size_t core_message_size,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
const uint8_t* signature,
|
|
size_t signature_size,
|
|
const uint8_t* session_key,
|
|
size_t session_key_size,
|
|
size_t provider_key_id,
|
|
const uint8_t* license_request,
|
|
size_t license_request_size);
|
|
|
|
// Loads a content key using a previously loaded entitlement key. The key data
|
|
// is a normal 128-bit AES content key. The key data is encrypted with an
|
|
// entitlement key that was loaded from the license using 256-bit AES-CBC.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : An initialized white-box instance.
|
|
//
|
|
// key_data (in) : The content key data.
|
|
//
|
|
// key_data_size (in) : The number of bytes in |key_data|.
|
|
//
|
|
// iv (in) : The initialization vector for the encrypted key data.
|
|
//
|
|
// iv_size (in) : The number of bytes in |iv|.
|
|
//
|
|
// entitlement_key_id (in) : The ID of the entitlement key the key data is
|
|
// encrypted with.
|
|
//
|
|
// entitlement_key_id_size (in) : The number of bytes in |entitlement_key_id|.
|
|
//
|
|
// content_key_id (in) : The ID of the new content key.
|
|
//
|
|
// content_key_id_size (in) : The number of bytes in |content_key_id|.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the key was loaded successfully.
|
|
//
|
|
// WB_INVALID_PARAMETER if any of the pointers are null or if there is another
|
|
// content key loaded with the same key ID.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if the requested entitlement key was not in the
|
|
// license.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
|
const uint8_t* entitlement_key_id,
|
|
size_t entitlement_key_id_size,
|
|
const uint8_t* content_key_id,
|
|
size_t content_key_id_size,
|
|
const uint8_t* iv,
|
|
size_t iv_size,
|
|
const uint8_t* key_data,
|
|
size_t key_data_size);
|
|
|
|
// Removes a content key that was previously loaded from an entitlement key.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : An initialized white-box instance.
|
|
//
|
|
// content_key_id (in) : The ID of the content key.
|
|
//
|
|
// content_key_id_size (in) : The number of bytes in |content_key_id|.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the key was loaded successfully.
|
|
//
|
|
// WB_INVALID_PARAMETER if any of the pointers are null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if the requested key was not added.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_RemoveEntitledContentKey(WB_License_Whitebox* whitebox,
|
|
const uint8_t* content_key_id,
|
|
size_t content_key_id_size);
|
|
|
|
// Queries the white-box to know whether or not the white-box loaded a specific
|
|
// key and to know what operations can be performed with that key.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : An initialized white-box instance.
|
|
//
|
|
// key_type (in) : The type of key being queried.
|
|
//
|
|
// key_id (in) : The content key id. Only required when |key_type| is
|
|
// WB_KEY_QUERY_TYPE_CONTENT_KEY, otherwise it will be ignored. Validation
|
|
// rules are not enforced when this value is ignored.
|
|
//
|
|
// key_id_size (in) : The number of bytes in the key id. Only required when
|
|
// |key_type| is WB_KEY_QUERY_TYPE_CONTENT_KEY, otherwise it will be ignored.
|
|
// Validation constraints are not enforced when this value is ignored.
|
|
//
|
|
// key_state (out) : A pointer to a key state object that should be filled in
|
|
// with the key state information.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if the key was present in the license and |key_state| was
|
|
// populated with information about the key.
|
|
//
|
|
// WB_INVALID_PARAMETER if |whitebox| was null, key_id is null and key_type is
|
|
// WB_KEY_QUERY_TYPE_CONTENT_KEY, when key_id is zero and key_type is
|
|
// WB_KEY_QUERY_TYPE_CONTENT_KEY, or |key_state| was null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if the requested key was not in the license.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
//
|
|
// Notes:
|
|
// Since the white-box can skip invalid/malformed content keys,
|
|
// WB_License_QueryKeyState() provides a means to know which keys we
|
|
// successfully loaded.
|
|
WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
|
|
WB_KeyQueryType type,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
WB_KeyStatus* key_status);
|
|
|
|
// Signs |message| and return the signature via |signature| using HMAC-SHA256
|
|
// and the client renewal signing key
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box instance containing the signing key.
|
|
//
|
|
// message (in) : The message that should be signed.
|
|
//
|
|
// message_size (in) : The number of bytes in |message|.
|
|
//
|
|
// signature (out) : The output parameter used to return the signature. This
|
|
// can be null if |*signature_size| is 0; this should return
|
|
// WB_RESULT_BUFFER_TOO_SMALL and fill |signature_size|.
|
|
//
|
|
// signature_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |signature|. As output, |signature_size| is set to
|
|
// the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |message| was successfully signed.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |message| was null,
|
|
// if |message_size| was zero, if |signature| was null, or if |signature_size|
|
|
// was null.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |signature_size| (as input) was less than the
|
|
// required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
|
WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
uint8_t* signature,
|
|
size_t* signature_size);
|
|
|
|
// Signs |message| and return the signature via |signature| using HMAC-SHA1 and
|
|
// the client renewal signing key
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box instance containing the signing key.
|
|
//
|
|
// message (in) : The message that should be signed.
|
|
//
|
|
// message_size (in) : The number of bytes in |message|.
|
|
//
|
|
// signature (out) : The output parameter used to return the signature. This
|
|
// can be null if |*signature_size| is 0; this should return
|
|
// WB_RESULT_BUFFER_TOO_SMALL and fill |signature_size|.
|
|
//
|
|
// signature_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |signature|. As output, |signature_size| is set to
|
|
// the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |message| was successfully signed.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |message| was null,
|
|
// if |message_size| was zero, if |signature| was null, or if |signature_size|
|
|
// was null.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |signature_size| (as input) was less than the
|
|
// required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had no signing keys.
|
|
WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
uint8_t* signature,
|
|
size_t* signature_size);
|
|
|
|
// Verifies the renewal response using HMAC and the server signing key.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the server signing key.
|
|
//
|
|
// message (in) : The message that needs to be verified.
|
|
//
|
|
// message_size (in) : The number of bytes in |message|.
|
|
//
|
|
// signature (in) : The expected signature for |message|.
|
|
//
|
|
// signature_size (in) : The number of bytes in |signature|.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |message|'s signature matches |signature|.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |message| was null,
|
|
// if |message_size| was zero, if |signature| was null, of if |signature_size|
|
|
// was incorrect.
|
|
//
|
|
// WB_RESULT_INVALID_SIGNATURE if |message|'s signature did not match
|
|
// |signature|.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
const uint8_t* signature,
|
|
size_t signature_size);
|
|
|
|
// Gets the secret string needed by WB_License_Unmask() in order to unmask the
|
|
// masked decrypted content returned by WB_License_MaskedDecrypt().
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box instance that will be used for the calls to
|
|
// WB_License_MaskedDecrypt().
|
|
//
|
|
// mode (in) : The AES decryption mode that will be used for the calls to
|
|
// WB_License_MaskedDecrypt().
|
|
//
|
|
// key_id (in) : The key id that will be used for the call to
|
|
// WB_License_MaskedDecrypt(). The key id must match a key loaded in
|
|
// |whitebox|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// secret_string (out) : The output parameter used to return the secret string
|
|
// that can be passed to WB_License_Unmask(). This can be null if
|
|
// |*secret_string_size| is 0; this should return WB_RESULT_BUFFER_TOO_SMALL
|
|
// and fill |secret_string_size|.
|
|
//
|
|
// secret_string_size (in/out) : As input, this contains the max number of
|
|
// bytes that can be written to |secret_string|. As output,
|
|
// |secret_string_size| is set to the required size on WB_RESULT_OK and
|
|
// WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |key_id| matches a key from the license response and the
|
|
// secret string was written to |secret_string|.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |secret_string| was
|
|
// null, or if |secret_string_size| was null.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if |key_id| referred to a key from
|
|
// the license, but the |whitebox| was not allowed to use it.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a content key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |secret_string_size| (as input) was less than
|
|
// the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
|
|
WB_CipherMode mode,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
uint8_t* secret_string,
|
|
size_t* secret_string_size);
|
|
|
|
// Performs a generic crypto "encrypt" operation to encrypt |input_data| and
|
|
// places the result in |output_data|.
|
|
//
|
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
|
// (in-place operation).
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// input_data (in) : The ciphertext.
|
|
//
|
|
// input_data_size (in) : The number of bytes in |input_data|.
|
|
//
|
|
// iv(in) This is the IV.
|
|
//
|
|
// iv_size (in) : The number of bytes in |iv|.
|
|
//
|
|
// output_data (out) : The output parameter for the output.
|
|
//
|
|
// output_data_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |output_data|. As output, |output_data_size| is set
|
|
// to the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |output_data| was null, or if |output_data_size| was null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a generic key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |output_data_size| (as input) was less than
|
|
// the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
//
|
|
// WB_RESULT_INVALID_SIGNATURE if the |mode| is Verify and the calculated
|
|
// signature doesn't match the value given in |output_data|.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
|
// permission bit sets in the KCB to allow encrypt.
|
|
WB_Result WB_License_GenericEncrypt(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* input_data,
|
|
size_t input_data_size,
|
|
const uint8_t* iv,
|
|
size_t iv_size,
|
|
uint8_t* output_data,
|
|
size_t* output_data_size);
|
|
|
|
// Performs a generic crypto "decrypt" operation to decrypt |input_data| and
|
|
// places the result in |output_data|.
|
|
//
|
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
|
// (in-place operation).
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// input_data (in) : The ciphertext.
|
|
//
|
|
// input_data_size (in) : The number of bytes in |input_data|.
|
|
//
|
|
// iv(in) This is the IV.
|
|
//
|
|
// iv_size (in) : The number of bytes in |iv|.
|
|
//
|
|
// output_data (out) : The output parameter for the output.
|
|
//
|
|
// output_data_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |output_data|. As output, |output_data_size| is set
|
|
// to the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |output_data| was null, or if |output_data_size| was null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a generic key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |output_data_size| (as input) was less than
|
|
// the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
//
|
|
// WB_RESULT_INVALID_SIGNATURE if the |mode| is Verify and the calculated
|
|
// signature doesn't match the value given in |output_data|.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
|
// permission bit sets in the KCB to allow decrypt.
|
|
WB_Result WB_License_GenericDecrypt(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* input_data,
|
|
size_t input_data_size,
|
|
const uint8_t* iv,
|
|
size_t iv_size,
|
|
uint8_t* output_data,
|
|
size_t* output_data_size);
|
|
|
|
// Performs a generic crypto "sign" operation that takes the given message in
|
|
// |input_data| and places the signature in |output_data|.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// mode (in) : The type of generic crypto operation to perform.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// message (in) : The input message.
|
|
//
|
|
// message_data_size (in) : The number of bytes in |message|.
|
|
//
|
|
// output_data (out) : The output parameter for the plaintext.
|
|
//
|
|
// output_data_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |output_data|. As output, |output_data_size| is set
|
|
// to the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |output_data| was null, or if |output_data_size| was null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a generic key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |message_size| (as input) was less than
|
|
// the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
|
// permission bit sets in the KCB to allow sign.
|
|
WB_Result WB_License_GenericSign(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
uint8_t* output_data,
|
|
size_t* output_data_size);
|
|
|
|
// Performs a generic crypto "verify" operation that takes |message| and
|
|
// verifies the signature matches |signature|.
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// message (in) : The input message.
|
|
//
|
|
// message_size (in) : The number of bytes in |message|.
|
|
//
|
|
// signature (in) : The input signature to verify.
|
|
//
|
|
// signature_size (in) : The number of bytes in |signature|.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |output_data| was null, or if |output_data_size| was null.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a generic key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
//
|
|
// WB_RESULT_INVALID_SIGNATURE if the |mode| is Verify and the calculated
|
|
// signature doesn't match the value given in |output_data|.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if the key doesn't have the correct
|
|
// permission bit sets in the KCB to allow verify.
|
|
WB_Result WB_License_GenericVerify(const WB_License_Whitebox* whitebox,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* message,
|
|
size_t message_size,
|
|
const uint8_t* signature,
|
|
size_t signature_size);
|
|
|
|
// Decrypts |input_data| and writes the plaintext to |output_data|.
|
|
//
|
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
|
// (in-place decrypt).
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// mode (in) : The decryption algorithm that should be used to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// input_data (in) : The ciphertext.
|
|
//
|
|
// input_data_size (in) : The number of bytes in |input_data|. If |mode| is set
|
|
// to CBC, then |input_data_size| must be a multiple of 16. Regardless of mode,
|
|
// this |input_data_size| must be greater than zero.
|
|
//
|
|
// iv (in) : The iv.
|
|
//
|
|
// iv_size (in) : The number of bytes in |iv|. This must be 16.
|
|
//
|
|
// output_data (out) : The output parameter for the plaintext.
|
|
//
|
|
// output_data_size (in/out) : As input, this contains the max number of bytes
|
|
// that can be written to |output_data|. As output, |output_data_size| is set
|
|
// to the required size on WB_RESULT_OK and WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |output_data| was null, or if |output_data_size| was null.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if |key_id| referred to a key from
|
|
// the license, but the |whitebox| was not allowed to use it.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a content key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |output_data_size| (as input) was less than
|
|
// the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
|
|
WB_CipherMode mode,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* input_data,
|
|
size_t input_data_size,
|
|
const uint8_t* iv,
|
|
size_t iv_size,
|
|
uint8_t* output_data,
|
|
size_t* output_data_size);
|
|
|
|
// Decrypts |input_data| and write the obfuscated plaintext to
|
|
// |masked_output_data|. The obfuscated plaintext can be deobfuscated using
|
|
// WB_License_GetSecretString() and WB_License_Unmask().
|
|
//
|
|
// This must support |input_data| and |output_data| pointing to the same buffer
|
|
// (in-place decrypt).
|
|
//
|
|
// Args:
|
|
// whitebox (in) : The white-box containing the keys needed to decrypt
|
|
// |input_data|.
|
|
//
|
|
// mode (in) : The decryption algorithm that should be used to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id (in) : The identifier for which key in |whitebox| to use to decrypt
|
|
// |input_data|.
|
|
//
|
|
// key_id_size (in) : The number of bytes in |key_id|.
|
|
//
|
|
// input_data (in) : The ciphertext.
|
|
//
|
|
// input_data_size (in) : The number of bytes in |input_data|. If |mode| is set
|
|
// to CBC, then |input_data_size| must be a multiple of 16. Regardless of mode,
|
|
// this |input_data_size| must be greater than zero.
|
|
//
|
|
// iv (in) : The iv.
|
|
//
|
|
// iv_size (in) : The number of bytes in |iv|. This must be 16.
|
|
//
|
|
// masked_output_data (out) : The output parameter for the obfuscated
|
|
// plaintext.
|
|
//
|
|
// masked_output_data_size (in/out) : As input, this contains the max number of
|
|
// bytes that can be written to |masked_output_data|. As output,
|
|
// |masked_output_data_size| is set to the required size on WB_RESULT_OK and
|
|
// WB_RESULT_BUFFER_TOO_SMALL.
|
|
//
|
|
// Returns:
|
|
// WB_RESULT_OK if |input_data| was successfully decrypted.
|
|
//
|
|
// WB_RESULT_INVALID_PARAMETER if |whitebox| was null, if |mode| was invalid,
|
|
// if |key_id| was null, if |key_id_size| was zero, if |input_data| was null,
|
|
// if |input_data_size| was invalid, if |iv| was null, if |iv_size| was
|
|
// invalid, if |masked_output_data| was null, or if |masked_output_data_size|
|
|
// was null.
|
|
//
|
|
// WB_RESULT_INSUFFICIENT_PERMISSIONS if |key_id| referred to a key from
|
|
// the license, but the |whitebox| was not allowed to use it.
|
|
//
|
|
// WB_RESULT_KEY_UNAVAILABLE if |key_id| did not match a content key from the
|
|
// loaded license.
|
|
//
|
|
// WB_RESULT_BUFFER_TOO_SMALL if |masked_output_data_size| (as input) was less
|
|
// than the required size.
|
|
//
|
|
// WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license.
|
|
WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox,
|
|
WB_CipherMode mode,
|
|
const uint8_t* key_id,
|
|
size_t key_id_size,
|
|
const uint8_t* input_data,
|
|
size_t input_data_size,
|
|
const uint8_t* iv,
|
|
size_t iv_size,
|
|
uint8_t* masked_output_data,
|
|
size_t* masked_output_data_size);
|
|
|
|
// Unmasks a subset of the data in |masked_data| using |secret_string| and
|
|
// writes it to |unmasked_data|.
|
|
//
|
|
// The subset is denoted as |offset| (inclusive) to |offset + size| (exclusive).
|
|
// It is assumed that |offset| and |offset + size - 1| are both valid indexes
|
|
// into |masked_data|.
|
|
//
|
|
// It is assumed that indexes between 0 and |size - 1| (inclusive) are all valid
|
|
// indexes into |unmasked_data|.
|
|
//
|
|
// The memory range used for |masked_data| must not overlap with
|
|
// |unmasked_data|.
|
|
//
|
|
// Args:
|
|
// masked_data (in) : The masked data to read from.
|
|
//
|
|
// offset (in) : The index into |masked_data| from where to start reading data.
|
|
//
|
|
// size (in) : The number of bytes from |masked_data| to unmask and copy into
|
|
// |unmasked_data|.
|
|
//
|
|
// secret_string (in) : The auxiliary data for unmasking |masked_data|.
|
|
//
|
|
// secret_string_size (in) : The number of bytes in |secret_string|.
|
|
//
|
|
// unmasked_data (out) : The output buffer to write the unmasked data to.
|
|
void WB_License_Unmask(const uint8_t* masked_data,
|
|
size_t offset,
|
|
size_t size,
|
|
const uint8_t* secret_string,
|
|
size_t secret_string_size,
|
|
uint8_t* unmasked_data);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // WHITEBOX_API_LICENSE_WHITEBOX_H_
|