Files
whitebox/whitebox/api/license_whitebox.h
Jacob Trimble 66820d41c5 Update partner repo
This adds:
- Requires WB_RESULT_NOT_IMPLEMENTED for masked in CE
- WB_License_RemoveEntitledContentKey
- WB_License_Generic* methods
2022-11-16 11:37:39 -08:00

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_