diff --git a/CHANGELOG.md b/CHANGELOG.md index 73565f0..7dfb17f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ [TOC] +## [Version 18.6][v18.6] + +This patch provides provisioning 3.0 for OEMs using OPK. Also includes bug +fixes and test improvements for ODK and OPK. + +General + +- New L3 API function OEMCrypto_WrapClearPrivateKey() for factory builds. +- New L3 API function OEMCrypto_MarkOfflineSession() for informing OEMCrypto + that a session is used for a reloaded offline license. +- Clarified HDCP level enforcement for downstream devices (see OEMCrypto + documentation). +- Small test improvement + - Skip CAS tests for non CAS devices + - Removed tests for deprecated features + +OPK TA + +- Added provisioning 3.0 support. +- Added tests for provisioning 3.0 support. +- Improved backwards compatibility for DRM key wrapping. +- Added secure clearing of buffers contain sensitive data. +- Fixed session resource freeing when closing session + - Ensures call to `OPKI_FreeSession` even if `OPKI_FreeEntitledKeySessions` + fails + ## [Version 18.5][v18.5] This is a minor release that includes a few security fixes and bug fixes. @@ -520,3 +546,4 @@ Public release for OEMCrypto API and ODK library version 16.4. [v18.3]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.3 [v18.4]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.4 [v18.5]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.5 +[v18.6]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.6 diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index e349200..bf771c1 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -3,7 +3,7 @@ // License Agreement. /** - * @mainpage OEMCrypto API v18.5 + * @mainpage OEMCrypto API v18.6 * * OEMCrypto is the low level library implemented by the OEM to provide key and * content protection, usually in a separate secure memory or process space. The @@ -719,6 +719,8 @@ typedef enum OEMCrypto_SignatureHashAlgorithm { #define OEMCrypto_FactoryInstallBCCSignature _oecc142 #define OEMCrypto_GetEmbeddedDrmCertificate _oecc143 #define OEMCrypto_UseSecondaryKey _oecc144 +#define OEMCrypto_MarkOfflineSession _oecc153 +#define OEMCrypto_WrapClearPrivateKey _oecc154 // clang-format on /// @addtogroup initcontrol @@ -3140,6 +3142,51 @@ OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void); OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id, size_t* device_id_length); +/** + * Encrypts a clear device RSA/ECC key with an internal key (such as the OEM + * key or Widevine Keybox key) and a generated IV using AES-128-CBC with PKCS#5 + * padding. + * + * Copies the wrapped key to the buffer specified by |wrapped_private_key| and + * sets the size of the wrapped key to |wrapped_private_key_length|. + * + * The clear private key is encoded in PKCS#8 binary DER format. The OEMCrypto + * library shall verify that this RSA key is valid. + * + * The clear key should be encrypted using the same device specific key used in + * OEMCrypto_LoadProvisioning. The wrapped private key will be unwrapped in the + * function OEMCrypto_LoadDRMPrivateKey. + * + * This function should only be implemented for factory builds. + * + * @param[in] clear_private_key_bytes: pointer to memory containing the + * unencrypted private key data. + * @param[in] clear_private_key_length: the length of the private key data. + * @param[out] wrapped_private_key: pointer to buffer in which the encrypted + * private key should be stored. May be null on the first call in order to + * find required buffer size. + * @param[in,out] wrapped_private_key_length: (in) length of the encrypted + * private key, in bytes. (out) actual length of the encrypted private key, + * or required length if provided length is too small. + * + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_CONTEXT clear_private_key_bytes is NULL, or + * clear private key fails to parse as PKCS#8 + * @retval OEMCrypto_ERROR_SHORT_BUFFER wrapped_private_key_length is too small, + * or wrapped_private_key is NULL + * + * @threading + * This is an "Initialization and Termination Function" and will not be + * called simultaneously with any other function, as if the CDM holds a write + * lock on the OEMCrypto system. + * + * @version + * This method is new in API version 18.6. + */ +OEMCryptoResult OEMCrypto_WrapClearPrivateKey( + const uint8_t* clear_private_key_bytes, size_t clear_private_key_length, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length); + /// @} /// @addtogroup keybox @@ -5871,11 +5918,28 @@ OEMCryptoResult OEMCrypto_GetEmbeddedDrmCertificate(uint8_t* public_cert, * * @ignore * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_SESSION_STATE_LOST + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED */ OEMCryptoResult OEMCrypto_UseSecondaryKey(OEMCrypto_SESSION session_id, bool dual_key); +/** + * Marks the given session as being used for existing offline licenses. + * + * @param[in] session: session id for operation. + * + * @ignore + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_SESSION_STATE_LOST + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + */ +OEMCryptoResult OEMCrypto_MarkOfflineSession(OEMCrypto_SESSION session); + #ifdef __cplusplus } #endif diff --git a/oemcrypto/include/level3.h b/oemcrypto/include/level3.h index cbab431..ab32177 100644 --- a/oemcrypto/include/level3.h +++ b/oemcrypto/include/level3.h @@ -119,6 +119,7 @@ #define Level3_GetDeviceSignedCsrPayload _lcc141 #define Level3_UseSecondaryKey _lcc142 #define Level3_GetEmbeddedDrmCertificate _lcc143 +#define Level3_MarkOfflineSession _lcc144 #else #define Level3_Initialize _oecc01 #define Level3_Terminate _oecc02 @@ -222,6 +223,7 @@ // Internal-only. #define Level3_GetEmbeddedDrmCertificate _oecc143 #define Level3_UseSecondaryKey _oecc144 +#define Level3_MarkOfflineSession _oecc145 #endif #define Level3_GetInitializationState _oecl3o01 @@ -498,6 +500,7 @@ OEMCryptoResult Level3_GetEmbeddedDrmCertificate(uint8_t* public_cert, size_t* public_cert_length); OEMCryptoResult Level3_UseSecondaryKey(OEMCrypto_SESSION session_id, bool dual_key); +OEMCryptoResult Level3_MarkOfflineSession(OEMCrypto_SESSION session_id); // The following are specific to Google's Level 3 implementation and are not // required. diff --git a/oemcrypto/odk/include/core_message_features.h b/oemcrypto/odk/include/core_message_features.h index 06396d5..5fd71c3 100644 --- a/oemcrypto/odk/include/core_message_features.h +++ b/oemcrypto/odk/include/core_message_features.h @@ -26,9 +26,9 @@ struct CoreMessageFeatures { // This is the published version of the ODK Core Message library. The default // behavior is for the server to restrict messages to at most this version - // number. The default is 18.5. + // number. The default is 18.6. uint32_t maximum_major_version = 18; - uint32_t maximum_minor_version = 5; + uint32_t maximum_minor_version = 6; bool operator==(const CoreMessageFeatures &other) const; bool operator!=(const CoreMessageFeatures &other) const { diff --git a/oemcrypto/odk/include/odk_structs.h b/oemcrypto/odk/include/odk_structs.h index b7d8ca0..12f9723 100644 --- a/oemcrypto/odk/include/odk_structs.h +++ b/oemcrypto/odk/include/odk_structs.h @@ -16,10 +16,10 @@ extern "C" { /* The version of this library. */ #define ODK_MAJOR_VERSION 18 -#define ODK_MINOR_VERSION 5 +#define ODK_MINOR_VERSION 6 /* ODK Version string. Date changed automatically on each release. */ -#define ODK_RELEASE_DATE "ODK v18.5 2024-03-21" +#define ODK_RELEASE_DATE "ODK v18.6 2024-06-04" /* The lowest version number for an ODK message. */ #define ODK_FIRST_VERSION 16 diff --git a/oemcrypto/odk/src/core_message_features.cpp b/oemcrypto/odk/src/core_message_features.cpp index 94a3d95..f312583 100644 --- a/oemcrypto/odk/src/core_message_features.cpp +++ b/oemcrypto/odk/src/core_message_features.cpp @@ -30,7 +30,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures( features.maximum_minor_version = 2; // 17.2 break; case 18: - features.maximum_minor_version = 5; // 18.5 + features.maximum_minor_version = 6; // 18.6 break; default: features.maximum_minor_version = 0; diff --git a/oemcrypto/odk/src/odk_timer.c b/oemcrypto/odk/src/odk_timer.c index 0b503f5..934717f 100644 --- a/oemcrypto/odk/src/odk_timer.c +++ b/oemcrypto/odk/src/odk_timer.c @@ -274,7 +274,7 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits, nonce_values->api_minor_version = 2; break; case 18: - nonce_values->api_minor_version = 5; + nonce_values->api_minor_version = 6; break; default: nonce_values->api_minor_version = 0; diff --git a/oemcrypto/odk/test/odk_test.cpp b/oemcrypto/odk/test/odk_test.cpp index c6937c3..118077e 100644 --- a/oemcrypto/odk/test/odk_test.cpp +++ b/oemcrypto/odk/test/odk_test.cpp @@ -1216,7 +1216,7 @@ std::vector TestCases() { // number. {16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5}, {17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2}, - {18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 5}, + {18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 6}, // Here are some known good versions. Make extra sure they work. {ODK_MAJOR_VERSION, 16, 3, 16, 3}, {ODK_MAJOR_VERSION, 16, 4, 16, 4}, @@ -1228,6 +1228,7 @@ std::vector TestCases() { {ODK_MAJOR_VERSION, 18, 3, 18, 3}, {ODK_MAJOR_VERSION, 18, 4, 18, 4}, {ODK_MAJOR_VERSION, 18, 5, 18, 5}, + {ODK_MAJOR_VERSION, 18, 6, 18, 6}, {0, 16, 3, 16, 3}, {0, 16, 4, 16, 4}, {0, 16, 5, 16, 5}, @@ -1235,6 +1236,7 @@ std::vector TestCases() { {0, 17, 2, 17, 2}, {0, 18, 4, 18, 4}, {0, 18, 5, 18, 5}, + {0, 18, 6, 18, 6}, }; return test_cases; } diff --git a/oemcrypto/opk/build/ree-sources.mk b/oemcrypto/opk/build/ree-sources.mk index 307dc46..6d7c67d 100644 --- a/oemcrypto/opk/build/ree-sources.mk +++ b/oemcrypto/opk/build/ree-sources.mk @@ -265,6 +265,7 @@ wtpi_unittests_sources += \ $(wtpi_unittests_dir)/ssl_util.cpp \ $(wtpi_unittests_dir)/cose_util.cpp \ $(wtpi_unittests_dir)/test_rsa_key.cpp \ + $(wtpi_unittests_dir)/legacy_keywrap_test.cpp \ $(log_dir)/log.cpp \ $(util_dir)/src/string_conversions.cpp \ $(odk_sources) \ diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto.c b/oemcrypto/opk/oemcrypto_ta/oemcrypto.c index 52eb6f0..7fd9935 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto.c +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto.c @@ -33,6 +33,7 @@ #include "wtpi_config_interface.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" +#include "wtpi_device_key_interface.h" #include "wtpi_idle_interface.h" #include "wtpi_initialize_terminate_interface.h" #include "wtpi_logging_interface.h" @@ -126,73 +127,6 @@ static bool IsSupportedAsymmetricKeyType(AsymmetricKeyType key_type) { return key_type == DRM_RSA_PRIVATE_KEY || key_type == DRM_ECC_PRIVATE_KEY; } -static OEMCryptoResult RewrapDeviceDRMKeyOEMCert( - OEMCryptoSession* session_context, const uint8_t* encrypted_message_key, - size_t encrypted_message_key_length, const uint8_t* enc_drm_key, - size_t enc_drm_key_length, const uint8_t* enc_drm_key_iv, - AsymmetricKeyType drm_key_type, uint8_t* wrapped_drm_key, - size_t wrapped_drm_key_length) { - ABORT_IF(g_opk_system_state != SYSTEM_INITIALIZED, - "OEMCrypto is not yet initialized"); - ABORT_IF(WTPI_GetProvisioningMethod() != OEMCrypto_OEMCertificate, - "This function is only valid on Provisioning 3.0 devices"); - - ABORT_IF_NULL(session_context); - ABORT_IF_NULL(encrypted_message_key); - ABORT_IF_ZERO(encrypted_message_key_length); - ABORT_IF_NULL(enc_drm_key); - ABORT_IF_ZERO(enc_drm_key_length); - ABORT_IF(enc_drm_key_length > PKCS8_DRM_KEY_MAX_SIZE, - "enc_drm_key_length of %zu is too large", enc_drm_key_length); - ABORT_IF_NULL(enc_drm_key_iv); - ABORT_IF(!IsSupportedAsymmetricKeyType(drm_key_type), - "drm_key_type %d is invalid", drm_key_type); - ABORT_IF_NULL(wrapped_drm_key); - ABORT_IF_ZERO(wrapped_drm_key_length); - - // TODO(b/225216277): implement this. - OEMCryptoResult result = OEMCrypto_ERROR_NOT_IMPLEMENTED; - - /* RSA decryption needs at most RSA_size to decrypt. 3072 is the largest size - OEM RSA keys we can use. */ - // uint8_t message_key[KEY_SIZE_3072]; - // size_t message_key_length = sizeof(message_key); - // DecryptMessageWithOEMPrivateKey( - // encrypted_message_key, encrypted_message_key_length, message_key, - // &message_key_length); - - if (result != OEMCrypto_SUCCESS) goto cleanup; - // if (message_key_length != KEY_SIZE_128) { - // /* Encryption key is expected to be an AES 128-bit key. */ - // result = OEMCrypto_ERROR_UNKNOWN_FAILURE; - // goto cleanup; - // } - - // result = OPKI_CreateKey(&session_context->encryption_key, ENCRYPTION_KEY, - // KEY_SIZE_128); - // if (result != OEMCrypto_SUCCESS) goto cleanup; - // result = WTPI_CreateKeyHandle(message_key, message_key_length, - // ENCRYPTION_KEY, - // &(session_context->encryption_key->key_handle)); - // if (result != OEMCrypto_SUCCESS) goto cleanup; - - // result = RewrapDeviceDRMKeyCommon( - // session_context, enc_drm_key, enc_drm_key_length, enc_drm_key_iv, - // drm_key_type, wrapped_drm_key, wrapped_drm_key_length); - -cleanup:; - OEMCryptoResult free_key_result = - OPKI_FreeAsymmetricKeyFromTable(&session_context->drm_private_key); - // TODO(b/225216277): When result is not OEMCrypto_ERROR_NOT_IMPLEMENTED - // above, uncomment this check. - // if (result == OEMCrypto_SUCCESS) - result = free_key_result; - free_key_result = FreeMacAndEncryptionKeys(session_context); - if (result == OEMCrypto_SUCCESS) result = free_key_result; - if (result != OEMCrypto_SUCCESS) session_context->state = SESSION_INVALID; - return result; -} - // This function contains the RewrapDeviceDRMKey code that is shared between // keybox and OEM certificate devices. static OEMCryptoResult RewrapDeviceDRMKeyCommon(OEMCryptoSession* session, @@ -264,9 +198,9 @@ static OEMCryptoResult RewrapDeviceDRMKeyCommon(OEMCryptoSession* session, return result; } - result = - WTPI_WrapAsymmetricKey(wrapped_drm_key, wrapped_drm_key_length, - drm_key_type, clear_drm_key, enc_drm_key_length); + result = WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, wrapped_drm_key, + wrapped_drm_key_length, drm_key_type, + clear_drm_key, enc_drm_key_length); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to re-wrap DRM private key with result: %u", result); return result; @@ -342,27 +276,149 @@ cleanup:; return result; } +static OEMCryptoResult DecryptMessageKeyWithOEMPrivateKey( + const uint8_t* encrypted_message_key, size_t encrypted_message_key_length, + uint8_t* message_key, size_t* message_key_length) { + ABORT_IF_NULL(encrypted_message_key); + ABORT_IF_ZERO(encrypted_message_key_length); + ABORT_IF_NULL(message_key); + ABORT_IF_NULL(message_key_length); + WTPI_AsymmetricKey_Handle oem_key_handle; + OEMCryptoResult result = + WTPI_CreateAsymmetricKeyHandleFromOEMKey(&oem_key_handle); + if (result != OEMCrypto_SUCCESS) return result; + result = WTPI_RSADecrypt(oem_key_handle, encrypted_message_key, + encrypted_message_key_length, message_key, + message_key_length); + WTPI_FreeAsymmetricKeyHandle(oem_key_handle); + return result; +} + +static OEMCryptoResult RewrapDeviceDRMKeyOEMCert( + OEMCryptoSession* session_context, const uint8_t* encrypted_message_key, + size_t encrypted_message_key_length, const uint8_t* enc_drm_key, + size_t enc_drm_key_length, const uint8_t* enc_drm_key_iv, + AsymmetricKeyType drm_key_type, uint8_t* wrapped_drm_key, + size_t wrapped_drm_key_length) { + ABORT_IF(g_opk_system_state != SYSTEM_INITIALIZED, + "OEMCrypto is not yet initialized"); + ABORT_IF(WTPI_GetProvisioningMethod() != OEMCrypto_OEMCertificate, + "This function is only valid on Provisioning 3.0 devices"); + ABORT_IF_NULL(session_context); + ABORT_IF_NULL(encrypted_message_key); + ABORT_IF_ZERO(encrypted_message_key_length); + ABORT_IF_NULL(enc_drm_key); + ABORT_IF_ZERO(enc_drm_key_length); + ABORT_IF(enc_drm_key_length > PKCS8_DRM_KEY_MAX_SIZE, + "enc_drm_key_length of %zu is too large", enc_drm_key_length); + ABORT_IF_NULL(enc_drm_key_iv); + ABORT_IF(!IsSupportedAsymmetricKeyType(drm_key_type), + "drm_key_type %d is invalid", drm_key_type); + ABORT_IF_NULL(wrapped_drm_key); + ABORT_IF_ZERO(wrapped_drm_key_length); + + /* Decrypt message key with OEM private key. */ + uint8_t message_key[KEY_SIZE_3072]; + size_t message_key_length = sizeof(message_key); + OEMCryptoResult result = DecryptMessageKeyWithOEMPrivateKey( + encrypted_message_key, encrypted_message_key_length, message_key, + &message_key_length); + if (result != OEMCrypto_SUCCESS) { + session_context->state = SESSION_INVALID; + return result; + } + + if (message_key_length != KEY_SIZE_128) { + /* Encryption key is expected to be an AES 128-bit key. */ + session_context->state = SESSION_INVALID; + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + /* Install message key and decrypt DRM private key with the message key. */ + uint8_t clear_drm_key[PKCS8_DRM_KEY_MAX_SIZE]; + result = OPKI_CreateKey(&session_context->encryption_key, ENCRYPTION_KEY, + KEY_SIZE_128); + if (result != OEMCrypto_SUCCESS) goto cleanup; + result = + WTPI_K1_CreateKeyHandle(message_key, message_key_length, ENCRYPTION_KEY, + &(session_context->encryption_key->key_handle)); + if (result != OEMCrypto_SUCCESS) goto cleanup; + result = WTPI_C1_AESCBCDecrypt( + session_context->encryption_key->key_handle, (size_t)KEY_SIZE_128, + enc_drm_key, enc_drm_key_length, enc_drm_key_iv, clear_drm_key); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to AES CBC decrypt DRM private key with result: %u", result); + goto cleanup; + } + /* Create asymmetric key handle for DRM private key in order to get the + * signature size. */ + WTPI_AsymmetricKey_Handle private_key_handle; + result = WTPI_CreateAsymmetricKeyHandle(clear_drm_key, enc_drm_key_length, + drm_key_type, &private_key_handle); + if (result != OEMCrypto_SUCCESS) { + LOGE( + "Failed to create asymmetric key handle for DRM private key with " + "result: %u", + result); + goto cleanup; + } + size_t signature_size; + result = WTPI_GetSignatureSize(private_key_handle, &signature_size); + WTPI_FreeAsymmetricKeyHandle(private_key_handle); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to get DRM key signature size with result: %u", result); + goto cleanup; + } + /* Wrap DRM private key with device key. */ + result = WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, wrapped_drm_key, + wrapped_drm_key_length, drm_key_type, + clear_drm_key, enc_drm_key_length); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to re-wrap DRM private key with result: %u", result); + goto cleanup; + } + /* Check that it's a valid DRM key. */ + result = + OPKI_LoadDRMKey(session_context, drm_key_type, wrapped_drm_key, + wrapped_drm_key_length, signature_size, kSign_RSASSA_PSS); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to load DRM key with result: %u", result); + } + +cleanup:; + memset(clear_drm_key, 0, sizeof(clear_drm_key)); + + OEMCryptoResult free_key_result = + OPKI_FreeAsymmetricKeyFromTable(&session_context->drm_private_key); + if (result == OEMCrypto_SUCCESS) result = free_key_result; + + free_key_result = FreeMacAndEncryptionKeys(session_context); + if (result == OEMCrypto_SUCCESS) result = free_key_result; + + if (result != OEMCrypto_SUCCESS) session_context->state = SESSION_INVALID; + return result; +} + static OEMCryptoResult GetDeviceID(uint8_t* device_id, size_t* device_id_length) { if (device_id_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (WTPI_GetProvisioningMethod() != OEMCrypto_Keybox && - WTPI_GetProvisioningMethod() != OEMCrypto_BootCertificateChain) { - // TODO(b/225216277): Implement this. + const OEMCrypto_ProvisioningMethod provisioning_method = + WTPI_GetProvisioningMethod(); + if (provisioning_method != OEMCrypto_Keybox && + provisioning_method != OEMCrypto_OEMCertificate && + provisioning_method != OEMCrypto_BootCertificateChain) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } size_t actual_device_id_size = 0; if (WTPI_GetDeviceIDLength(&actual_device_id_size) != OEMCrypto_SUCCESS) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (*device_id_length < actual_device_id_size) { + if (device_id == NULL || *device_id_length < actual_device_id_size) { *device_id_length = actual_device_id_size; return OEMCrypto_ERROR_SHORT_BUFFER; } - if (device_id == NULL) { - return OEMCrypto_ERROR_INVALID_CONTEXT; - } *device_id_length = actual_device_id_size; return WTPI_GetDeviceID(device_id, *device_id_length); } @@ -619,8 +675,9 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) { result = OPKI_CheckStatePreCall(session_context, API_CLOSESESSION); if (result != OEMCrypto_SUCCESS) return result; result = OPKI_FreeEntitledKeySessions(session); - if (result != OEMCrypto_SUCCESS) return result; - return OPKI_FreeSession(session); + OEMCryptoResult free_session_result = OPKI_FreeSession(session); + if (result == OEMCrypto_SUCCESS) result = free_session_result; + return result; } OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session, @@ -730,8 +787,9 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( if (session_context->drm_private_key == NULL) goto cleanup; private_key = session_context->drm_private_key; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - private_key->wrapped_key, private_key->wrapped_key_length, - private_key->key_type, &private_key_handle, &allowed_schemes); + DEVICE_KEY_WRAP_DRM_CERT, private_key->wrapped_key, + private_key->wrapped_key_length, private_key->key_type, + &private_key_handle, &allowed_schemes); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap DRM private key into key handle with result: %u", result); @@ -925,8 +983,12 @@ OEMCryptoResult OEMCrypto_PrepAndSignProvisioningRequest( &session_context->nonce_values, device_info, device_info_length, &g_counter_info); } else { - result = GetROTSignatureLength(&required_signature_size); - if (result != OEMCrypto_SUCCESS) return result; + if (provisioning_method == OEMCrypto_OEMCertificate) { + required_signature_size = MAX_ASYMMETRIC_SIGNATURE_SIZE; + } else { + result = GetROTSignatureLength(&required_signature_size); + if (result != OEMCrypto_SUCCESS) return result; + } result = ODK_PrepareCoreProvisioningRequest( message, message_length, core_message_length, &session_context->nonce_values, &g_counter_info); @@ -1234,7 +1296,7 @@ static OEMCryptoResult LoadKeysNoSignature( OEMCryptoResult result = OEMCrypto_SUCCESS; session->license_type = license_type; - session->refresh_valid = + const bool refresh_valid = IsSubstrInRange(message_length, enc_mac_keys, false) && IsSubstrInRange(message_length, enc_mac_keys_iv, false); @@ -1300,7 +1362,7 @@ static OEMCryptoResult LoadKeysNoSignature( } } if (result != OEMCrypto_SUCCESS) goto cleanup; - if (session->refresh_valid) { + if (refresh_valid) { result = OPKI_UpdateMacKeys(session, message + enc_mac_keys.offset, message + enc_mac_keys_iv.offset); if (result != OEMCrypto_SUCCESS) { @@ -1379,7 +1441,7 @@ cleanup:; OEMCryptoResult free_key_result = OPKI_FreeKeyFromTable(&session->encryption_key); if (result == OEMCrypto_SUCCESS) result = free_key_result; - if (result != OEMCrypto_SUCCESS || !session->refresh_valid) { + if (result != OEMCrypto_SUCCESS || !refresh_valid) { /* Mac keys must be freed in every case except when the call is successful AND we are given new mac keys. In that case, the new keys should be preserved in the session for future RefreshKeys calls. */ @@ -2329,29 +2391,51 @@ OEMCryptoResult OEMCrypto_Generic_Verify( } OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert( - const uint8_t* rot UNUSED, size_t rotLength UNUSED, - uint8_t* wrappedRot UNUSED, size_t* wrappedRotLength UNUSED, - const uint8_t* transportKey UNUSED, size_t transportKeyLength UNUSED) { - // TODO(fredgc, ncbray, marcone): One installation option is that there an - // installation tool that uses a system key to unwrap the keybox and then - // re-wraps it using a device key. This wrapped keybox can be stored on the - // file system. I think we don't plan to use this. If we do, then Widevine - // needs to implement this function, and we have to agree on an porting - // layer interface for: decrypt w/system key -> encrypt w/device key -> - // return buffer. - // - return OEMCrypto_ERROR_NOT_IMPLEMENTED; -} - -OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox, - size_t length) { + const uint8_t* rot, size_t rot_length, uint8_t* wrapped_rot, + size_t* wrapped_rot_length, const uint8_t* transport_key UNUSED, + size_t transport_key_length UNUSED) { // This API is only allowed in factory mode. #ifdef FACTORY_BUILD_ONLY - // TODO(b/225216277): We currently only support keyboxes. - return WTPI_UnwrapValidateAndInstallKeybox(keybox, length); + if (g_opk_system_state != SYSTEM_INITIALIZED) { + LOGE("OEMCrypto is not yet initialized"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + const OEMCrypto_ProvisioningMethod provisioning_method = + WTPI_GetProvisioningMethod(); + if (provisioning_method != OEMCrypto_OEMCertificate) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + return WTPI_WrapOEMCert(rot, rot_length, wrapped_rot, wrapped_rot_length); #else - (void)keybox; - (void)length; + (void)rot; + (void)rot_length; + (void)wrapped_rot; + (void)wrapped_rot_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif +} + +OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* rot, + size_t rot_length) { +// This API is only allowed in factory mode. +#ifdef FACTORY_BUILD_ONLY + if (g_opk_system_state != SYSTEM_INITIALIZED) { + LOGE("OEMCrypto is not yet initialized"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + RETURN_INVALID_CONTEXT_IF_NULL(rot); + const OEMCrypto_ProvisioningMethod provisioning_method = + WTPI_GetProvisioningMethod(); + if (provisioning_method == OEMCrypto_Keybox) { + return WTPI_UnwrapValidateAndInstallKeybox(rot, rot_length); + } else if (provisioning_method == OEMCrypto_OEMCertificate) { + return WTPI_UnwrapValidateAndInstallOEMCert(rot, rot_length); + } else { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } +#else + (void)rot; + (void)rot_length; return OEMCrypto_ERROR_NOT_IMPLEMENTED; #endif } @@ -2361,6 +2445,8 @@ OEMCryptoResult OEMCrypto_FactoryInstallBCCSignature(const uint8_t* signature, // This API is only allowed in factory mode. #ifdef FACTORY_BUILD_ONLY // TODO: add implementation. + (void)signature; + (void)signature_length; return OEMCrypto_ERROR_NOT_IMPLEMENTED; #else (void)signature; @@ -2385,8 +2471,7 @@ OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) { const OEMCrypto_ProvisioningMethod provisioning_method = WTPI_GetProvisioningMethod(); if (provisioning_method == OEMCrypto_OEMCertificate) { - // TODO(b/225216277): Implement this. - return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return WTPI_ValidateOEMCertAndKey(); } else if (provisioning_method == OEMCrypto_Keybox) { return WTPI_ValidateKeybox(); } else if (provisioning_method == OEMCrypto_BootCertificateChain) { @@ -2452,10 +2537,18 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer, size_t length) { return WTPI_LoadTestKeybox(buffer, length); } -OEMCryptoResult OEMCrypto_GetOEMPublicCertificate( - uint8_t* public_cert UNUSED, size_t* public_cert_length UNUSED) { - // TODO(b/225216277): implement this. - return OEMCrypto_ERROR_NOT_IMPLEMENTED; +OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert, + size_t* public_cert_length) { + if (g_opk_system_state != SYSTEM_INITIALIZED) { + LOGE("OEMCrypto is not yet initialized"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + if (WTPI_GetProvisioningMethod() != OEMCrypto_OEMCertificate) { + LOGD("This function is only valid on Provisioning 3.0 devices"); + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + RETURN_INVALID_CONTEXT_IF_NULL(public_cert_length); + return WTPI_LoadOEMPublicCertificate(public_cert, public_cert_length); } OEMCryptoResult OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session) { @@ -2485,6 +2578,7 @@ OEMCryptoResult OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session) { /* This API sets the session state to indicate that the OEM private key is * ready for use. It doesn't actually load it. It is best to load the OEM * private key in memory only when being used. */ + session_context->prov30_oem_key_loaded = true; return OPKI_SetStatePostCall(session_context, API_LOADOEMPRIVATEKEY); } @@ -2755,8 +2849,8 @@ OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(OEMCrypto_SESSION session, WTPI_AsymmetricKey_Handle private_key_handle; uint32_t allowed_schemes; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - wrapped_drm_key, wrapped_drm_key_length, drm_key_type, - &private_key_handle, &allowed_schemes); + DEVICE_KEY_WRAP_DRM_CERT, wrapped_drm_key, wrapped_drm_key_length, + drm_key_type, &private_key_handle, &allowed_schemes); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap DRM private key into key handle with result: %u", result); @@ -2840,8 +2934,9 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature( uint32_t allowed_schemes; AsymmetricKey* private_key = session_context->drm_private_key; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - private_key->wrapped_key, private_key->wrapped_key_length, - private_key->key_type, &private_key_handle, &allowed_schemes); + DEVICE_KEY_WRAP_DRM_CERT, private_key->wrapped_key, + private_key->wrapped_key_length, private_key->key_type, + &private_key_handle, &allowed_schemes); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap DRM private key into key handle with result: %u", result); @@ -2897,7 +2992,11 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( RETURN_INVALID_CONTEXT_IF_ZERO(message_length); RETURN_INVALID_CONTEXT_IF_NULL(signature); RETURN_INVALID_CONTEXT_IF_ZERO(signature_length); - if (signature_length != SHA256_DIGEST_LENGTH) { + const OEMCrypto_ProvisioningMethod provisioning_method = + WTPI_GetProvisioningMethod(); + if ((provisioning_method == OEMCrypto_Keybox || + provisioning_method == OEMCrypto_BootCertificateChain) && + signature_length != SHA256_DIGEST_LENGTH) { LOGE("signature_length is not the length of a SHA256 digest"); return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -2950,8 +3049,6 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( *wrapped_private_key_length = buffer_size; const uint8_t* message_body = message + core_message_length; - const OEMCrypto_ProvisioningMethod provisioning_method = - WTPI_GetProvisioningMethod(); // RewrapDeviceDRMKey only intended for Prov 4 with cast, or Prov 2. if (provisioning_method == OEMCrypto_Keybox || @@ -3468,10 +3565,20 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( return result; } } + + // Determine which stage of Prov 4 provisioning we are in + // Stage 1: OEM private key is NOT installed, we are requesting it. + // Stage 2: OEM private key is installed, now requesting DRM cert. + const bool is_stage1 = (session_context->prov40_oem_private_key == NULL); + const CertSignatureType requested_cert_type = + is_stage1 ? CERT_SIGNATURE_OEM : CERT_SIGNATURE_DRM; + const uint32_t wrapping_context = + is_stage1 ? DEVICE_KEY_WRAP_OEM_CERT : DEVICE_KEY_WRAP_DRM_CERT; + AsymmetricKeyType generated_key_type; result = WTPI_GenerateRandomCertificateKeyPair( - &generated_key_type, wrapped_private_key, wrapped_private_key_size, - public_key, public_key_size); + requested_cert_type, &generated_key_type, wrapped_private_key, + wrapped_private_key_size, public_key, public_key_size); if (public_key_signature == NULL || *public_key_signature_size < required_signature_size || result == OEMCrypto_ERROR_SHORT_BUFFER) { @@ -3489,10 +3596,8 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( LOGE("Invalid key_type: %d", generated_key_type); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - /* The provisioning stage is determined by whether the - * prov40_oem_private_key is installed. NOT installed: first stage; - * Installed: second stage. */ - if (session_context->prov40_oem_private_key == NULL) { + + if (is_stage1) { /* This is the first stage for obtaining an OEM leaf cert. Sign with BCC * leaf private key. */ result = @@ -3505,9 +3610,9 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( uint32_t allowed_schemes_unused; AsymmetricKey* oem_private_key = session_context->prov40_oem_private_key; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - oem_private_key->wrapped_key, oem_private_key->wrapped_key_length, - oem_private_key->key_type, &signing_key_handle, - &allowed_schemes_unused); + DEVICE_KEY_WRAP_OEM_CERT, oem_private_key->wrapped_key, + oem_private_key->wrapped_key_length, oem_private_key->key_type, + &signing_key_handle, &allowed_schemes_unused); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap OEM private key into key handle with result: %u", result); @@ -3550,8 +3655,8 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( WTPI_AsymmetricKey_Handle csr_signing_key_handle; uint32_t allowed_schemes; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - wrapped_private_key, *wrapped_private_key_size, generated_key_type, - &csr_signing_key_handle, &allowed_schemes); + wrapping_context, wrapped_private_key, *wrapped_private_key_size, + generated_key_type, &csr_signing_key_handle, &allowed_schemes); if (result != OEMCrypto_SUCCESS) { LOGE( "Failed to unwrap the CSR signing key into key handle with result: " @@ -3582,6 +3687,7 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( LOGE("Failed to create asymmetric CSR signing key with result: %u", result); return result; } + session_context->prov40_csr_keywrap_context = wrapping_context; return OPKI_SetStatePostCall(session_context, API_GENERATECERTIFICATEKEYPAIR); } @@ -3685,8 +3791,8 @@ OEMCryptoResult OEMCrypto_InstallOemPrivateKey( WTPI_AsymmetricKey_Handle private_key_handle; uint32_t allowed_schemes; result = WTPI_UnwrapIntoAsymmetricKeyHandle( - wrapped_private_key, wrapped_private_key_length, oem_key_type, - &private_key_handle, &allowed_schemes); + DEVICE_KEY_WRAP_OEM_CERT, wrapped_private_key, wrapped_private_key_length, + oem_key_type, &private_key_handle, &allowed_schemes); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap OEM private key into key handle with result: %u", result); @@ -3801,7 +3907,7 @@ OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession( break; } } // loop entitlement keys - } // loop entitled keys + } // loop entitled keys if (!key_found) { LOGE("Failed to find entitlement keys in session = %u", entitlement_session); @@ -4204,3 +4310,64 @@ OEMCryptoResult OEMCrypto_GetEmbeddedDrmCertificate( uint8_t* public_cert UNUSED, size_t* public_cert_length UNUSED) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } + +OEMCryptoResult OEMCrypto_WrapClearPrivateKey( + const uint8_t* clear_private_key_bytes, size_t clear_private_key_length, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length) { +#ifdef FACTORY_BUILD_ONLY + if (g_opk_system_state != SYSTEM_INITIALIZED) { + LOGE("OEMCrypto is not yet initialized"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + OEMCryptoResult res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + + RETURN_INVALID_CONTEXT_IF_NULL(clear_private_key_bytes); + RETURN_INVALID_CONTEXT_IF_NULL(wrapped_private_key_length); + + size_t required_size = 0; + AsymmetricKeyType key_type = DRM_RSA_PRIVATE_KEY; + + // verify clear private key format by trying to convert it into a key handle + WTPI_AsymmetricKey_Handle out_handle; + res = WTPI_CreateAsymmetricKeyHandle( + clear_private_key_bytes, clear_private_key_length, key_type, &out_handle); + WTPI_FreeAsymmetricKeyHandle(out_handle); + if (res != OEMCrypto_SUCCESS) { + // try again with ECC type + key_type = DRM_ECC_PRIVATE_KEY; + res = WTPI_CreateAsymmetricKeyHandle(clear_private_key_bytes, + clear_private_key_length, key_type, + &out_handle); + WTPI_FreeAsymmetricKeyHandle(out_handle); + if (res != OEMCrypto_SUCCESS) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + } + + res = WTPI_GetWrappedAsymmetricKeySize(clear_private_key_length, key_type, + &required_size); + if (res != OEMCrypto_SUCCESS) { + return res; + } + + if (wrapped_private_key == NULL || + *wrapped_private_key_length < required_size) { + *wrapped_private_key_length = required_size; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + res = + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, wrapped_private_key, + *wrapped_private_key_length, key_type, + clear_private_key_bytes, clear_private_key_length); + + return res; +#else + (void)clear_private_key_bytes; + (void)clear_private_key_length; + (void)wrapped_private_key; + (void)wrapped_private_key_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif +} diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h index 66d1fb0..26898fe 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h @@ -34,7 +34,7 @@ // version bumps to v17.1, the first released OPK implementation would be // v17.1.0 #define API_MAJOR_VERSION 18 -#define API_MINOR_VERSION 5 +#define API_MINOR_VERSION 6 #define OPK_PATCH_VERSION 0 #endif /* OEMCRYPTO_TA_OEMCRYPTO_API_MACROS_H_ */ diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_key_types.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_key_types.h index 0180ff8..c3288d1 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_key_types.h +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_key_types.h @@ -50,6 +50,12 @@ typedef enum AsymmetricKeyType { // TODO(b/225216277): Add OEM Cert private key. } AsymmetricKeyType; +typedef enum CertSignatureType { + CERT_SIGNATURE_OEM = (int)0x386eebf3, + CERT_SIGNATURE_DRM = (int)0x6b4684e3, + CERT_SIGNATURE_CSR = (int)0x1f37a40a, +} CertSignatureType; + /* The valid possible sizes of the crypto and private key. The name is the size in bits, while the value is the size in bytes. */ typedef enum KeySize { diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.c b/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.c index 1cb0d65..9448b65 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.c +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.c @@ -24,8 +24,10 @@ #include "wtpi_clock_interface_layer1.h" #include "wtpi_crc32_interface.h" #include "wtpi_decrypt_sample_interface.h" +#include "wtpi_device_key_interface.h" #include "wtpi_logging_interface.h" #include "wtpi_root_of_trust_interface_layer1.h" +#include "wtpi_device_key_interface.h" NO_IGNORE_RESULT static bool IsSupportedDrmKeyType(AsymmetricKeyType key_type) { return key_type == DRM_RSA_PRIVATE_KEY || key_type == DRM_ECC_PRIVATE_KEY; @@ -118,6 +120,7 @@ OEMCryptoResult OPKI_CheckStatePreCall(OEMCryptoSession* session, case API_GENERATENONCE: switch (session->state) { case (SESSION_OPENED): + case (SESSION_LOAD_OEM_RSA_KEY): case (SESSION_INSTALL_OEM_PRIVATE_KEY): case (SESSION_LOAD_DRM_RSA_KEY): return OEMCrypto_SUCCESS; @@ -627,37 +630,51 @@ OEMCryptoResult OPKI_GenerateCertSignature(OEMCryptoSession* session, signature == NULL || signature_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (signature_type == CERT_SIGNATURE_OEM) { - // TODO(b/225216277): implement this. - // return SignMessageWithOEMPrivateKey(message, message_length, signature, - // signature_length); - return OEMCrypto_ERROR_NOT_IMPLEMENTED; - } - + AsymmetricKeyType key_type; AsymmetricKey* signing_key; + uint32_t wrapping_context; if (signature_type == CERT_SIGNATURE_DRM) { + // DRM cert (prov20, prov30, or prov40) if (!DRMKeyMaySign(session->drm_private_key)) return OEMCrypto_ERROR_INVALID_KEY; signing_key = session->drm_private_key; + key_type = signing_key->key_type; + wrapping_context = DEVICE_KEY_WRAP_DRM_CERT; } else if (signature_type == CERT_SIGNATURE_CSR) { + // Prov40 OEM cert, RSA or ECC if (!DRMKeyMaySign(session->prov40_csr_signing_key)) return OEMCrypto_ERROR_INVALID_KEY; signing_key = session->prov40_csr_signing_key; + key_type = signing_key->key_type; + wrapping_context = session->prov40_csr_keywrap_context; + } else if (signature_type == CERT_SIGNATURE_OEM) { + // Prov30 OEM cert, RSA only + // For Prov30, signing key handle is directly loaded from the secure + // storage. The oemcrypto session doesn't hold the key. + key_type = DRM_RSA_PRIVATE_KEY; + wrapping_context = DEVICE_KEY_WRAP_OEM_CERT; } else { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - WTPI_AsymmetricKey_Handle signing_key_handle; - uint32_t allowed_schemes; - OEMCryptoResult result = WTPI_UnwrapIntoAsymmetricKeyHandle( - signing_key->wrapped_key, signing_key->wrapped_key_length, - signing_key->key_type, &signing_key_handle, &allowed_schemes); - if (result != OEMCrypto_SUCCESS) { - LOGE("Failed to unwrap signing key into key handle with result: %u", - result); - return result; + OEMCryptoResult result = OEMCrypto_SUCCESS; + if (signature_type == CERT_SIGNATURE_OEM) { + result = WTPI_CreateAsymmetricKeyHandleFromOEMKey(&signing_key_handle); + if (result != OEMCrypto_SUCCESS) return result; + } else { + // For prov20 or prov40, signing key handle is created from |signing_key|, + // which has already been loaded in the session. + uint32_t allowed_schemes; + result = WTPI_UnwrapIntoAsymmetricKeyHandle(wrapping_context, + signing_key->wrapped_key, signing_key->wrapped_key_length, + signing_key->key_type, &signing_key_handle, &allowed_schemes); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to unwrap signing key into key handle with result: %u", + result); + return result; + } } - if (signing_key->key_type == DRM_RSA_PRIVATE_KEY) { + if (key_type == DRM_RSA_PRIVATE_KEY) { result = WTPI_RSASign(signing_key_handle, message, message_length, signature, signature_length, kSign_RSASSA_PSS); } else { @@ -674,12 +691,27 @@ NO_IGNORE_RESULT OEMCryptoResult OPKI_GetSessionSignatureHashAlgorithm( if (!session) return OEMCrypto_ERROR_UNKNOWN_FAILURE; const AsymmetricKey* key; + uint32_t context; if (session->drm_private_key != NULL) { key = session->drm_private_key; + context = DEVICE_KEY_WRAP_DRM_CERT; } else if (session->prov40_oem_private_key != NULL) { key = session->prov40_oem_private_key; + context = DEVICE_KEY_WRAP_OEM_CERT; } else if (session->prov40_csr_signing_key != NULL) { key = session->prov40_csr_signing_key; + context = session->prov40_csr_keywrap_context; + } else if (session->prov30_oem_key_loaded) { + // Create OEM key handle on the fly for prov30 since it is not held by + // the session. + WTPI_AsymmetricKey_Handle key_handle; + OEMCryptoResult result = + WTPI_CreateAsymmetricKeyHandleFromOEMKey(&key_handle); + if (result != OEMCrypto_SUCCESS) return result; + result = WTPI_GetSignatureHashAlgorithm(key_handle, DRM_RSA_PRIVATE_KEY, + hash_algorithm); + WTPI_FreeAsymmetricKeyHandle(key_handle); + return result; } else { LOGE("No asymmetric keys loaded."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -688,8 +720,8 @@ NO_IGNORE_RESULT OEMCryptoResult OPKI_GetSessionSignatureHashAlgorithm( WTPI_AsymmetricKey_Handle key_handle; uint32_t ignored; OEMCryptoResult result = WTPI_UnwrapIntoAsymmetricKeyHandle( - key->wrapped_key, key->wrapped_key_length, key->key_type, &key_handle, - &ignored); + context, key->wrapped_key, key->wrapped_key_length, key->key_type, + &key_handle, &ignored); if (result != OEMCrypto_SUCCESS) { LOGE("Failed to unwrap key into key handle with result: %u", result); return result; diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.h index 4714159..36c3fe4 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.h +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_session.h @@ -10,6 +10,7 @@ #include "oemcrypto_compiler_attributes.h" #include "oemcrypto_entitled_key_session.h" #include "oemcrypto_key.h" +#include "oemcrypto_key_types.h" #include "wtpi_config_interface.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" @@ -74,12 +75,6 @@ typedef enum OEMCryptoSessionAPI { API_GETKEYHANDLE = (int)0x81aac42f, } OEMCryptoSessionAPI; -typedef enum CertSignatureType { - CERT_SIGNATURE_OEM = (int)0x386eebf3, - CERT_SIGNATURE_DRM = (int)0x6b4684e3, - CERT_SIGNATURE_CSR = (int)0x1f37a40a, -} CertSignatureType; - typedef struct OEMCryptoSession { OEMCrypto_SESSION session_id; OEMCryptoSessionState state; @@ -91,10 +86,10 @@ typedef struct OEMCryptoSession { * it is the generated OEM private key. For stage 2, it is the generated DRM * private key. */ AsymmetricKey* prov40_csr_signing_key; + uint32_t prov40_csr_keywrap_context; SymmetricKey* mac_key_server; SymmetricKey* mac_key_client; SymmetricKey* encryption_key; - bool refresh_valid; OEMCrypto_LicenseType license_type; uint32_t current_content_key_index; SymmetricKey* content_keys[CONTENT_KEYS_PER_SESSION]; @@ -112,16 +107,13 @@ typedef struct OEMCryptoSession { uint8_t license_request_hash[ODK_SHA256_HASH_SIZE]; /* |decrypt_hash| is only used by hash validation for content key session. */ DecryptHash decrypt_hash; - /* If |recent_decrypt| is true, then a usage report cannot be generated - * without first updating the usage entry. It should be set to true whenever a - * key is used. */ - bool recent_decrypt; /* The bare minimum state check to double-confirm that at most one call of * each of these function categories can be made during the lifetime of a * session. This is also enforced by the OPK session state machine. */ bool nonce_created; bool request_signed; bool response_loaded; + bool prov30_oem_key_loaded; } OEMCryptoSession; /* Initializes session context. diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h index eedbae9..2463edd 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h @@ -68,6 +68,7 @@ OEMCryptoResult WTPI_CreateAsymmetricKeyHandle( * * Caller retains ownership of all parameters. * + * @param[in] context: the expected context that was used to wrap the key * @param[in] input: wrapped asymmetric key * @param[in] input_length: size of the wrapped asymmetric key * @param[in] key_type: type of asymmetric key @@ -83,8 +84,9 @@ OEMCryptoResult WTPI_CreateAsymmetricKeyHandle( * @retval OEMCrypto_SUCCESS otherwise */ OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( - const uint8_t* input, size_t input_length, AsymmetricKeyType key_type, - WTPI_AsymmetricKey_Handle* key_handle, uint32_t* allowed_schemes); + uint32_t context, const uint8_t* input, size_t input_length, + AsymmetricKeyType key_type, WTPI_AsymmetricKey_Handle* key_handle, + uint32_t* allowed_schemes); /** * Frees |key_handle| that was constructed from a previous call to @@ -133,6 +135,7 @@ OEMCryptoResult WTPI_GetWrappedAsymmetricKeySize(size_t enc_private_key_length, * This is given the clear, PKCS8-padded key and the key may be prefixed with * "SIGN" and a 4-byte code for the padding schemes. * + * @param[in] context: context for wrapping scheme * @param[out] output: destination buffer that will contain the wrapped key data * @param[in] output_length: length of destination buffer * @param[in] key_type: type of asymmetric key @@ -146,7 +149,8 @@ OEMCryptoResult WTPI_GetWrappedAsymmetricKeySize(size_t enc_private_key_length, * @retval OEMCrypto_ERROR_SHORT_BUFFER output_length is too small * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE otherwise */ -OEMCryptoResult WTPI_WrapAsymmetricKey(uint8_t* output, size_t output_length, +OEMCryptoResult WTPI_WrapAsymmetricKey(uint32_t context, uint8_t* output, + size_t output_length, AsymmetricKeyType key_type, const uint8_t* clear_key, size_t clear_key_length); @@ -323,6 +327,22 @@ OEMCryptoResult WTPI_GetSignatureHashAlgorithm( WTPI_AsymmetricKey_Handle key, AsymmetricKeyType key_type, OEMCrypto_SignatureHashAlgorithm* hash_algorithm); +/** + * Provisioning 3.0 only. Creates a key handle from the Prov30 key material in + * secure storage, and places the result in |key_handle|. Key type is + * DRM_RSA_PRIVATE_KEY. + * + * Caller retains ownership of all parameters. + * + * @param[out] key_handle: output key handle + * + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if any of the parameters are NULL + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE if there are any other failures + * @retval OEMCrypto_SUCCESS otherwise + */ +OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( + WTPI_AsymmetricKey_Handle* key_handle); + /// @} #ifdef __cplusplus diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_device_key_interface.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_device_key_interface.h index 103bd39..7de054d 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_device_key_interface.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_device_key_interface.h @@ -35,13 +35,21 @@ extern "C" { */ #define DEVICE_KEY_WRAP_USAGE_TABLE 0x22d8fdcf -/** A device unique key for encrypting/signing the private key in the DRM - * certificate. This key must be unique to this device so that a DRM certificate - * not be copied from one device to another. +/** A device unique key for encrypting/signing the private key in the DRM/OEM + * certificates. This key must be unique to this device so that a DRM/OEM + * certificate not be copied from one device to another. * This should be used as a key derivation context in * WTPI_K1_DeriveDeviceKeyIntoHandle(). + * + * DEVICE_KEY_WRAP_DRM_CERT_V1 is for unwrapping DRM certs that were wrapped on + * OPK implementations v19.0 and older. + * + * DEVICE_KEY_WRAP_DRM_CERT and DEVICE_KEY_WRAP_OEM_CERT are used as wrapping + * keys */ -#define DEVICE_KEY_WRAP_DRM_CERT 0x1db2a411 +#define DEVICE_KEY_WRAP_DRM_CERT_V1 0x1db2a411 +#define DEVICE_KEY_WRAP_DRM_CERT 0x90833ed3 +#define DEVICE_KEY_WRAP_OEM_CERT 0x88b24739 /** A device unique key for encrypting the internal key used by the * implementation of the key management layer. This should be used as a key diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_provisioning_4_interface.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_provisioning_4_interface.h index a953c00..8e338ba 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_provisioning_4_interface.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_provisioning_4_interface.h @@ -8,6 +8,7 @@ #include "OEMCryptoCENC.h" #include "wtpi_crypto_asymmetric_interface.h" +#include "oemcrypto_key_types.h" #ifdef __cplusplus extern "C" { @@ -80,6 +81,8 @@ OEMCryptoResult WTPI_GetMaxBootCertificateChainSize(size_t* out_length); * * Caller retains ownership of all pointers. * + * @param[in] cert_type: DRM or OEM cert type, which should each result in a + * different wrapping context for the |wrapped_private_key| output * @param[out] key_type: Type (RSA or EC) of the generated key pair. * @param[out] wrapped_private_key: The generated private key, wrapped with * encryption key for storage. @@ -90,6 +93,7 @@ OEMCryptoResult WTPI_GetMaxBootCertificateChainSize(size_t* out_length); * modified based on used/required space of output. */ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( + CertSignatureType cert_type, AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, uint8_t* public_key, size_t* public_key_length); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer1.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer1.h index d7d7078..b36406f 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer1.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer1.h @@ -10,6 +10,7 @@ #include "OEMCryptoCENC.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" +#include "wtpi_crypto_asymmetric_interface.h" #ifdef __cplusplus extern "C" { @@ -137,6 +138,103 @@ OEMCryptoResult WTPI_GetDeviceID(uint8_t* device_id, size_t device_id_length); */ OEMCryptoResult WTPI_GetDeviceIDLength(size_t* device_id_length); +/* Provisioning 3.0 */ + +/** + * Wrap the root of trust of Provisioning 3.0, which + * contains the OEM certificate chain (a leaf cert followed by an intermediate + * cert), and the key of the leaf cert. It may be wise to make this function a + * no-op when the device is not in factory mode. + * Caller retains ownership of all parameters. + * + * @param[in] input: OEM certificate chain and private key to be wrapped + * @param[in] input_length: size of the input + * @param[out] wrapped_cert: buffer where wrapped OEM cert and key will be + * written. + * @param[in,out] wrapped_cert_length: on input, it's the buffer size, on output + * it's how much was wrapped. If wrapped_cert_length is too short for the entire + * cert chain and key, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be + * returned. Otherwise, set wrapped_cert_length to the size of the OEM cert + * chain and key wrapped. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if |input| or |wrapped_cert_length| + * is NULL + * @retval OEMCrypto_ERROR_SHORT_BUFFER if |wrapped_cert| is NULL, or + * |wrapped_cert_length| is too small + */ +OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, + uint8_t* wrapped_cert, + size_t* wrapped_cert_length); + +/** + * Unwrap and store the root of trust of Provisioning 3.0. It may be wise to + * make this function a no-op when the device is not in factory mode. + * Caller retains ownership of all parameters. + * + * @param[in] wrapped_cert: OEM certificate chain and private key to be + * installed. It is a result of WTPI_WrapOEMCert(). + * @param[in] wrapped_cert_length: size of |wrapped_cert| + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if |wrapped_cert| is NULL, or if + * |wrapped_cert| can not be parsed + * @retal OEMCrypto_ERROR_INVALID_KEY if the OEM private key is not + * valid + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE otherwise + */ +OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert( + const uint8_t* wrapped_cert, size_t wrapped_cert_length); + +/** + * Load Provisioning 3.0 OEM public certificate to output buffer. + * Caller retains ownership of all parameters. + * + * @param[out] output: buffer of the OEM public certificate. + * @param[in,out] output_length: on input, it's the buffer size, on output it's + * the actual size loaded into the buffer. If output_length is too short for the + * OEM public certificate, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be + * returned. Otherwise, set output length to the size of the OEM public + * certificate loaded. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if |output_length| is NULL + * @retval OEMCrypto_ERROR_SHORT_BUFFER if |output| is NULL, or |output_length| + * is too small + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE otherwise + */ +OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, + size_t* output_length); + +/** + * Attempt to validate the Provisioning 3.0 OEM certificate chain and key. + * Caller retains ownership of all parameters. + * + * @retval OEMCrypto_SUCCESS success + * @retal OEMCrypto_ERROR_INVALID_CONTEXT if the OEM cert is not valid + * @retal OEMCrypto_ERROR_INVALID_KEY if the OEM private key is not + * valid + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if Provisioning 3.0 is not enabled + */ +OEMCryptoResult WTPI_ValidateOEMCertAndKey(void); + +/** + * Provisioning 3.0 only. Creates a key handle from the Prov30 key material in + * secure storage, and places the result in |key_handle|. Key type is + * DRM_RSA_PRIVATE_KEY. + * Caller retains ownership of all parameters. + * + * @param[out] key_handle: output key handle + * + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if any of the parameters are NULL + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE if there are any other failures + * @retval OEMCrypto_SUCCESS otherwise + */ +OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( + WTPI_AsymmetricKey_Handle* key_handle); + +/* End of Provisioning 3.0 */ + /// @} #ifdef __cplusplus } diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer2.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer2.h index 15ecbe9..eccbbd3 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer2.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer2.h @@ -46,24 +46,103 @@ OEMCryptoResult WTPI_UnwrapRootOfTrust(const uint8_t* input, * return an error code if this function is called when the device is not in * "factory mode". * - *@param[in] keybox: buffer of the keybox. - *@param[in] length: on input, it's the buffer size, on output it's the actual - * size loaded into the buffer. If length is too short for the entire root - * of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be returned. - * Otherwise, set length to the size of the root of trust loaded. + * @param[in] keybox: buffer of the keybox. + * @param[in] length: keybox buffer size. */ OEMCryptoResult WTPI_SaveRootOfTrust(const uint8_t* keybox, size_t length); /** Read the buffer from secure permanent storage. * - *@param[in] keybox: buffer of the keybox. - *@param[in,out] length: on input, it's the buffer size, on output it's the + * @param[out] keybox: buffer of the keybox. + * @param[in,out] length: on input, it's the buffer size, on output it's the * actual size loaded into the buffer. If length is too short for the entire * root of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be * returned. Otherwise, set length to the size of the root of trust loaded. */ OEMCryptoResult WTPI_LoadRootOfTrust(uint8_t* keybox, size_t* length); +/* Provisioning 3.0 */ + +/** Use the system specific key to wrap the Provisioning 3.0 root of trust, + * which contains the OEM certificate chain and key. This function is used in + * the factory. + * + * @param[in] input: buffer with OEM cert chain and key. + * @param[in] input_length: the length of the input buffer. + * @param[out] output: buffer where encrypted OEM cert chain and key will be + * written. + * @param[in,out] output_length: on input, it's the buffer size, on output it's + * how much was wrapped. If output_length is too short for the entire root + * of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be returned. + */ +OEMCryptoResult WTPI_WrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length); + +/** Use the system specific key to unwrap the Provisioning 3.0 root of trust, + * which contains the OEM certificate chain and key. This function is used in + * the factory. + * + * @param[in] input: buffer with encrypted OEM cert chain and key. + * @param[in] input_length: the length of the input buffer. + * @param[out] output: buffer where clear OEM cert chain and key will be + * written. + * @param[in,out] output_length: on input, it's the buffer size, on output it's + * how much was unwrapped. If output_length is too short for the entire root + * of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER shall be returned. + */ +OEMCryptoResult WTPI_UnwrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length); + +/** Save the buffer to secure permanent storage. + * To prevent accidentally destroying the OEM private key, production devices + * should return an error code if this function is called when the device is + * not in "factory mode". + * + * @param[in] input: buffer of the OEM cert private key. + * @param[in] input_length: input buffer size. + */ +OEMCryptoResult WTPI_SaveOEMPrivateKey30(const uint8_t* input, + size_t input_length); + +/** Read the buffer from secure permanent storage. + * + * @param[out] output: buffer of the OEM cert private key. + * @param[in,out] output_length: on input, it's the buffer size, on output it's + * the actual size loaded into the buffer. If output_length is too short + * for the entire root of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER + * shall be returned. Otherwise, set length to the size of the root of + * trust loaded. + */ +OEMCryptoResult WTPI_LoadOEMPrivateKey30(uint8_t* output, + size_t* output_length); + +/** Save the buffer to secure permanent storage. + * To prevent accidentally destroying the OEM public certificate, production + * devices should return an error code if this function is called when the + * device is not in "factory mode". + * + * @param[in] input: buffer of the OEM public certificate. + * @param[in] input_length: input buffer size. + */ +OEMCryptoResult WTPI_SaveOEMPublicCertificate30(const uint8_t* input, + size_t input_length); + +/** Read the buffer from secure permanent storage. + * + * @param[out] output: buffer of the OEM public certificate. + * @param[in,out] output_length: on input, it's the buffer size, on output it's + * the actual size loaded into the buffer. If output_length is too short + * for the entire root of trust, the error code OEMCrypto_ERROR_SHORT_BUFFER + * shall be returned. Otherwise, set length to the size of the OEM public + * certificate loaded. + */ +OEMCryptoResult WTPI_LoadOEMPublicCertificate30(uint8_t* output, + size_t* output_length); + +/* End of Provisioning 3.0 */ + /// @} #ifdef __cplusplus diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/config/default.h b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/config/default.h index f4ef821..d85fe0e 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/config/default.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/config/default.h @@ -285,7 +285,7 @@ * Size of overhead required by WTPI_EncryptAndSign (if applicable). */ #ifndef ENCRYPT_AND_SIGN_EXTRA -# define ENCRYPT_AND_SIGN_EXTRA 68 +# define ENCRYPT_AND_SIGN_EXTRA 72 #endif /** @@ -324,6 +324,35 @@ # define MAX_ASYMMETRIC_SIGNATURE_SIZE 1024 #endif +/** + * Maximum size of OEM certificate chain and private key in Provisioning 3.0 + */ +#ifndef MAX_PROV30_ROT_SIZE +# define MAX_PROV30_ROT_SIZE 8192 +#endif + +/** + * Maximum size of OEM X509 certificate chain in Provisioning 3.0 + */ +#ifndef MAX_PROV30_OEM_CERT_CHAIN_SIZE +# define MAX_PROV30_OEM_CERT_CHAIN_SIZE 4096 +#endif + +/** + * Maximum size of OEM certificate chain in PKCS#7 in Provisioning 3.0 + */ +#ifndef MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE +# define MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE \ + (MAX_PROV30_OEM_CERT_CHAIN_SIZE + 2048) +#endif + +/** + * Maximum size of OEM private key in Provisioning 3.0 + */ +#ifndef MAX_PROV30_OEM_KEY_SIZE +# define MAX_PROV30_OEM_KEY_SIZE 2048 +#endif + /* * * Config values that must be defined by the build process. These are wrapped by diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c new file mode 100644 index 0000000..b9d5a4c --- /dev/null +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c @@ -0,0 +1,135 @@ +/* Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary + source code may only be used and distributed under the Widevine + License Agreement. */ + +#include "prov30_factory_util.h" + +#include + +#include "openssl/evp.h" +#include "openssl/pkcs7.h" +#include "openssl/x509.h" + +/* +This code assumes the certs_and_key always contains a certificate chain (one +leaf and one intermediate cert) followed by a private key. + 1. Leaf certificate + 2. Intermediate certificate + 3. Private leaf key +Input format for |certs_and_key|: ++-----------------------+----------------------+--------------------------+ +| Cert Chain Length | Certificate Chain | Key Length | ++-----------------------+----------------------+--------------------------+ +| (4 bytes, big-endian) | (DER-encoded PKCS#7) | (4 bytes, big-endian) | ++-----------------------+----------------------+--------------------------+ +| Private Key | ++-----------------------+ +*/ +OEMCryptoResult ParseCertificateChainAndKey(const uint8_t* certs_and_key, + size_t certs_and_key_length, + uint8_t* cert_chain_out, + size_t* cert_chain_out_length, + uint8_t* key_out, + size_t* key_out_length) { + if (certs_and_key == NULL || certs_and_key_length == 0 || + cert_chain_out == NULL || cert_chain_out_length == NULL || + key_out == NULL || key_out_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // Read cert chain length from the first 4 bytes of the input buffer + if (certs_and_key_length < sizeof(uint32_t)) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + const uint32_t cert_chain_length = (certs_and_key[0] << 24) | + (certs_and_key[1] << 16) | + (certs_and_key[2] << 8) | certs_and_key[3]; + // Read key length from the next 4 bytes after the cert chain + if (certs_and_key_length < + sizeof(uint32_t) + cert_chain_length + sizeof(uint32_t)) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + const uint8_t* key_data = + certs_and_key + sizeof(uint32_t) + cert_chain_length; + const uint32_t key_length = (key_data[0] << 24) | (key_data[1] << 16) | + (key_data[2] << 8) | key_data[3]; + if (certs_and_key_length < + sizeof(uint32_t) + cert_chain_length + sizeof(uint32_t) + key_length) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // Check if output buffers are large enough + if (*cert_chain_out_length < cert_chain_length || + *key_out_length < key_length) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // Copy certificate chain + memcpy(cert_chain_out, certs_and_key + sizeof(uint32_t), cert_chain_length); + *cert_chain_out_length = (size_t)cert_chain_length; + // Copy private key + memcpy(key_out, key_data + sizeof(uint32_t), key_length); + *key_out_length = (size_t)key_length; + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult ValidateCertificateChainAndKey(const uint8_t* cert_chain, + size_t cert_chain_length, + const uint8_t* key, + size_t key_length) { + // 1. PKCS#7 Parsing + BIO* bio_cert_chain = BIO_new_mem_buf(cert_chain, cert_chain_length); + if (!bio_cert_chain) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + PKCS7* pkcs7 = d2i_PKCS7_bio(bio_cert_chain, NULL); + if (!pkcs7) { + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + STACK_OF(X509)* certs = pkcs7->d.sign->cert; // Assuming signed PKCS#7 + if (sk_X509_num(certs) < 2) { + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // 2. Certificate Chain Verification (without root trust) + X509* leaf_cert = sk_X509_value(certs, 0); + X509* intermediate_cert = sk_X509_value(certs, 1); + if (!leaf_cert || !intermediate_cert) { + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + EVP_PKEY* issuer_pubkey = X509_get_pubkey(intermediate_cert); + if (!issuer_pubkey) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + int status = X509_verify(leaf_cert, issuer_pubkey); + EVP_PKEY_free(issuer_pubkey); + if (status != 1) { + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // 3. Key Matching Verification (DER-encoded key) + BIO* bio_key = BIO_new_mem_buf(key, key_length); + if (!bio_key) { + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + EVP_PKEY* pkey = d2i_PrivateKey_bio(bio_key, NULL); + if (!pkey) { + BIO_free(bio_key); + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + return OEMCrypto_ERROR_INVALID_KEY; + } + int key_match_result = X509_check_private_key(leaf_cert, pkey); + EVP_PKEY_free(pkey); + BIO_free(bio_key); + PKCS7_free(pkcs7); + BIO_free(bio_cert_chain); + if (key_match_result != 1) { + return OEMCrypto_ERROR_INVALID_KEY; + } + return OEMCrypto_SUCCESS; +} diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.h b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.h new file mode 100644 index 0000000..6339b11 --- /dev/null +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.h @@ -0,0 +1,31 @@ +/* Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary + source code may only be used and distributed under the Widevine + License Agreement. */ + +#ifndef OEMCRYPTO_TA_PROV30_FACTORY_UTIL_H_ +#define OEMCRYPTO_TA_PROV30_FACTORY_UTIL_H_ + +#include "OEMCryptoCENC.h" + +/* Parse |certs_and_key|, which includes an X509 certificate chain (one leaf + certificate and one intermediate certificate) and leaf private key, outputs + DER encoded PKCS#7 certificate chain and DER encoded private key. The input + format of |certs_and_key| is implementation specific. It could be PEM encoded + bytes, or any self-defined format. Caller retains ownership of all pointers + and they must not be NULL. */ +OEMCryptoResult ParseCertificateChainAndKey(const uint8_t* certs_and_key, + size_t certs_and_key_length, + uint8_t* cert_chain_out, + size_t* cert_chain_out_length, + uint8_t* key_out, + size_t* key_out_length); + +/* Validate DER encoded PKCS#7 certificate chain and DER encoded private key + corresponding to the leaf certificate. Caller retains ownership of all + pointers and they must not be NULL. */ +OEMCryptoResult ValidateCertificateChainAndKey(const uint8_t* cert_chain, + size_t cert_chain_length, + const uint8_t* key, + size_t key_length); + +#endif /* OEMCRYPTO_TA_PROV30_FACTORY_UTIL_H_ */ diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_crypto_wrap_asymmetric.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_crypto_wrap_asymmetric.c index 44ca231..7aed644 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_crypto_wrap_asymmetric.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_crypto_wrap_asymmetric.c @@ -50,7 +50,7 @@ static OEMCryptoResult LoadECCKeyInfoAsymmetricKeyHandle( } OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( - const uint8_t* wrapped_key, size_t wrapped_key_length, + uint32_t context, const uint8_t* wrapped_key, size_t wrapped_key_length, AsymmetricKeyType key_type, WTPI_AsymmetricKey_Handle* key_handle, uint32_t* allowed_schemes) { if (wrapped_key == NULL || wrapped_key_length == 0 || @@ -62,8 +62,8 @@ OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( /* Unwrap encrypted key. */ uint8_t unwrapped_key[PKCS8_DRM_KEY_MAX_SIZE]; size_t unwrapped_key_length = sizeof(unwrapped_key); - const OEMCryptoResult result = WTPI_VerifyAndDecrypt( - DEVICE_KEY_WRAP_DRM_CERT, wrapped_key, wrapped_key_length, unwrapped_key, + OEMCryptoResult result = WTPI_VerifyAndDecrypt( + context, wrapped_key, wrapped_key_length, unwrapped_key, &unwrapped_key_length); if (result == OEMCrypto_ERROR_SHORT_BUFFER) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -79,12 +79,11 @@ OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( key_handle, allowed_schemes); } -OEMCryptoResult WTPI_WrapAsymmetricKey(uint8_t* wrapped_key, +OEMCryptoResult WTPI_WrapAsymmetricKey(uint32_t context, uint8_t* wrapped_key, size_t wrapped_key_length, UNUSED AsymmetricKeyType key_type, const uint8_t* clear_key, size_t clear_key_length) { - return WTPI_EncryptAndSign(DEVICE_KEY_WRAP_DRM_CERT, clear_key, - clear_key_length, wrapped_key, + return WTPI_EncryptAndSign(context, clear_key, clear_key_length, wrapped_key, &wrapped_key_length); } diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_device_key.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_device_key.c index c2d7408..cff68e3 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_device_key.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_device_key.c @@ -1,11 +1,11 @@ -/* Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary +/* Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary source code may only be used and distributed under the Widevine License Agreement. */ #include "wtpi_device_key_interface.h" #include - +#include "odk_endian.h" #include "oemcrypto_overflow.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" @@ -30,29 +30,49 @@ static const uint8_t kMagicUuid[UUID_LENGTH] = { 0xb5, 0x76, 0x3b, 0xad, 0x84, 0x05, 0x40, 0xfd, 0xa0, 0x88, 0x3b, 0x6c, 0x69, 0x97, 0xfc, 0x74}; -// 1 in network byte order -static const uint8_t kVersionOne[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x01}; - // This is the layout of the |data| field of a WrappedData structure when its -// |version| field is 1. +// |version| field is 1. This covers default implementations of OPK from v17 +// through v18.4 +static const uint8_t kVersionOne[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x01}; typedef struct WrappedData_V1 { uint8_t iv[KEY_IV_SIZE]; uint8_t enc_data[]; } WrappedData_V1; +// V2 includes the context used to derive the wrapping and signing keys. +static const uint8_t kVersionTwo[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x02}; +typedef struct WrappedData_V2 { + uint8_t context[sizeof(uint32_t)]; + uint8_t iv[KEY_IV_SIZE]; + uint8_t enc_data[]; +} WrappedData_V2; + +static OEMCryptoResult ReadWrapProtocolVersion(const WrappedData* data, + uint32_t* version) { + if (data == NULL || version == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + uint32_t value = UINT32_MAX; + memcpy(&value, data->version, sizeof(value)); + *version = oemcrypto_htobe32(value); + + return OEMCrypto_SUCCESS; +} + OEMCryptoResult WTPI_GetEncryptAndSignSize(UNUSED uint32_t context, size_t in_size, size_t* wrapped_size) { - if (OPK_AddOverflowUX(in_size, sizeof(WrappedData) + sizeof(WrappedData_V1), + if (OPK_AddOverflowUX(in_size, sizeof(WrappedData) + sizeof(WrappedData_V2), wrapped_size)) { return OEMCrypto_ERROR_INVALID_CONTEXT; } return OEMCrypto_SUCCESS; } -OEMCryptoResult WTPI_EncryptAndSign(uint32_t context, const uint8_t* data, - size_t data_size, uint8_t* out, - size_t* out_size) { +static OEMCryptoResult EncryptAndSign_V2(uint32_t context, const uint8_t* data, + size_t data_size, uint8_t* out, + size_t* out_size) { if (!out_size) { return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -70,9 +90,11 @@ OEMCryptoResult WTPI_EncryptAndSign(uint32_t context, const uint8_t* data, WrappedData* const wrapped_header = (WrappedData*)out; memcpy(wrapped_header->magic, kMagicUuid, sizeof(wrapped_header->magic)); - memcpy(wrapped_header->version, kVersionOne, sizeof(wrapped_header->version)); + memcpy(wrapped_header->version, kVersionTwo, sizeof(wrapped_header->version)); + + WrappedData_V2* const wrapped_data = (WrappedData_V2*)wrapped_header->data; + memcpy(wrapped_data->context, &context, sizeof(context)); - WrappedData_V1* const wrapped_data = (WrappedData_V1*)wrapped_header->data; /* Pick a random IV for generating keys. */ result = WTPI_C1_RandomBytes(wrapped_data->iv, sizeof(wrapped_data->iv)); if (result != OEMCrypto_SUCCESS) return result; @@ -124,10 +146,6 @@ static OEMCryptoResult VerifyAndDecrypt_V1(uint32_t context, WTPI_K1_FreeKeyHandle(signing_key); if (result != OEMCrypto_SUCCESS) return result; - // If someday we support multiple versions, we'll need to decode - // wrapped_header->version and switch our behavior depending on the version - // we find. But for now, since only version 1 is valid, we can just verify - // that wrapped_header->version is 1. if (memcmp(wrapped_header->magic, kMagicUuid, sizeof(wrapped_header->magic)) != 0 || memcmp(wrapped_header->version, kVersionOne, @@ -162,13 +180,102 @@ static OEMCryptoResult VerifyAndDecrypt_V1(uint32_t context, return result; } +// In V2 the context value is contained with the wrapped data +static OEMCryptoResult VerifyAndDecrypt_V2(uint32_t context, + const uint8_t* data, + size_t data_size, uint8_t* out, + size_t* out_size) { + if (data == NULL || out == NULL || + data_size < sizeof(WrappedData) + sizeof(WrappedData_V2) || + out_size == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + const WrappedData* const wrapped_header = (const WrappedData*)data; + const WrappedData_V2* const wrapped_data = + (const WrappedData_V2*)wrapped_header->data; + + uint32_t wrapped_context = UINT32_MAX; + memcpy(&wrapped_context, wrapped_data->context, sizeof(wrapped_context)); + + if (wrapped_context != context) { + return OEMCrypto_ERROR_INVALID_KEY; + } + + // Verify the signature first, before interpreting. + WTPI_K1_SymmetricKey_Handle signing_key = NULL; + OEMCryptoResult result = WTPI_K1_DeriveDeviceKeyIntoHandle( + context, MAC_KEY_SERVER, &signing_key, KEY_SIZE_256); + if (result != OEMCrypto_SUCCESS) return result; + const size_t offset = sizeof(wrapped_header->signature); + result = + WTPI_C1_HMAC_SHA256_Verify(signing_key, data + offset, data_size - offset, + wrapped_header->signature); + WTPI_K1_FreeKeyHandle(signing_key); + if (result != OEMCrypto_SUCCESS) return result; + + if (memcmp(wrapped_header->magic, kMagicUuid, + sizeof(wrapped_header->magic)) != 0 || + memcmp(wrapped_header->version, kVersionTwo, + sizeof(wrapped_header->version)) != 0) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + const size_t needed_size = + data_size - (sizeof(WrappedData) + sizeof(WrappedData_V2)); + if (*out_size < needed_size) { + *out_size = needed_size; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + *out_size = needed_size; + + // Decrypt the buffer. + WTPI_K1_SymmetricKey_Handle encryption_key = NULL; + result = WTPI_K1_DeriveDeviceKeyIntoHandle(context, ENCRYPTION_KEY, + &encryption_key, KEY_SIZE_128); + if (result != OEMCrypto_SUCCESS) return result; + KeySize key_size; + result = WTPI_K1_GetKeySize(encryption_key, &key_size); + if (result != OEMCrypto_SUCCESS) return result; + result = WTPI_C1_AESCBCDecrypt(encryption_key, (size_t)key_size, + wrapped_data->enc_data, needed_size, + wrapped_data->iv, out); + WTPI_K1_FreeKeyHandle(encryption_key); + return result; +} + +OEMCryptoResult WTPI_EncryptAndSign(uint32_t context, const uint8_t* data, + size_t data_size, uint8_t* out, + size_t* out_size) { + return EncryptAndSign_V2(context, data, data_size, out, out_size); +} + OEMCryptoResult WTPI_VerifyAndDecrypt(uint32_t context, const uint8_t* data, size_t data_size, uint8_t* out, size_t* out_size) { - // This function is broken out separately in order to ease maintenance for - // those who also need to maintain backwards-compatibility with other, older - // wrapping formats. - return VerifyAndDecrypt_V1(context, data, data_size, out, out_size); + if (data_size < sizeof(WrappedData)) return OEMCrypto_ERROR_INVALID_CONTEXT; + uint32_t version = UINT32_MAX; + OEMCryptoResult res = + ReadWrapProtocolVersion((const WrappedData*)data, &version); + if (res != OEMCrypto_SUCCESS) return res; + + switch (version) { + case 1: + // If the header type is V1, use the legacy unwrapping format. + // Check the incoming context. DRM_CERT or OEM_CERT means this is a + // legacy DRM/OEM wrap, which used the same DRM_CERT_V1 context to wrap. + // Otherwise use the context provided. + if (context == DEVICE_KEY_WRAP_DRM_CERT || + context == DEVICE_KEY_WRAP_OEM_CERT) { + context = DEVICE_KEY_WRAP_DRM_CERT_V1; + } + return VerifyAndDecrypt_V1(context, data, data_size, out, out_size); + case 2: + return VerifyAndDecrypt_V2(context, data, data_size, out, out_size); + default: + return OEMCrypto_ERROR_INVALID_CONTEXT; + } } OEMCryptoResult WTPI_VerifyAndDecryptUsageData_Legacy( diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_provisioning_4.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_provisioning_4.c index d53f69a..11528ed 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_provisioning_4.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_provisioning_4.c @@ -100,9 +100,9 @@ OEMCryptoResult WTPI_GetMaxBootCertificateChainSize(size_t* out_length) { } OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( - AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length, uint8_t* public_key, - size_t* public_key_length) { + CertSignatureType cert_type, AsymmetricKeyType* key_type, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, + uint8_t* public_key, size_t* public_key_length) { if (key_type == NULL || wrapped_private_key_length == NULL || public_key_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -148,10 +148,21 @@ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( return OEMCrypto_ERROR_SHORT_BUFFER; } + uint32_t context = 0; + if (cert_type == CERT_SIGNATURE_DRM) { + context = DEVICE_KEY_WRAP_DRM_CERT; + } else if (cert_type == CERT_SIGNATURE_OEM) { + context = DEVICE_KEY_WRAP_OEM_CERT; + } else { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + *wrapped_private_key_length = actual_wrapped_private_key_length; - return WTPI_WrapAsymmetricKey(wrapped_private_key, - *wrapped_private_key_length, *key_type, - clear_private_key, clear_private_key_length); + result = WTPI_WrapAsymmetricKey(context, wrapped_private_key, + *wrapped_private_key_length, *key_type, + clear_private_key, clear_private_key_length); + + return result; } OEMCryptoResult WTPI_BccKeyCoseSign1(const uint8_t* message, diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp index 41befb8..7886a09 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp @@ -30,6 +30,17 @@ 'include_dirs': [ '.', ], + # The reference implementation of the root of trust interface uses + # BoringSSL/OpenSSL, which requires C11. These flags effectively do the + # opposite of the default flags, filtering out the C99 flag and + # un-filtering-out the C11 flag. + 'cflags_c': [ + '-std=c11', + ], + 'cflags_c/': [ + ['exclude', '-std=*'], + ['include', '-std=c11'], + ], 'dependencies': [ '../../../odk/src/odk.gyp:odk', 'oemcrypto_ta_reference_crypto', @@ -106,6 +117,7 @@ 'device_key_util.c', 'cose_util.c', 'ecc_util.c', + 'prov30_factory_util.c', 'rsa_util.c', 'wtpi_crc32.c', 'wtpi_crypto_asymmetric.c', diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_root_of_trust_layer1.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_root_of_trust_layer1.c index e13b87e..7a8fa70 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_root_of_trust_layer1.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_root_of_trust_layer1.c @@ -11,15 +11,19 @@ #include #include +#include "config/default.h" #include "cose_util.h" #include "odk_endian.h" +#include "oemcrypto_compiler_attributes.h" #include "oemcrypto_key_types.h" +#include "prov30_factory_util.h" #include "renewal_util.h" #include "wtpi_abort_interface.h" #include "wtpi_config_interface.h" #include "wtpi_crc32_interface.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" +#include "wtpi_device_key_interface.h" #include "wtpi_device_renewal_interface_layer1.h" #include "wtpi_logging_interface.h" #include "wtpi_provisioning_4_interface.h" @@ -232,15 +236,37 @@ static OEMCryptoResult GetProv4DeviceID(uint8_t* device_id, return result; } +static OEMCryptoResult GetProv3DeviceID(uint8_t* device_id, + size_t device_id_length) { + if (device_id == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (device_id_length < SHA256_DIGEST_LENGTH) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + uint8_t public_cert_buffer[MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE]; + size_t public_cert_buffer_size = sizeof(public_cert_buffer); + OEMCryptoResult result = WTPI_LoadOEMPublicCertificate( + public_cert_buffer, &public_cert_buffer_size); + if (result != OEMCrypto_SUCCESS) return result; + // Device ID with provisioning 3 in this reference implementation is hash of + // (PKCS#7 DER encoded) OEM public certificate. + result = + WTPI_C1_SHA256(public_cert_buffer, public_cert_buffer_size, device_id); + return result; +} + OEMCryptoResult WTPI_GetDeviceID(uint8_t* device_id, size_t device_id_length) { if (device_id == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; - if (WTPI_GetProvisioningMethod() == OEMCrypto_BootCertificateChain) { + const OEMCrypto_ProvisioningMethod provisioning_method = + WTPI_GetProvisioningMethod(); + if (provisioning_method == OEMCrypto_BootCertificateChain) { return GetProv4DeviceID(device_id, device_id_length); } + if (provisioning_method == OEMCrypto_OEMCertificate) { + return GetProv3DeviceID(device_id, device_id_length); + } - if (WTPI_GetProvisioningMethod() != OEMCrypto_Keybox) { - // TODO(b/225216277): Implement this. + if (provisioning_method != OEMCrypto_Keybox) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } @@ -255,7 +281,8 @@ OEMCryptoResult WTPI_GetDeviceIDLength(size_t* device_id_length) { if (device_id_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (WTPI_GetProvisioningMethod() == OEMCrypto_BootCertificateChain) { + if (WTPI_GetProvisioningMethod() == OEMCrypto_OEMCertificate || + WTPI_GetProvisioningMethod() == OEMCrypto_BootCertificateChain) { *device_id_length = SHA256_DIGEST_LENGTH; } else if (WTPI_GetProvisioningMethod() == OEMCrypto_Keybox) { *device_id_length = KEYBOX_DEVICE_ID_SIZE; @@ -310,3 +337,124 @@ OEMCryptoResult WTPI_K1_CreateKeyHandleFromKeybox( DERIVING_KEY, out); } } + +// Load Provisioning 3.0 OEM private key to output buffer +static OEMCryptoResult LoadOEMPrivateKey(uint8_t* output, + size_t* output_length) { + if (output_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + if (output == NULL || *output_length < MAX_PROV30_OEM_KEY_SIZE) { + *output_length = MAX_PROV30_OEM_KEY_SIZE; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + return WTPI_LoadOEMPrivateKey30(output, output_length); +} + +OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, + uint8_t* wrapped_cert, + size_t* wrapped_cert_length) { + if (input == NULL || input_length == 0 || wrapped_cert_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + size_t required_size = 0; + OEMCryptoResult result = WTPI_GetEncryptAndSignSize( + DEVICE_KEY_WRAP_DRM_CERT, input_length, &required_size); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to get wrapped OEM cert and key size with result: %u", result); + return result; + } + if (wrapped_cert == NULL || *wrapped_cert_length < required_size) { + *wrapped_cert_length = required_size; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + /* Tell caller how much space we used. */ + *wrapped_cert_length = required_size; + return WTPI_WrapRootOfTrust30(input, input_length, wrapped_cert, + wrapped_cert_length); +} + +OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert(const uint8_t* input, + size_t input_length) { + if (input == NULL || input_length == 0) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + uint8_t certs_and_key[MAX_PROV30_ROT_SIZE] = {0}; + size_t certs_and_key_length = MAX_PROV30_ROT_SIZE; + OEMCryptoResult result = WTPI_UnwrapRootOfTrust30( + input, input_length, certs_and_key, &certs_and_key_length); + if (result != OEMCrypto_SUCCESS) { + return result; + } + + uint8_t cert_chain[MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE] = {0}; + size_t cert_chain_length = MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE; + uint8_t private_key[MAX_PROV30_OEM_KEY_SIZE] = {0}; + size_t private_key_length = MAX_PROV30_OEM_KEY_SIZE; + result = ParseCertificateChainAndKey(certs_and_key, certs_and_key_length, + cert_chain, &cert_chain_length, + private_key, &private_key_length); + if (result != OEMCrypto_SUCCESS) { + return result; + } + result = ValidateCertificateChainAndKey(cert_chain, cert_chain_length, + private_key, private_key_length); + if (result != OEMCrypto_SUCCESS) { + LOGE("OEM certificate chain or key is not valid"); + return result; + } + result = WTPI_SaveOEMPrivateKey30(private_key, private_key_length); + if (result != OEMCrypto_SUCCESS) { + return result; + } + return WTPI_SaveOEMPublicCertificate30(cert_chain, cert_chain_length); +} + +OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, + size_t* output_length) { + if (output_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + if (output == NULL || *output_length < MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE) { + *output_length = MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + return WTPI_LoadOEMPublicCertificate30(output, output_length); +} + +OEMCryptoResult WTPI_ValidateOEMCertAndKey(void) { + uint8_t cert_chain[MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE] = {0}; + size_t cert_chain_length = MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE; + OEMCryptoResult result = + WTPI_LoadOEMPublicCertificate(cert_chain, &cert_chain_length); + if (result != OEMCrypto_SUCCESS) return result; + uint8_t private_key[MAX_PROV30_OEM_KEY_SIZE] = {0}; + size_t private_key_length = MAX_PROV30_OEM_KEY_SIZE; + result = LoadOEMPrivateKey(private_key, &private_key_length); + if (result != OEMCrypto_SUCCESS) return result; + return ValidateCertificateChainAndKey(cert_chain, cert_chain_length, + private_key, private_key_length); +} + +OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( + WTPI_AsymmetricKey_Handle* key_handle) { + uint8_t oem_key[MAX_PROV30_OEM_KEY_SIZE]; + size_t oem_key_length = MAX_PROV30_OEM_KEY_SIZE; + OEMCryptoResult result = LoadOEMPrivateKey(oem_key, &oem_key_length); + if (result != OEMCrypto_SUCCESS) { + LOGE("Failed to load OEM private key with result: %u", result); + return result; + } + result = WTPI_CreateAsymmetricKeyHandle(oem_key, oem_key_length, + DRM_RSA_PRIVATE_KEY, key_handle); + if (result != OEMCrypto_SUCCESS) { + memset(oem_key, 0, sizeof(oem_key)); + LOGE( + "Failed to create asymmetric key handle for OEM private key with " + "result: %u", + result); + return result; + } + memset(oem_key, 0, sizeof(oem_key)); + return OEMCrypto_SUCCESS; +} diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.c index aeaf159..d4a67e9 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.c @@ -256,3 +256,18 @@ void OPK_Unpack_OEMCrypto_SignatureHashAlgorithm( ODK_Message* message, OEMCrypto_SignatureHashAlgorithm* value) { OPK_Unpack_int(message, (int*)value); } + +void OPK_Pack_CertSignatureType(ODK_Message* message, + CertSignatureType* value) { + if (value == NULL) { + ODK_MESSAGE_SETSTATUS(message, MESSAGE_STATUS_NULL_POINTER_ERROR); + return; + } + + OPK_Pack_uint32_t(message, (uint32_t*)value); +} + +void OPK_Unpack_CertSignatureType(ODK_Message* message, + CertSignatureType* value) { + OPK_Unpack_uint32_t(message, (uint32_t*)value); +} diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.h b/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.h index 21301ba..ce973f0 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/common/common_special_cases.h @@ -76,5 +76,7 @@ void OPK_Pack_OEMCrypto_SignatureHashAlgorithm( ODK_Message* message, const OEMCrypto_SignatureHashAlgorithm* value); void OPK_Unpack_OEMCrypto_SignatureHashAlgorithm( ODK_Message* message, OEMCrypto_SignatureHashAlgorithm* value); +void OPK_Pack_CertSignatureType(ODK_Message* message, CertSignatureType* value); +void OPK_Unpack_CertSignatureType(ODK_Message* message, CertSignatureType* value); #endif diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/crypto_test.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/crypto_test.cpp index 6cc11e8..9fde42f 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/crypto_test.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/crypto_test.cpp @@ -20,11 +20,6 @@ #include "wtpi_crypto_asymmetric_interface.h" #include "wtpi_device_key_interface.h" -#define TEST_RSA_KEY_DER_LEN 1216 -#define HELLO_WORLD_ENC_LEN 256 -extern uint8_t test_rsa_key_der[TEST_RSA_KEY_DER_LEN]; -extern uint8_t hello_world_encrypted[HELLO_WORLD_ENC_LEN]; - using wtpi_test::EcKeyPtr; using wtpi_test::MakeEccPublicKey; using wtpi_test::NewEccPrivateKey; @@ -1134,18 +1129,20 @@ TEST_F(CryptoTest, WrapAsymmetricKeyFailsForBadInputs) { uint8_t clear_key[256] = {0}; size_t clear_key_length = 256; - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_WrapAsymmetricKey(NULL, output_length, key_type, clear_key, - clear_key_length)); - ASSERT_EQ( - OEMCrypto_ERROR_SHORT_BUFFER, - WTPI_WrapAsymmetricKey(output, 0, key_type, clear_key, clear_key_length)); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_WrapAsymmetricKey(output, output_length, key_type, NULL, - clear_key_length)); ASSERT_EQ( OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_WrapAsymmetricKey(output, output_length, key_type, clear_key, 0)); + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, NULL, output_length, + key_type, clear_key, clear_key_length)); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, output, 0, + key_type, clear_key, clear_key_length)); + ASSERT_EQ( + OEMCrypto_ERROR_INVALID_CONTEXT, + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, output, output_length, + key_type, NULL, clear_key_length)); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, output, + output_length, key_type, clear_key, 0)); } TEST_F(CryptoTest, UnwrapAsymmetricKeyFailsForBadInputs) { @@ -1156,16 +1153,20 @@ TEST_F(CryptoTest, UnwrapAsymmetricKeyFailsForBadInputs) { uint32_t allowed_schemes = 0; ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_UnwrapIntoAsymmetricKeyHandle(NULL, input_length, key_type, + WTPI_UnwrapIntoAsymmetricKeyHandle(DEVICE_KEY_WRAP_DRM_CERT, NULL, + input_length, key_type, &key_handle, &allowed_schemes)); ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_UnwrapIntoAsymmetricKeyHandle(input, 0, key_type, &key_handle, + WTPI_UnwrapIntoAsymmetricKeyHandle(DEVICE_KEY_WRAP_DRM_CERT, input, + 0, key_type, &key_handle, &allowed_schemes)); ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_UnwrapIntoAsymmetricKeyHandle(input, input_length, key_type, - NULL, &allowed_schemes)); + WTPI_UnwrapIntoAsymmetricKeyHandle(DEVICE_KEY_WRAP_DRM_CERT, input, + input_length, key_type, NULL, + &allowed_schemes)); ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - WTPI_UnwrapIntoAsymmetricKeyHandle(input, input_length, key_type, + WTPI_UnwrapIntoAsymmetricKeyHandle(DEVICE_KEY_WRAP_DRM_CERT, input, + input_length, key_type, &key_handle, NULL)); } @@ -1183,16 +1184,16 @@ TEST_F(CryptoTest, WrapAndUnwrapAsymmetricKeyWorks) { std::vector wrapped(buffer_size, 0); ASSERT_EQ(OEMCrypto_SUCCESS, - WTPI_WrapAsymmetricKey(wrapped.data(), wrapped.size(), - DRM_RSA_PRIVATE_KEY, test_rsa_key_der, - TEST_RSA_KEY_DER_LEN)); + WTPI_WrapAsymmetricKey(DEVICE_KEY_WRAP_DRM_CERT, wrapped.data(), + wrapped.size(), DRM_RSA_PRIVATE_KEY, + test_rsa_key_der, TEST_RSA_KEY_DER_LEN)); WTPI_AsymmetricKey_Handle out_handle; uint32_t allowed_schemes; ASSERT_EQ(OEMCrypto_SUCCESS, - WTPI_UnwrapIntoAsymmetricKeyHandle(wrapped.data(), wrapped.size(), - DRM_RSA_PRIVATE_KEY, &out_handle, - &allowed_schemes)); + WTPI_UnwrapIntoAsymmetricKeyHandle( + DEVICE_KEY_WRAP_DRM_CERT, wrapped.data(), wrapped.size(), + DRM_RSA_PRIVATE_KEY, &out_handle, &allowed_schemes)); // perform an operation with the two handles to prove they are the same std::vector decrypted1(256, 0); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp new file mode 100644 index 0000000..96ae90c --- /dev/null +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp @@ -0,0 +1,165 @@ +// Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +// This file is a direct code copy of keywrap code v1, followed by a GTEST test +// to compare it to the v2 implementation for backards compatibility + +#include +#include + +#include "log.h" +#include "opk_init.h" +#include "test_common.h" +#include "wtpi_crypto_and_key_management_interface_layer1.h" +#include "wtpi_crypto_asymmetric_interface.h" +#include "wtpi_device_key_interface.h" + +#define UUID_LENGTH 16 +// This struct represents a wrapped blob that we do not yet know how to +// interpret. It contains only the fields that we expect every versioned blob to +// have. +typedef struct WrappedData { + uint8_t signature[SHA256_DIGEST_LENGTH]; + uint8_t magic[UUID_LENGTH]; + uint8_t version[sizeof(uint32_t)]; + uint8_t data[]; +} WrappedData; +// The randomly-generated UUID that identifies a blob as a WrappedData struct, +// in network byte order. +static const uint8_t kMagicUuid[UUID_LENGTH] = { + 0xb5, 0x76, 0x3b, 0xad, 0x84, 0x05, 0x40, 0xfd, + 0xa0, 0x88, 0x3b, 0x6c, 0x69, 0x97, 0xfc, 0x74}; +// 1 in network byte order +static const uint8_t kVersionOne[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x01}; +// This is the layout of the |data| field of a WrappedData structure when its +// |version| field is 1. +typedef struct WrappedData_V1 { + uint8_t iv[KEY_IV_SIZE]; + uint8_t enc_data[]; +} WrappedData_V1; + +static OEMCryptoResult GetEncryptAndSignSize(uint32_t context, size_t in_size, + size_t* wrapped_size) { + *wrapped_size = in_size + sizeof(WrappedData) + sizeof(WrappedData_V1); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult EncryptAndSign_V1(uint32_t context, const uint8_t* data, + size_t data_size, uint8_t* out, + size_t* out_size) { + if (!out_size) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + size_t needed_size; + OEMCryptoResult result = + GetEncryptAndSignSize(context, data_size, &needed_size); + if (result != OEMCrypto_SUCCESS) return result; + if (*out_size < needed_size) { + printf("need %zu", needed_size); + *out_size = needed_size; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + // Allow querying size without these buffers. + if (!data || !out) return OEMCrypto_ERROR_INVALID_CONTEXT; + *out_size = needed_size; + WrappedData* const wrapped_header = (WrappedData*)out; + memcpy(wrapped_header->magic, kMagicUuid, sizeof(wrapped_header->magic)); + memcpy(wrapped_header->version, kVersionOne, sizeof(wrapped_header->version)); + WrappedData_V1* const wrapped_data = (WrappedData_V1*)wrapped_header->data; + /* Pick a random IV for generating keys. */ + result = WTPI_C1_RandomBytes(wrapped_data->iv, sizeof(wrapped_data->iv)); + if (result != OEMCrypto_SUCCESS) return result; + // Encrypt the buffer. + WTPI_K1_SymmetricKey_Handle encryption_key = NULL; + result = WTPI_K1_DeriveDeviceKeyIntoHandle(context, ENCRYPTION_KEY, + &encryption_key, KEY_SIZE_128); + if (result != OEMCrypto_SUCCESS) return result; + result = WTPI_C1_AESCBCEncrypt(encryption_key, data, data_size, + wrapped_data->iv, wrapped_data->enc_data); + WTPI_K1_FreeKeyHandle(encryption_key); + if (result != OEMCrypto_SUCCESS) return result; + // Compute the signature of the data past the signature block and store it + // at the start of the output buffer. + WTPI_K1_SymmetricKey_Handle signing_key = NULL; + result = WTPI_K1_DeriveDeviceKeyIntoHandle(context, MAC_KEY_CLIENT, + &signing_key, KEY_SIZE_256); + if (result != OEMCrypto_SUCCESS) return result; + const size_t offset = sizeof(wrapped_header->signature); + result = WTPI_C1_HMAC_SHA256(signing_key, out + offset, needed_size - offset, + wrapped_header->signature); + WTPI_K1_FreeKeyHandle(signing_key); + return result; +} + +class LegacyKeywrapTest : public ::testing::Test { + protected: + LegacyKeywrapTest() {} + + void SetUp() override { + ::testing::Test::SetUp(); + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name()); + ASSERT_EQ(true, OPK_Initialize()); + ASSERT_EQ(OEMCrypto_SUCCESS, WTPI_K1_InitializeKeyManagement()); + } + + void TearDown() override { + ASSERT_EQ(OEMCrypto_SUCCESS, WTPI_K1_TerminateKeyManagement()); + OPK_Terminate(); + ::testing::Test::TearDown(); + } +}; + +TEST_F(LegacyKeywrapTest, UnwrapDrmLegacyKey) { + OEMCryptoResult res = OEMCrypto_ERROR_INVALID_CONTEXT; + std::vector wrapped_key; + size_t required_size = wrapped_key.size(); + uint8_t* clear_key = test_rsa_key_der; + size_t clear_key_len = TEST_RSA_KEY_DER_LEN; + AsymmetricKeyType key_type = DRM_RSA_PRIVATE_KEY; + + // Get required max size (most recent impl, larger than v1 wrapping size) + res = + WTPI_GetWrappedAsymmetricKeySize(clear_key_len, key_type, &required_size); + ASSERT_EQ(res, OEMCrypto_SUCCESS); + wrapped_key.resize(required_size); + + // Will be changed to reflect the actual size of the wrapped key + size_t v1_wrapped_key_size = wrapped_key.size(); + + // Wrap and unwrap using v1 scheme + res = EncryptAndSign_V1(DEVICE_KEY_WRAP_DRM_CERT_V1, clear_key, + clear_key_len, wrapped_key.data(), + &v1_wrapped_key_size); + ASSERT_EQ(res, OEMCrypto_SUCCESS); + + WTPI_AsymmetricKey_Handle unwrapped_key_handle; + uint32_t allowed_schemes = 0; + res = WTPI_UnwrapIntoAsymmetricKeyHandle( + DEVICE_KEY_WRAP_DRM_CERT, wrapped_key.data(), v1_wrapped_key_size, + key_type, &unwrapped_key_handle, &allowed_schemes); + ASSERT_EQ(res, OEMCrypto_SUCCESS); + + // Create a key handle directly + WTPI_AsymmetricKey_Handle created_key_handle; + res = WTPI_CreateAsymmetricKeyHandle(clear_key, clear_key_len, key_type, + &created_key_handle); + ASSERT_EQ(res, OEMCrypto_SUCCESS); + + // Compare the two key handles to ensure they are the same + for (WTPI_AsymmetricKey_Handle handle : + {unwrapped_key_handle, created_key_handle}) { + std::vector output(256, 0); + size_t output_len = 256; + ASSERT_EQ(OEMCrypto_SUCCESS, + WTPI_RSADecrypt(handle, hello_world_encrypted, + HELLO_WORLD_ENC_LEN, output.data(), &output_len)); + + output.resize(output_len); + std::string message = "Hello world!\n"; + std::vector expected(message.begin(), message.end()); + ASSERT_EQ(expected, output); + } +} diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/provisioning_4_interface_test.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/provisioning_4_interface_test.cpp index f68f1dd..86a482f 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/provisioning_4_interface_test.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/provisioning_4_interface_test.cpp @@ -14,6 +14,7 @@ #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" #include "wtpi_provisioning_4_interface.h" +#include "wtpi_device_key_interface.h" using wtpi_test::EcKeyPtr; using wtpi_test::ExtractPublicKeyFromBcc; @@ -267,16 +268,18 @@ TEST_F(Prov4Test, GenerateRandomCertificateKeyPairSuccess) { uint8_t wrapped_private_key[kBufferSize]; size_t wrapped_private_key_length = sizeof(wrapped_private_key); - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( - &type, wrapped_private_key, &wrapped_private_key_length, - public_key.data(), &public_key_length), - OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_EQ( + WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, + &wrapped_private_key_length, public_key.data(), &public_key_length), + OEMCrypto_ERROR_SHORT_BUFFER); public_key.resize(public_key_length); - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( - &type, wrapped_private_key, &wrapped_private_key_length, - public_key.data(), &public_key_length), - OEMCrypto_SUCCESS); + ASSERT_EQ( + WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, + &wrapped_private_key_length, public_key.data(), &public_key_length), + OEMCrypto_SUCCESS); EXPECT_TRUE(type == DRM_ECC_PRIVATE_KEY || type == DRM_RSA_PRIVATE_KEY); EXPECT_GT(public_key_length, size_t(0)); @@ -288,7 +291,7 @@ TEST_F(Prov4Test, GenerateRandomCertificateKeyPairSuccess) { // it with public key to ensure keypair is valid WTPI_AsymmetricKey_Handle key_handle; uint32_t allowed_schemes; - ASSERT_EQ(WTPI_UnwrapIntoAsymmetricKeyHandle(wrapped_private_key, + ASSERT_EQ(WTPI_UnwrapIntoAsymmetricKeyHandle(DEVICE_KEY_WRAP_DRM_CERT, wrapped_private_key, wrapped_private_key_length, type, &key_handle, &allowed_schemes), OEMCrypto_SUCCESS); @@ -373,42 +376,42 @@ TEST_F(Prov4Test, GenerateRandomCertificateKeyPairFailsForBadInput) { size_t wrapped_private_key_length = sizeof(wrapped_private_key); ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( - NULL, wrapped_private_key, &wrapped_private_key_length, + CERT_SIGNATURE_DRM, NULL, wrapped_private_key, + &wrapped_private_key_length, public_key, &public_key_length), + OEMCrypto_ERROR_INVALID_CONTEXT); + + ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, NULL, public_key, &public_key_length), OEMCrypto_ERROR_INVALID_CONTEXT); - ASSERT_EQ( - WTPI_GenerateRandomCertificateKeyPair(&type, wrapped_private_key, NULL, - public_key, &public_key_length), - OEMCrypto_ERROR_INVALID_CONTEXT); - - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair(&type, wrapped_private_key, - &wrapped_private_key_length, - public_key, NULL), + ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, + &wrapped_private_key_length, public_key, NULL), OEMCrypto_ERROR_INVALID_CONTEXT); size_t bad_size = 0; - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair(&type, wrapped_private_key, - &bad_size, public_key, - &public_key_length), + ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, &bad_size, + public_key, &public_key_length), OEMCrypto_ERROR_SHORT_BUFFER); EXPECT_GT(bad_size, size_t(0)); bad_size = 0; - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair(&type, wrapped_private_key, - &wrapped_private_key_length, - public_key, &bad_size), + ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, + &wrapped_private_key_length, public_key, &bad_size), OEMCrypto_ERROR_SHORT_BUFFER); EXPECT_GT(bad_size, size_t(0)); ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( - &type, NULL, &wrapped_private_key_length, public_key, - &public_key_length), + CERT_SIGNATURE_DRM, &type, NULL, + &wrapped_private_key_length, public_key, &public_key_length), OEMCrypto_ERROR_SHORT_BUFFER); - ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair(&type, wrapped_private_key, - &wrapped_private_key_length, - NULL, &public_key_length), + ASSERT_EQ(WTPI_GenerateRandomCertificateKeyPair( + CERT_SIGNATURE_DRM, &type, wrapped_private_key, + &wrapped_private_key_length, NULL, &public_key_length), OEMCrypto_ERROR_SHORT_BUFFER); } diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_oemcrypto_tee_test_api.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_oemcrypto_tee_test_api.c index b9c259f..b62a8a2 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_oemcrypto_tee_test_api.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_oemcrypto_tee_test_api.c @@ -867,8 +867,9 @@ cleanup_and_return: } OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( - const uint8_t* input, size_t input_length, AsymmetricKeyType key_type, - WTPI_AsymmetricKey_Handle* key_handle, uint32_t* allowed_schemes) { + uint32_t context, const uint8_t* input, size_t input_length, + AsymmetricKeyType key_type, WTPI_AsymmetricKey_Handle* key_handle, + uint32_t* allowed_schemes) { pthread_mutex_lock(&api_lock); OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; ODK_Message request = ODK_Message_Create(NULL, 0); @@ -876,7 +877,7 @@ OEMCryptoResult WTPI_UnwrapIntoAsymmetricKeyHandle( API_Initialize(); request = OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Request( - input, input_length, key_type, key_handle, allowed_schemes); + context, input, input_length, key_type, key_handle, allowed_schemes); if (ODK_Message_GetStatus(&request) != MESSAGE_STATUS_OK) { if (ODK_Message_GetStatus(&request) == MESSAGE_STATUS_BUFFER_TOO_LARGE) { api_result = OEMCrypto_ERROR_BUFFER_TOO_LARGE; @@ -971,7 +972,8 @@ cleanup_and_return: return result; } -OEMCryptoResult WTPI_WrapAsymmetricKey(uint8_t* output, size_t output_length, +OEMCryptoResult WTPI_WrapAsymmetricKey(uint32_t context, uint8_t* output, + size_t output_length, AsymmetricKeyType key_type, const uint8_t* clear_key, size_t clear_key_length) { @@ -981,8 +983,8 @@ OEMCryptoResult WTPI_WrapAsymmetricKey(uint8_t* output, size_t output_length, ODK_Message response = ODK_Message_Create(NULL, 0); API_Initialize(); - request = OPK_Pack_WrapAsymmetricKey_Request(output, output_length, key_type, - clear_key, clear_key_length); + request = OPK_Pack_WrapAsymmetricKey_Request( + context, output, output_length, key_type, clear_key, clear_key_length); if (ODK_Message_GetStatus(&request) != MESSAGE_STATUS_OK) { if (ODK_Message_GetStatus(&request) == MESSAGE_STATUS_BUFFER_TOO_LARGE) { api_result = OEMCrypto_ERROR_BUFFER_TOO_LARGE; @@ -1223,6 +1225,40 @@ cleanup_and_return: return result; } +OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( + WTPI_AsymmetricKey_Handle* key_handle) { + pthread_mutex_lock(&api_lock); + OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + ODK_Message request = ODK_Message_Create(NULL, 0); + ODK_Message response = ODK_Message_Create(NULL, 0); + + API_Initialize(); + request = OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Request(key_handle); + if (ODK_Message_GetStatus(&request) != MESSAGE_STATUS_OK) { + if (ODK_Message_GetStatus(&request) == MESSAGE_STATUS_BUFFER_TOO_LARGE) { + api_result = OEMCrypto_ERROR_BUFFER_TOO_LARGE; + } else { + api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + goto cleanup_and_return; + } + response = API_Transact(&request); + OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Response(&response, &result, + &key_handle); + + if (ODK_Message_GetStatus(&response) != MESSAGE_STATUS_OK) { + api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + } +cleanup_and_return: + TOS_Transport_ReleaseMessage(&request); + TOS_Transport_ReleaseMessage(&response); + + API_Terminate(); + result = API_CheckResult(result); + pthread_mutex_unlock(&api_lock); + return result; +} + OEMCryptoResult WTPI_GetBootCertificateChain(uint8_t* out, size_t* out_length) { pthread_mutex_lock(&api_lock); OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -1290,9 +1326,9 @@ cleanup_and_return: } OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( - AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length, uint8_t* public_key, - size_t* public_key_length) { + CertSignatureType cert_type, AsymmetricKeyType* key_type, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, + uint8_t* public_key, size_t* public_key_length) { pthread_mutex_lock(&api_lock); OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; ODK_Message request = ODK_Message_Create(NULL, 0); @@ -1300,8 +1336,8 @@ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( API_Initialize(); request = OPK_Pack_GenerateRandomCertificateKeyPair_Request( - key_type, wrapped_private_key, wrapped_private_key_length, public_key, - public_key_length); + cert_type, key_type, wrapped_private_key, wrapped_private_key_length, + public_key, public_key_length); if (ODK_Message_GetStatus(&request) != MESSAGE_STATUS_OK) { if (ODK_Message_GetStatus(&request) == MESSAGE_STATUS_BUFFER_TOO_LARGE) { api_result = OEMCrypto_ERROR_BUFFER_TOO_LARGE; diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.c index f01039e..ee162ee 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.c @@ -821,8 +821,8 @@ void OPK_Unpack_CreateAsymmetricKeyHandle_Response( } ODK_Message OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Request( - const uint8_t* input, size_t input_length, AsymmetricKeyType key_type, - const WTPI_AsymmetricKey_Handle* key_handle, + uint32_t context, const uint8_t* input, size_t input_length, + AsymmetricKeyType key_type, const WTPI_AsymmetricKey_Handle* key_handle, const uint32_t* allowed_schemes) { uint32_t api_value = 10024; /* from _tee10024 */ ODK_Message msg = TOS_Transport_GetRequest(); @@ -830,6 +830,7 @@ ODK_Message OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Request( uint64_t timestamp = time(0); OPK_Pack_uint64_t(&msg, ×tamp); OPK_Pack_size_t(&msg, &input_length); + OPK_Pack_uint32_t(&msg, &context); OPK_PackMemory(&msg, (const uint8_t*)input, OPK_ToLengthType(input_length)); OPK_Pack_AsymmetricKeyType(&msg, &key_type); OPK_PackIsNull(&msg, key_handle); @@ -936,7 +937,8 @@ void OPK_Unpack_GetWrappedAsymmetricKeySize_Response(ODK_Message* msg, } } -ODK_Message OPK_Pack_WrapAsymmetricKey_Request(const uint8_t* output, +ODK_Message OPK_Pack_WrapAsymmetricKey_Request(uint32_t context, + const uint8_t* output, size_t output_length, AsymmetricKeyType key_type, const uint8_t* clear_key, @@ -948,6 +950,7 @@ ODK_Message OPK_Pack_WrapAsymmetricKey_Request(const uint8_t* output, OPK_Pack_uint64_t(&msg, ×tamp); OPK_Pack_size_t(&msg, &output_length); OPK_Pack_size_t(&msg, &clear_key_length); + OPK_Pack_uint32_t(&msg, &context); OPK_PackAlloc(&msg, output); OPK_Pack_AsymmetricKeyType(&msg, &key_type); OPK_PackMemory(&msg, (const uint8_t*)clear_key, @@ -1247,9 +1250,45 @@ void OPK_Unpack_GetSignatureHashAlgorithm_Response( } } +ODK_Message OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Request( + const WTPI_AsymmetricKey_Handle* key_handle) { + uint32_t api_value = 10034; /* from _tee10034 */ + ODK_Message msg = TOS_Transport_GetRequest(); + OPK_Pack_uint32_t(&msg, &api_value); + uint64_t timestamp = time(0); + OPK_Pack_uint64_t(&msg, ×tamp); + OPK_PackIsNull(&msg, key_handle); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + +void OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Response( + ODK_Message* msg, OEMCryptoResult* result, + WTPI_AsymmetricKey_Handle** key_handle) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 10034) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + OPK_Unpack_uint32_t(msg, result); + if (!Is_Valid_OEMCryptoResult(*result)) { + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_INVALID_ENUM_VALUE); + } + if (SuccessResult(*result)) { + OPK_UnpackNullable_WTPI_AsymmetricKey_Handle(msg, key_handle); + } else { + OPK_UnpackNullable_WTPI_AsymmetricKey_Handle(msg, NULL); + } + OPK_UnpackEOM(msg); + + if (SuccessResult(*result)) { + OPK_SharedBuffer_FinalizeUnpacking(); + } +} + ODK_Message OPK_Pack_GetBootCertificateChain_Request(const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10034; /* from _tee10034 */ + uint32_t api_value = 10035; /* from _tee10035 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1267,7 +1306,7 @@ void OPK_Unpack_GetBootCertificateChain_Response(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10034) + if (api_value != 10035) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -1290,7 +1329,7 @@ void OPK_Unpack_GetBootCertificateChain_Response(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBootCertificateChainSize_Request( const size_t* out_length) { - uint32_t api_value = 10035; /* from _tee10035 */ + uint32_t api_value = 10036; /* from _tee10036 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1306,7 +1345,7 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Response(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10035) + if (api_value != 10036) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1325,16 +1364,18 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GenerateRandomCertificateKeyPair_Request( - const AsymmetricKeyType* key_type, const uint8_t* wrapped_private_key, + CertSignatureType cert_type, const AsymmetricKeyType* key_type, + const uint8_t* wrapped_private_key, const size_t* wrapped_private_key_length, const uint8_t* public_key, const size_t* public_key_length) { - uint32_t api_value = 10036; /* from _tee10036 */ + uint32_t api_value = 10037; /* from _tee10037 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); OPK_Pack_uint64_t(&msg, ×tamp); OPK_PackNullable_size_t(&msg, wrapped_private_key_length); OPK_PackNullable_size_t(&msg, public_key_length); + OPK_Pack_CertSignatureType(&msg, &cert_type); OPK_PackIsNull(&msg, key_type); OPK_PackAlloc(&msg, wrapped_private_key); OPK_PackAlloc(&msg, public_key); @@ -1349,7 +1390,7 @@ void OPK_Unpack_GenerateRandomCertificateKeyPair_Response( uint8_t** public_key, size_t** public_key_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10036) + if (api_value != 10037) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, wrapped_private_key_length); OPK_UnpackNullable_size_t(msg, public_key_length); @@ -1389,7 +1430,7 @@ ODK_Message OPK_Pack_GetSignedCsrPayload_Request( const uint8_t* encoded_device_info, size_t encoded_device_info_length, const uint8_t* signed_csr_payload, const size_t* signed_csr_payload_length) { - uint32_t api_value = 10037; /* from _tee10037 */ + uint32_t api_value = 10038; /* from _tee10038 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1412,7 +1453,7 @@ void OPK_Unpack_GetSignedCsrPayload_Response( size_t** signed_csr_payload_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10037) + if (api_value != 10038) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, signed_csr_payload_length); OPK_Unpack_uint32_t(msg, result); @@ -1435,7 +1476,7 @@ void OPK_Unpack_GetSignedCsrPayload_Response( } ODK_Message OPK_Pack_MaxDeviceInfoSize_Request(void) { - uint32_t api_value = 10038; /* from _tee10038 */ + uint32_t api_value = 10039; /* from _tee10039 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1448,7 +1489,7 @@ ODK_Message OPK_Pack_MaxDeviceInfoSize_Request(void) { void OPK_Unpack_MaxDeviceInfoSize_Response(ODK_Message* msg, size_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10038) + if (api_value != 10039) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -1457,7 +1498,7 @@ void OPK_Unpack_MaxDeviceInfoSize_Response(ODK_Message* msg, size_t* result) { ODK_Message OPK_Pack_GetDeviceInformation_Request(const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10039; /* from _tee10039 */ + uint32_t api_value = 10040; /* from _tee10040 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1475,7 +1516,7 @@ void OPK_Unpack_GetDeviceInformation_Response(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10039) + if (api_value != 10040) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -1500,7 +1541,7 @@ ODK_Message OPK_Pack_BccKeyCoseSign1_Request(const uint8_t* message, size_t message_length, const uint8_t* signature, const size_t* signature_length) { - uint32_t api_value = 10040; /* from _tee10040 */ + uint32_t api_value = 10041; /* from _tee10041 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1521,7 +1562,7 @@ void OPK_Unpack_BccKeyCoseSign1_Response(ODK_Message* msg, size_t** signature_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10040) + if (api_value != 10041) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, signature_length); OPK_Unpack_uint32_t(msg, result); @@ -1544,7 +1585,7 @@ void OPK_Unpack_BccKeyCoseSign1_Response(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBccKeyCoseSign1Size_Request( const size_t* out_length) { - uint32_t api_value = 10041; /* from _tee10041 */ + uint32_t api_value = 10042; /* from _tee10042 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1560,7 +1601,7 @@ void OPK_Unpack_GetMaxBccKeyCoseSign1Size_Response(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10041) + if (api_value != 10042) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1579,7 +1620,7 @@ void OPK_Unpack_GetMaxBccKeyCoseSign1Size_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetDeviceFusedStatus_Request(const bool* is_fused) { - uint32_t api_value = 10042; /* from _tee10042 */ + uint32_t api_value = 10043; /* from _tee10043 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1595,7 +1636,7 @@ void OPK_Unpack_GetDeviceFusedStatus_Response(ODK_Message* msg, bool** is_fused) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10042) + if (api_value != 10043) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1614,7 +1655,7 @@ void OPK_Unpack_GetDeviceFusedStatus_Response(ODK_Message* msg, } ODK_Message OPK_Pack_Crc32Init_Request(const uint32_t* initial_hash) { - uint32_t api_value = 10043; /* from _tee10043 */ + uint32_t api_value = 10044; /* from _tee10044 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1629,7 +1670,7 @@ void OPK_Unpack_Crc32Init_Response(ODK_Message* msg, OEMCryptoResult* result, uint32_t** initial_hash) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10043) + if (api_value != 10044) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1650,7 +1691,7 @@ void OPK_Unpack_Crc32Init_Response(ODK_Message* msg, OEMCryptoResult* result, ODK_Message OPK_Pack_Crc32Cont_Request(const uint8_t* in, size_t in_length, uint32_t prev_crc, const uint32_t* new_crc) { - uint32_t api_value = 10044; /* from _tee10044 */ + uint32_t api_value = 10045; /* from _tee10045 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1668,7 +1709,7 @@ void OPK_Unpack_Crc32Cont_Response(ODK_Message* msg, OEMCryptoResult* result, uint32_t** new_crc) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10044) + if (api_value != 10045) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1691,7 +1732,7 @@ ODK_Message OPK_Pack_Crc32Cont_OutputBuffer_Request(const OPK_OutputBuffer* in, size_t in_length, uint32_t prev_crc, const uint32_t* new_crc) { - uint32_t api_value = 10045; /* from _tee10045 */ + uint32_t api_value = 10046; /* from _tee10046 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1723,7 +1764,7 @@ void OPK_Unpack_Crc32Cont_OutputBuffer_Response(ODK_Message* msg, uint32_t** new_crc) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10045) + if (api_value != 10046) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1742,7 +1783,7 @@ void OPK_Unpack_Crc32Cont_OutputBuffer_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetTrustedTime_Request(const uint64_t* time_in_s) { - uint32_t api_value = 10046; /* from _tee10046 */ + uint32_t api_value = 10047; /* from _tee10047 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1758,7 +1799,7 @@ void OPK_Unpack_GetTrustedTime_Response(ODK_Message* msg, uint64_t** time_in_s) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10046) + if (api_value != 10047) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1777,7 +1818,7 @@ void OPK_Unpack_GetTrustedTime_Response(ODK_Message* msg, } ODK_Message OPK_Pack_InitializeClock_Request(void) { - uint32_t api_value = 10047; /* from _tee10047 */ + uint32_t api_value = 10048; /* from _tee10048 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1791,34 +1832,6 @@ void OPK_Unpack_InitializeClock_Response(ODK_Message* msg, OEMCryptoResult* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10047) - ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); - OPK_Unpack_uint32_t(msg, result); - if (!Is_Valid_OEMCryptoResult(*result)) { - ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_INVALID_ENUM_VALUE); - } - OPK_UnpackEOM(msg); - - if (SuccessResult(*result)) { - OPK_SharedBuffer_FinalizeUnpacking(); - } -} - -ODK_Message OPK_Pack_TerminateClock_Request(void) { - uint32_t api_value = 10048; /* from _tee10048 */ - ODK_Message msg = TOS_Transport_GetRequest(); - OPK_Pack_uint32_t(&msg, &api_value); - uint64_t timestamp = time(0); - OPK_Pack_uint64_t(&msg, ×tamp); - OPK_PackEOM(&msg); - OPK_SharedBuffer_FinalizePacking(); - return msg; -} - -void OPK_Unpack_TerminateClock_Response(ODK_Message* msg, - OEMCryptoResult* result) { - uint32_t api_value = UINT32_MAX; - OPK_Unpack_uint32_t(msg, &api_value); if (api_value != 10048) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); @@ -1832,7 +1845,7 @@ void OPK_Unpack_TerminateClock_Response(ODK_Message* msg, } } -ODK_Message OPK_Pack_GetClockType_Request(void) { +ODK_Message OPK_Pack_TerminateClock_Request(void) { uint32_t api_value = 10049; /* from _tee10049 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); @@ -1843,11 +1856,39 @@ ODK_Message OPK_Pack_GetClockType_Request(void) { return msg; } +void OPK_Unpack_TerminateClock_Response(ODK_Message* msg, + OEMCryptoResult* result) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 10049) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + OPK_Unpack_uint32_t(msg, result); + if (!Is_Valid_OEMCryptoResult(*result)) { + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_INVALID_ENUM_VALUE); + } + OPK_UnpackEOM(msg); + + if (SuccessResult(*result)) { + OPK_SharedBuffer_FinalizeUnpacking(); + } +} + +ODK_Message OPK_Pack_GetClockType_Request(void) { + uint32_t api_value = 10050; /* from _tee10050 */ + ODK_Message msg = TOS_Transport_GetRequest(); + OPK_Pack_uint32_t(&msg, &api_value); + uint64_t timestamp = time(0); + OPK_Pack_uint64_t(&msg, ×tamp); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + void OPK_Unpack_GetClockType_Response(ODK_Message* msg, OEMCrypto_Clock_Security_Level* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10049) + if (api_value != 10050) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_Clock_Security_Level(msg, result); OPK_UnpackEOM(msg); @@ -1855,7 +1896,7 @@ void OPK_Unpack_GetClockType_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetSecurityLevel_Request(void) { - uint32_t api_value = 10050; /* from _tee10050 */ + uint32_t api_value = 10051; /* from _tee10051 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1869,7 +1910,7 @@ void OPK_Unpack_GetSecurityLevel_Response(ODK_Message* msg, OEMCrypto_Security_Level* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10050) + if (api_value != 10051) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_Security_Level(msg, result); OPK_UnpackEOM(msg); @@ -1877,7 +1918,7 @@ void OPK_Unpack_GetSecurityLevel_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetProvisioningMethod_Request(void) { - uint32_t api_value = 10051; /* from _tee10051 */ + uint32_t api_value = 10052; /* from _tee10052 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1891,7 +1932,7 @@ void OPK_Unpack_GetProvisioningMethod_Response( ODK_Message* msg, OEMCrypto_ProvisioningMethod* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10051) + if (api_value != 10052) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_ProvisioningMethod(msg, result); OPK_UnpackEOM(msg); @@ -1899,7 +1940,7 @@ void OPK_Unpack_GetProvisioningMethod_Response( } ODK_Message OPK_Pack_GetResourceRatingTier_Request(void) { - uint32_t api_value = 10052; /* from _tee10052 */ + uint32_t api_value = 10053; /* from _tee10053 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1913,7 +1954,7 @@ void OPK_Unpack_GetResourceRatingTier_Response(ODK_Message* msg, uint32_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10052) + if (api_value != 10053) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); OPK_UnpackEOM(msg); @@ -1921,7 +1962,7 @@ void OPK_Unpack_GetResourceRatingTier_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsTAAntiRollbackEnabled_Request(void) { - uint32_t api_value = 10053; /* from _tee10053 */ + uint32_t api_value = 10054; /* from _tee10054 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1935,7 +1976,7 @@ void OPK_Unpack_IsTAAntiRollbackEnabled_Response(ODK_Message* msg, OPK_FeatureStatus* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10053) + if (api_value != 10054) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OPK_FeatureStatus(*result)) { @@ -1946,7 +1987,7 @@ void OPK_Unpack_IsTAAntiRollbackEnabled_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsProductionReady_Request(void) { - uint32_t api_value = 10054; /* from _tee10054 */ + uint32_t api_value = 10055; /* from _tee10055 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1959,7 +2000,7 @@ ODK_Message OPK_Pack_IsProductionReady_Request(void) { void OPK_Unpack_IsProductionReady_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10054) + if (api_value != 10055) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -1967,7 +2008,7 @@ void OPK_Unpack_IsProductionReady_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_GetWatermarkingSupport_Request(void) { - uint32_t api_value = 10055; /* from _tee10055 */ + uint32_t api_value = 10056; /* from _tee10056 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1981,7 +2022,7 @@ void OPK_Unpack_GetWatermarkingSupport_Response( ODK_Message* msg, OEMCrypto_WatermarkingSupport* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10055) + if (api_value != 10056) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_WatermarkingSupport(msg, result); OPK_UnpackEOM(msg); @@ -1989,7 +2030,7 @@ void OPK_Unpack_GetWatermarkingSupport_Response( } ODK_Message OPK_Pack_GetCurrentSRMVersion_Request(const uint32_t* srm_version) { - uint32_t api_value = 10056; /* from _tee10056 */ + uint32_t api_value = 10057; /* from _tee10057 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2005,7 +2046,7 @@ void OPK_Unpack_GetCurrentSRMVersion_Response(ODK_Message* msg, uint32_t** srm_version) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10056) + if (api_value != 10057) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -2024,7 +2065,7 @@ void OPK_Unpack_GetCurrentSRMVersion_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsAntiRollbackHWPresent_Request(void) { - uint32_t api_value = 10057; /* from _tee10057 */ + uint32_t api_value = 10058; /* from _tee10058 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2038,7 +2079,7 @@ void OPK_Unpack_IsAntiRollbackHWPresent_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10057) + if (api_value != 10058) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2046,7 +2087,7 @@ void OPK_Unpack_IsAntiRollbackHWPresent_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsCGMS_AActive_Request(void) { - uint32_t api_value = 10058; /* from _tee10058 */ + uint32_t api_value = 10059; /* from _tee10059 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2059,7 +2100,7 @@ ODK_Message OPK_Pack_IsCGMS_AActive_Request(void) { void OPK_Unpack_IsCGMS_AActive_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10058) + if (api_value != 10059) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2067,7 +2108,7 @@ void OPK_Unpack_IsCGMS_AActive_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_SupportsCGMS_A_Request(void) { - uint32_t api_value = 10059; /* from _tee10059 */ + uint32_t api_value = 10060; /* from _tee10060 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2080,7 +2121,7 @@ ODK_Message OPK_Pack_SupportsCGMS_A_Request(void) { void OPK_Unpack_SupportsCGMS_A_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10059) + if (api_value != 10060) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2088,7 +2129,7 @@ void OPK_Unpack_SupportsCGMS_A_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_HasAnalogDisplay_Request(void) { - uint32_t api_value = 10060; /* from _tee10060 */ + uint32_t api_value = 10061; /* from _tee10061 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2101,7 +2142,7 @@ ODK_Message OPK_Pack_HasAnalogDisplay_Request(void) { void OPK_Unpack_HasAnalogDisplay_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10060) + if (api_value != 10061) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2109,7 +2150,7 @@ void OPK_Unpack_HasAnalogDisplay_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_IsAnalogDisplayActive_Request(void) { - uint32_t api_value = 10061; /* from _tee10061 */ + uint32_t api_value = 10062; /* from _tee10062 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2122,7 +2163,7 @@ ODK_Message OPK_Pack_IsAnalogDisplayActive_Request(void) { void OPK_Unpack_IsAnalogDisplayActive_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10061) + if (api_value != 10062) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2130,7 +2171,7 @@ void OPK_Unpack_IsAnalogDisplayActive_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_CanDisableAnalogDisplay_Request(void) { - uint32_t api_value = 10062; /* from _tee10062 */ + uint32_t api_value = 10063; /* from _tee10063 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2144,7 +2185,7 @@ void OPK_Unpack_CanDisableAnalogDisplay_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10062) + if (api_value != 10063) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2152,7 +2193,7 @@ void OPK_Unpack_CanDisableAnalogDisplay_Response(ODK_Message* msg, } ODK_Message OPK_Pack_DisableAnalogDisplay_Request(void) { - uint32_t api_value = 10063; /* from _tee10063 */ + uint32_t api_value = 10064; /* from _tee10064 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2165,7 +2206,7 @@ ODK_Message OPK_Pack_DisableAnalogDisplay_Request(void) { void OPK_Unpack_DisableAnalogDisplay_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10063) + if (api_value != 10064) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2173,7 +2214,7 @@ void OPK_Unpack_DisableAnalogDisplay_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_MaxOutputSizeForDecrypt_Request(void) { - uint32_t api_value = 10064; /* from _tee10064 */ + uint32_t api_value = 10065; /* from _tee10065 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2187,7 +2228,7 @@ void OPK_Unpack_MaxOutputSizeForDecrypt_Response(ODK_Message* msg, size_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10064) + if (api_value != 10065) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2195,7 +2236,7 @@ void OPK_Unpack_MaxOutputSizeForDecrypt_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsClosedPlatform_Request(void) { - uint32_t api_value = 10065; /* from _tee10065 */ + uint32_t api_value = 10066; /* from _tee10066 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2208,7 +2249,7 @@ ODK_Message OPK_Pack_IsClosedPlatform_Request(void) { void OPK_Unpack_IsClosedPlatform_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10065) + if (api_value != 10066) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2216,7 +2257,7 @@ void OPK_Unpack_IsClosedPlatform_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_CurrentHDCPCapability_Request(void) { - uint32_t api_value = 10066; /* from _tee10066 */ + uint32_t api_value = 10067; /* from _tee10067 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2230,7 +2271,7 @@ void OPK_Unpack_CurrentHDCPCapability_Response( ODK_Message* msg, OEMCrypto_HDCP_Capability* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10066) + if (api_value != 10067) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_HDCP_Capability(msg, result); OPK_UnpackEOM(msg); @@ -2238,7 +2279,7 @@ void OPK_Unpack_CurrentHDCPCapability_Response( } ODK_Message OPK_Pack_MaxHDCPCapability_Request(void) { - uint32_t api_value = 10067; /* from _tee10067 */ + uint32_t api_value = 10068; /* from _tee10068 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2252,7 +2293,7 @@ void OPK_Unpack_MaxHDCPCapability_Response(ODK_Message* msg, OEMCrypto_HDCP_Capability* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10067) + if (api_value != 10068) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_HDCP_Capability(msg, result); OPK_UnpackEOM(msg); @@ -2260,7 +2301,7 @@ void OPK_Unpack_MaxHDCPCapability_Response(ODK_Message* msg, } ODK_Message OPK_Pack_MaxBufferSizeForGenericCrypto_Request(void) { - uint32_t api_value = 10068; /* from _tee10068 */ + uint32_t api_value = 10069; /* from _tee10069 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2274,7 +2315,7 @@ void OPK_Unpack_MaxBufferSizeForGenericCrypto_Response(ODK_Message* msg, size_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10068) + if (api_value != 10069) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2282,7 +2323,7 @@ void OPK_Unpack_MaxBufferSizeForGenericCrypto_Response(ODK_Message* msg, } ODK_Message OPK_Pack_MaxSampleSize_Request(void) { - uint32_t api_value = 10069; /* from _tee10069 */ + uint32_t api_value = 10070; /* from _tee10070 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2295,7 +2336,7 @@ ODK_Message OPK_Pack_MaxSampleSize_Request(void) { void OPK_Unpack_MaxSampleSize_Response(ODK_Message* msg, size_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10069) + if (api_value != 10070) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2303,7 +2344,7 @@ void OPK_Unpack_MaxSampleSize_Response(ODK_Message* msg, size_t* result) { } ODK_Message OPK_Pack_SupportedCertificates_Request(void) { - uint32_t api_value = 10070; /* from _tee10070 */ + uint32_t api_value = 10071; /* from _tee10071 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2317,7 +2358,7 @@ void OPK_Unpack_SupportedCertificates_Response(ODK_Message* msg, uint32_t* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10070) + if (api_value != 10071) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); OPK_UnpackEOM(msg); @@ -2325,7 +2366,7 @@ void OPK_Unpack_SupportedCertificates_Response(ODK_Message* msg, } ODK_Message OPK_Pack_ContentDecryptBypassesTA_Request(void) { - uint32_t api_value = 10071; /* from _tee10071 */ + uint32_t api_value = 10072; /* from _tee10072 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2339,7 +2380,7 @@ void OPK_Unpack_ContentDecryptBypassesTA_Response(ODK_Message* msg, bool* result) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10071) + if (api_value != 10072) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2348,7 +2389,7 @@ void OPK_Unpack_ContentDecryptBypassesTA_Response(ODK_Message* msg, ODK_Message OPK_Pack_GetEncryptAndSignSize_Request( uint32_t context, size_t in_length, const size_t* wrapped_length) { - uint32_t api_value = 10072; /* from _tee10072 */ + uint32_t api_value = 10073; /* from _tee10073 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2366,7 +2407,7 @@ void OPK_Unpack_GetEncryptAndSignSize_Response(ODK_Message* msg, size_t** wrapped_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10072) + if (api_value != 10073) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -2389,7 +2430,7 @@ ODK_Message OPK_Pack_EncryptAndSign_Request(uint32_t context, size_t data_length, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10073; /* from _tee10073 */ + uint32_t api_value = 10074; /* from _tee10074 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2409,7 +2450,7 @@ void OPK_Unpack_EncryptAndSign_Response(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10073) + if (api_value != 10074) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -2435,7 +2476,7 @@ ODK_Message OPK_Pack_VerifyAndDecrypt_Request(uint32_t context, size_t wrapped_length, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10074; /* from _tee10074 */ + uint32_t api_value = 10075; /* from _tee10075 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2456,7 +2497,7 @@ void OPK_Unpack_VerifyAndDecrypt_Response(ODK_Message* msg, uint8_t** out, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10074) + if (api_value != 10075) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -2480,7 +2521,7 @@ void OPK_Unpack_VerifyAndDecrypt_Response(ODK_Message* msg, ODK_Message OPK_Pack_VerifyAndDecryptUsageData_Legacy_Request( const uint8_t* wrapped, size_t wrapped_length, const uint8_t* signature, const uint8_t* iv, const uint8_t* out) { - uint32_t api_value = 10075; /* from _tee10075 */ + uint32_t api_value = 10076; /* from _tee10076 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -2500,7 +2541,7 @@ void OPK_Unpack_VerifyAndDecryptUsageData_Legacy_Response( ODK_Message* msg, OEMCryptoResult* result, uint8_t** out) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10075) + if (api_value != 10076) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.h b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.h index 33def3b..ab40914 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ree/GEN_ree_serializer.h @@ -137,8 +137,8 @@ void OPK_Unpack_CreateAsymmetricKeyHandle_Response( ODK_Message* msg, OEMCryptoResult* result, WTPI_AsymmetricKey_Handle** key_handle); ODK_Message OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Request( - const uint8_t* input, size_t input_length, AsymmetricKeyType key_type, - const WTPI_AsymmetricKey_Handle* key_handle, + uint32_t context, const uint8_t* input, size_t input_length, + AsymmetricKeyType key_type, const WTPI_AsymmetricKey_Handle* key_handle, const uint32_t* allowed_schemes); void OPK_Unpack_UnwrapIntoAsymmetricKeyHandle_Response( ODK_Message* msg, OEMCryptoResult* result, @@ -153,7 +153,8 @@ ODK_Message OPK_Pack_GetWrappedAsymmetricKeySize_Request( void OPK_Unpack_GetWrappedAsymmetricKeySize_Response(ODK_Message* msg, OEMCryptoResult* result, size_t** buffer_size); -ODK_Message OPK_Pack_WrapAsymmetricKey_Request(const uint8_t* output, +ODK_Message OPK_Pack_WrapAsymmetricKey_Request(uint32_t context, + const uint8_t* output, size_t output_length, AsymmetricKeyType key_type, const uint8_t* clear_key, @@ -204,6 +205,11 @@ ODK_Message OPK_Pack_GetSignatureHashAlgorithm_Request( void OPK_Unpack_GetSignatureHashAlgorithm_Response( ODK_Message* msg, OEMCryptoResult* result, OEMCrypto_SignatureHashAlgorithm** hash_algorithm); +ODK_Message OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Request( + const WTPI_AsymmetricKey_Handle* key_handle); +void OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Response( + ODK_Message* msg, OEMCryptoResult* result, + WTPI_AsymmetricKey_Handle** key_handle); ODK_Message OPK_Pack_GetBootCertificateChain_Request(const uint8_t* out, const size_t* out_length); void OPK_Unpack_GetBootCertificateChain_Response(ODK_Message* msg, @@ -216,7 +222,8 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Response(ODK_Message* msg, OEMCryptoResult* result, size_t** out_length); ODK_Message OPK_Pack_GenerateRandomCertificateKeyPair_Request( - const AsymmetricKeyType* key_type, const uint8_t* wrapped_private_key, + CertSignatureType cert_type, const AsymmetricKeyType* key_type, + const uint8_t* wrapped_private_key, const size_t* wrapped_private_key_length, const uint8_t* public_key, const size_t* public_key_length); void OPK_Unpack_GenerateRandomCertificateKeyPair_Response( diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c index 98a254a..6f7ccb1 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c @@ -588,6 +588,8 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, { size_t input_length; OPK_Init_size_t((size_t*)&input_length); + uint32_t context; + OPK_Init_uint32_t((uint32_t*)&context); uint8_t* input; OPK_InitPointer((uint8_t**)&input); AsymmetricKeyType key_type; @@ -597,14 +599,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, uint32_t* allowed_schemes; OPK_InitPointer((uint8_t**)&allowed_schemes); OPK_Unpack_UnwrapIntoAsymmetricKeyHandle_Request( - request, &input, &input_length, &key_type, &key_handle, + request, &context, &input, &input_length, &key_type, &key_handle, &allowed_schemes); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; OEMCryptoResult result; OPK_Init_uint32_t((uint32_t*)&result); LOGD("UnwrapIntoAsymmetricKeyHandle"); - result = WTPI_UnwrapIntoAsymmetricKeyHandle(input, input_length, key_type, - key_handle, allowed_schemes); + result = WTPI_UnwrapIntoAsymmetricKeyHandle( + context, input, input_length, key_type, key_handle, allowed_schemes); *response = OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Response( result, key_handle, allowed_schemes); break; @@ -649,20 +651,22 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Init_size_t((size_t*)&output_length); size_t clear_key_length; OPK_Init_size_t((size_t*)&clear_key_length); + uint32_t context; + OPK_Init_uint32_t((uint32_t*)&context); uint8_t* output; OPK_InitPointer((uint8_t**)&output); AsymmetricKeyType key_type; OPK_Init_AsymmetricKeyType((AsymmetricKeyType*)&key_type); uint8_t* clear_key; OPK_InitPointer((uint8_t**)&clear_key); - OPK_Unpack_WrapAsymmetricKey_Request(request, &output, &output_length, - &key_type, &clear_key, - &clear_key_length); + OPK_Unpack_WrapAsymmetricKey_Request(request, &context, &output, + &output_length, &key_type, + &clear_key, &clear_key_length); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; OEMCryptoResult result; OPK_Init_uint32_t((uint32_t*)&result); LOGD("WrapAsymmetricKey"); - result = WTPI_WrapAsymmetricKey(output, output_length, key_type, + result = WTPI_WrapAsymmetricKey(context, output, output_length, key_type, clear_key, clear_key_length); *response = OPK_Pack_WrapAsymmetricKey_Response(result, output, output_length); @@ -800,7 +804,22 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetSignatureHashAlgorithm_Response(result, hash_algorithm); break; } - case 10034: /* WTPI_GetBootCertificateChain */ + case 10034: /* WTPI_CreateAsymmetricKeyHandleFromOEMKey */ + { + WTPI_AsymmetricKey_Handle* key_handle; + OPK_InitPointer((uint8_t**)&key_handle); + OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Request(request, + &key_handle); + if (!ODK_Message_IsValid(request)) goto handle_invalid_request; + OEMCryptoResult result; + OPK_Init_uint32_t((uint32_t*)&result); + LOGD("CreateAsymmetricKeyHandleFromOEMKey"); + result = WTPI_CreateAsymmetricKeyHandleFromOEMKey(key_handle); + *response = OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Response( + result, key_handle); + break; + } + case 10035: /* WTPI_GetBootCertificateChain */ { size_t* out_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(out_length); @@ -816,7 +835,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetBootCertificateChain_Response(result, out, out_length); break; } - case 10035: /* WTPI_GetMaxBootCertificateChainSize */ + case 10036: /* WTPI_GetMaxBootCertificateChainSize */ { size_t* out_length; OPK_InitPointer((uint8_t**)&out_length); @@ -830,13 +849,15 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetMaxBootCertificateChainSize_Response(result, out_length); break; } - case 10036: /* WTPI_GenerateRandomCertificateKeyPair */ + case 10037: /* WTPI_GenerateRandomCertificateKeyPair */ { size_t* wrapped_private_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(wrapped_private_key_length); size_t* public_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(public_key_length); + CertSignatureType cert_type; + OPK_Init_CertSignatureType((CertSignatureType*)&cert_type); AsymmetricKeyType* key_type; OPK_InitPointer((uint8_t**)&key_type); uint8_t* wrapped_private_key; @@ -844,21 +865,21 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, uint8_t* public_key; OPK_InitPointer((uint8_t**)&public_key); OPK_Unpack_GenerateRandomCertificateKeyPair_Request( - request, &key_type, &wrapped_private_key, &wrapped_private_key_length, - &public_key, &public_key_length); + request, &cert_type, &key_type, &wrapped_private_key, + &wrapped_private_key_length, &public_key, &public_key_length); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; OEMCryptoResult result; OPK_Init_uint32_t((uint32_t*)&result); LOGD("GenerateRandomCertificateKeyPair"); result = WTPI_GenerateRandomCertificateKeyPair( - key_type, wrapped_private_key, wrapped_private_key_length, public_key, - public_key_length); + cert_type, key_type, wrapped_private_key, wrapped_private_key_length, + public_key, public_key_length); *response = OPK_Pack_GenerateRandomCertificateKeyPair_Response( result, key_type, wrapped_private_key, wrapped_private_key_length, public_key, public_key_length); break; } - case 10037: /* WTPI_GetSignedCsrPayload */ + case 10038: /* WTPI_GetSignedCsrPayload */ { size_t challenge_length; OPK_Init_size_t((size_t*)&challenge_length); @@ -888,7 +909,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, result, signed_csr_payload, signed_csr_payload_length); break; } - case 10038: /* WTPI_MaxDeviceInfoSize */ + case 10039: /* WTPI_MaxDeviceInfoSize */ { OPK_Unpack_MaxDeviceInfoSize_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -899,7 +920,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxDeviceInfoSize_Response(result); break; } - case 10039: /* WTPI_GetDeviceInformation */ + case 10040: /* WTPI_GetDeviceInformation */ { size_t* out_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(out_length); @@ -915,7 +936,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetDeviceInformation_Response(result, out, out_length); break; } - case 10040: /* WTPI_BccKeyCoseSign1 */ + case 10041: /* WTPI_BccKeyCoseSign1 */ { size_t message_length; OPK_Init_size_t((size_t*)&message_length); @@ -937,7 +958,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, signature_length); break; } - case 10041: /* WTPI_GetMaxBccKeyCoseSign1Size */ + case 10042: /* WTPI_GetMaxBccKeyCoseSign1Size */ { size_t* out_length; OPK_InitPointer((uint8_t**)&out_length); @@ -951,7 +972,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetMaxBccKeyCoseSign1Size_Response(result, out_length); break; } - case 10042: /* WTPI_GetDeviceFusedStatus */ + case 10043: /* WTPI_GetDeviceFusedStatus */ { bool* is_fused; OPK_InitPointer((uint8_t**)&is_fused); @@ -964,7 +985,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetDeviceFusedStatus_Response(result, is_fused); break; } - case 10043: /* WTPI_Crc32Init */ + case 10044: /* WTPI_Crc32Init */ { uint32_t* initial_hash; OPK_InitPointer((uint8_t**)&initial_hash); @@ -977,7 +998,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Init_Response(result, initial_hash); break; } - case 10044: /* WTPI_Crc32Cont */ + case 10045: /* WTPI_Crc32Cont */ { size_t in_length; OPK_Init_size_t((size_t*)&in_length); @@ -997,7 +1018,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Cont_Response(result, new_crc); break; } - case 10045: /* WTPI_Crc32Cont_OutputBuffer */ + case 10046: /* WTPI_Crc32Cont_OutputBuffer */ { size_t in_length; OPK_Init_size_t((size_t*)&in_length); @@ -1020,7 +1041,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Cont_OutputBuffer_Response(result, new_crc); break; } - case 10046: /* WTPI_GetTrustedTime */ + case 10047: /* WTPI_GetTrustedTime */ { uint64_t* time_in_s; OPK_InitPointer((uint8_t**)&time_in_s); @@ -1033,7 +1054,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetTrustedTime_Response(result, time_in_s); break; } - case 10047: /* WTPI_InitializeClock */ + case 10048: /* WTPI_InitializeClock */ { OPK_Unpack_InitializeClock_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1044,7 +1065,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_InitializeClock_Response(result); break; } - case 10048: /* WTPI_TerminateClock */ + case 10049: /* WTPI_TerminateClock */ { OPK_Unpack_TerminateClock_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1055,7 +1076,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_TerminateClock_Response(result); break; } - case 10049: /* WTPI_GetClockType */ + case 10050: /* WTPI_GetClockType */ { OPK_Unpack_GetClockType_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1067,7 +1088,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetClockType_Response(result); break; } - case 10050: /* WTPI_GetSecurityLevel */ + case 10051: /* WTPI_GetSecurityLevel */ { OPK_Unpack_GetSecurityLevel_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1078,7 +1099,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetSecurityLevel_Response(result); break; } - case 10051: /* WTPI_GetProvisioningMethod */ + case 10052: /* WTPI_GetProvisioningMethod */ { OPK_Unpack_GetProvisioningMethod_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1090,7 +1111,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetProvisioningMethod_Response(result); break; } - case 10052: /* WTPI_GetResourceRatingTier */ + case 10053: /* WTPI_GetResourceRatingTier */ { OPK_Unpack_GetResourceRatingTier_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1101,7 +1122,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetResourceRatingTier_Response(result); break; } - case 10053: /* WTPI_IsTAAntiRollbackEnabled */ + case 10054: /* WTPI_IsTAAntiRollbackEnabled */ { OPK_Unpack_IsTAAntiRollbackEnabled_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1112,7 +1133,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsTAAntiRollbackEnabled_Response(result); break; } - case 10054: /* WTPI_IsProductionReady */ + case 10055: /* WTPI_IsProductionReady */ { OPK_Unpack_IsProductionReady_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1123,7 +1144,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsProductionReady_Response(result); break; } - case 10055: /* WTPI_GetWatermarkingSupport */ + case 10056: /* WTPI_GetWatermarkingSupport */ { OPK_Unpack_GetWatermarkingSupport_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1135,7 +1156,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetWatermarkingSupport_Response(result); break; } - case 10056: /* WTPI_GetCurrentSRMVersion */ + case 10057: /* WTPI_GetCurrentSRMVersion */ { uint32_t* srm_version; OPK_InitPointer((uint8_t**)&srm_version); @@ -1148,7 +1169,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetCurrentSRMVersion_Response(result, srm_version); break; } - case 10057: /* WTPI_IsAntiRollbackHWPresent */ + case 10058: /* WTPI_IsAntiRollbackHWPresent */ { OPK_Unpack_IsAntiRollbackHWPresent_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1159,7 +1180,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsAntiRollbackHWPresent_Response(result); break; } - case 10058: /* WTPI_IsCGMS_AActive */ + case 10059: /* WTPI_IsCGMS_AActive */ { OPK_Unpack_IsCGMS_AActive_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1170,7 +1191,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsCGMS_AActive_Response(result); break; } - case 10059: /* WTPI_SupportsCGMS_A */ + case 10060: /* WTPI_SupportsCGMS_A */ { OPK_Unpack_SupportsCGMS_A_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1181,7 +1202,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_SupportsCGMS_A_Response(result); break; } - case 10060: /* WTPI_HasAnalogDisplay */ + case 10061: /* WTPI_HasAnalogDisplay */ { OPK_Unpack_HasAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1192,7 +1213,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_HasAnalogDisplay_Response(result); break; } - case 10061: /* WTPI_IsAnalogDisplayActive */ + case 10062: /* WTPI_IsAnalogDisplayActive */ { OPK_Unpack_IsAnalogDisplayActive_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1203,7 +1224,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsAnalogDisplayActive_Response(result); break; } - case 10062: /* WTPI_CanDisableAnalogDisplay */ + case 10063: /* WTPI_CanDisableAnalogDisplay */ { OPK_Unpack_CanDisableAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1214,7 +1235,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_CanDisableAnalogDisplay_Response(result); break; } - case 10063: /* WTPI_DisableAnalogDisplay */ + case 10064: /* WTPI_DisableAnalogDisplay */ { OPK_Unpack_DisableAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1225,7 +1246,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_DisableAnalogDisplay_Response(result); break; } - case 10064: /* WTPI_MaxOutputSizeForDecrypt */ + case 10065: /* WTPI_MaxOutputSizeForDecrypt */ { OPK_Unpack_MaxOutputSizeForDecrypt_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1236,7 +1257,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxOutputSizeForDecrypt_Response(result); break; } - case 10065: /* WTPI_IsClosedPlatform */ + case 10066: /* WTPI_IsClosedPlatform */ { OPK_Unpack_IsClosedPlatform_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1247,7 +1268,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsClosedPlatform_Response(result); break; } - case 10066: /* WTPI_CurrentHDCPCapability */ + case 10067: /* WTPI_CurrentHDCPCapability */ { OPK_Unpack_CurrentHDCPCapability_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1258,7 +1279,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_CurrentHDCPCapability_Response(result); break; } - case 10067: /* WTPI_MaxHDCPCapability */ + case 10068: /* WTPI_MaxHDCPCapability */ { OPK_Unpack_MaxHDCPCapability_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1269,7 +1290,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxHDCPCapability_Response(result); break; } - case 10068: /* WTPI_MaxBufferSizeForGenericCrypto */ + case 10069: /* WTPI_MaxBufferSizeForGenericCrypto */ { OPK_Unpack_MaxBufferSizeForGenericCrypto_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1280,7 +1301,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxBufferSizeForGenericCrypto_Response(result); break; } - case 10069: /* WTPI_MaxSampleSize */ + case 10070: /* WTPI_MaxSampleSize */ { OPK_Unpack_MaxSampleSize_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1291,7 +1312,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxSampleSize_Response(result); break; } - case 10070: /* WTPI_SupportedCertificates */ + case 10071: /* WTPI_SupportedCertificates */ { OPK_Unpack_SupportedCertificates_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1302,7 +1323,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_SupportedCertificates_Response(result); break; } - case 10071: /* WTPI_ContentDecryptBypassesTA */ + case 10072: /* WTPI_ContentDecryptBypassesTA */ { OPK_Unpack_ContentDecryptBypassesTA_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1313,7 +1334,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_ContentDecryptBypassesTA_Response(result); break; } - case 10072: /* WTPI_GetEncryptAndSignSize */ + case 10073: /* WTPI_GetEncryptAndSignSize */ { uint32_t context; OPK_Init_uint32_t((uint32_t*)&context); @@ -1332,7 +1353,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetEncryptAndSignSize_Response(result, wrapped_length); break; } - case 10073: /* WTPI_EncryptAndSign */ + case 10074: /* WTPI_EncryptAndSign */ { size_t data_length; OPK_Init_size_t((size_t*)&data_length); @@ -1354,7 +1375,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_EncryptAndSign_Response(result, out, out_length); break; } - case 10074: /* WTPI_VerifyAndDecrypt */ + case 10075: /* WTPI_VerifyAndDecrypt */ { size_t wrapped_length; OPK_Init_size_t((size_t*)&wrapped_length); @@ -1377,7 +1398,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_VerifyAndDecrypt_Response(result, out, out_length); break; } - case 10075: /* WTPI_VerifyAndDecryptUsageData_Legacy */ + case 10076: /* WTPI_VerifyAndDecryptUsageData_Legacy */ { size_t wrapped_length; OPK_Init_size_t((size_t*)&wrapped_length); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.c index de44ab9..3caf4f5 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.c @@ -638,7 +638,7 @@ ODK_Message OPK_Pack_CreateAsymmetricKeyHandle_Response( } void OPK_Unpack_UnwrapIntoAsymmetricKeyHandle_Request( - ODK_Message* msg, uint8_t** input, size_t* input_length, + ODK_Message* msg, uint32_t* context, uint8_t** input, size_t* input_length, AsymmetricKeyType* key_type, WTPI_AsymmetricKey_Handle** key_handle, uint32_t** allowed_schemes) { uint32_t api_value = UINT32_MAX; @@ -648,6 +648,7 @@ void OPK_Unpack_UnwrapIntoAsymmetricKeyHandle_Request( uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); OPK_Unpack_size_t(msg, input_length); + OPK_Unpack_uint32_t(msg, context); OPK_UnpackInPlace(msg, (uint8_t**)input, OPK_FromSizeTPtr(input_length)); OPK_Unpack_AsymmetricKeyType(msg, key_type); *key_handle = (WTPI_AsymmetricKey_Handle*)OPK_UnpackAlloc( @@ -722,7 +723,8 @@ ODK_Message OPK_Pack_GetWrappedAsymmetricKeySize_Response( return msg; } -void OPK_Unpack_WrapAsymmetricKey_Request(ODK_Message* msg, uint8_t** output, +void OPK_Unpack_WrapAsymmetricKey_Request(ODK_Message* msg, uint32_t* context, + uint8_t** output, size_t* output_length, AsymmetricKeyType* key_type, uint8_t** clear_key, @@ -735,6 +737,7 @@ void OPK_Unpack_WrapAsymmetricKey_Request(ODK_Message* msg, uint8_t** output, OPK_Unpack_uint64_t(msg, ×tamp); OPK_Unpack_size_t(msg, output_length); OPK_Unpack_size_t(msg, clear_key_length); + OPK_Unpack_uint32_t(msg, context); *output = (uint8_t*)OPK_UnpackAllocBuffer( msg, OPK_FromSizeTPtr(output_length), sizeof(uint8_t)); OPK_Unpack_AsymmetricKeyType(msg, key_type); @@ -972,11 +975,37 @@ ODK_Message OPK_Pack_GetSignatureHashAlgorithm_Response( return msg; } +void OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Request( + ODK_Message* msg, WTPI_AsymmetricKey_Handle** key_handle) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 10034) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + uint64_t timestamp; + OPK_Unpack_uint64_t(msg, ×tamp); + *key_handle = (WTPI_AsymmetricKey_Handle*)OPK_UnpackAlloc( + msg, sizeof(WTPI_AsymmetricKey_Handle)); + OPK_UnpackEOM(msg); + OPK_SharedBuffer_FinalizeUnpacking(); +} + +ODK_Message OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Response( + OEMCryptoResult result, const WTPI_AsymmetricKey_Handle* key_handle) { + uint32_t api_value = 10034; /* from _tee10034 */ + ODK_Message msg = TOS_Transport_GetResponse(); + OPK_Pack_uint32_t(&msg, &api_value); + OPK_Pack_uint32_t(&msg, &result); + OPK_PackNullable_WTPI_AsymmetricKey_Handle(&msg, key_handle); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + void OPK_Unpack_GetBootCertificateChain_Request(ODK_Message* msg, uint8_t** out, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10034) + if (api_value != 10035) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -989,7 +1018,7 @@ void OPK_Unpack_GetBootCertificateChain_Request(ODK_Message* msg, uint8_t** out, ODK_Message OPK_Pack_GetBootCertificateChain_Response( OEMCryptoResult result, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10034; /* from _tee10034 */ + uint32_t api_value = 10035; /* from _tee10035 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -1006,7 +1035,7 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Request(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10035) + if (api_value != 10036) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1017,7 +1046,7 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBootCertificateChainSize_Response( OEMCryptoResult result, const size_t* out_length) { - uint32_t api_value = 10035; /* from _tee10035 */ + uint32_t api_value = 10036; /* from _tee10036 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1028,17 +1057,19 @@ ODK_Message OPK_Pack_GetMaxBootCertificateChainSize_Response( } void OPK_Unpack_GenerateRandomCertificateKeyPair_Request( - ODK_Message* msg, AsymmetricKeyType** key_type, - uint8_t** wrapped_private_key, size_t** wrapped_private_key_length, - uint8_t** public_key, size_t** public_key_length) { + ODK_Message* msg, CertSignatureType* cert_type, + AsymmetricKeyType** key_type, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length, uint8_t** public_key, + size_t** public_key_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10036) + if (api_value != 10037) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); OPK_UnpackNullable_size_t(msg, wrapped_private_key_length); OPK_UnpackNullable_size_t(msg, public_key_length); + OPK_Unpack_CertSignatureType(msg, cert_type); *key_type = (AsymmetricKeyType*)OPK_UnpackAlloc(msg, sizeof(AsymmetricKeyType)); *wrapped_private_key = (uint8_t*)OPK_UnpackAllocBuffer( @@ -1054,7 +1085,7 @@ ODK_Message OPK_Pack_GenerateRandomCertificateKeyPair_Response( const uint8_t* wrapped_private_key, const size_t* wrapped_private_key_length, const uint8_t* public_key, const size_t* public_key_length) { - uint32_t api_value = 10036; /* from _tee10036 */ + uint32_t api_value = 10037; /* from _tee10037 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, wrapped_private_key_length); @@ -1080,7 +1111,7 @@ void OPK_Unpack_GetSignedCsrPayload_Request( uint8_t** signed_csr_payload, size_t** signed_csr_payload_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10037) + if (api_value != 10038) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1100,7 +1131,7 @@ void OPK_Unpack_GetSignedCsrPayload_Request( ODK_Message OPK_Pack_GetSignedCsrPayload_Response( OEMCryptoResult result, const uint8_t* signed_csr_payload, const size_t* signed_csr_payload_length) { - uint32_t api_value = 10037; /* from _tee10037 */ + uint32_t api_value = 10038; /* from _tee10038 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, signed_csr_payload_length); @@ -1117,7 +1148,7 @@ ODK_Message OPK_Pack_GetSignedCsrPayload_Response( void OPK_Unpack_MaxDeviceInfoSize_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10038) + if (api_value != 10039) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1126,7 +1157,7 @@ void OPK_Unpack_MaxDeviceInfoSize_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxDeviceInfoSize_Response(size_t result) { - uint32_t api_value = 10038; /* from _tee10038 */ + uint32_t api_value = 10039; /* from _tee10039 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1139,7 +1170,7 @@ void OPK_Unpack_GetDeviceInformation_Request(ODK_Message* msg, uint8_t** out, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10039) + if (api_value != 10040) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1153,7 +1184,7 @@ void OPK_Unpack_GetDeviceInformation_Request(ODK_Message* msg, uint8_t** out, ODK_Message OPK_Pack_GetDeviceInformation_Response(OEMCryptoResult result, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10039; /* from _tee10039 */ + uint32_t api_value = 10040; /* from _tee10040 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -1172,7 +1203,7 @@ void OPK_Unpack_BccKeyCoseSign1_Request(ODK_Message* msg, uint8_t** message, size_t** signature_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10040) + if (api_value != 10041) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1188,7 +1219,7 @@ void OPK_Unpack_BccKeyCoseSign1_Request(ODK_Message* msg, uint8_t** message, ODK_Message OPK_Pack_BccKeyCoseSign1_Response(OEMCryptoResult result, const uint8_t* signature, const size_t* signature_length) { - uint32_t api_value = 10040; /* from _tee10040 */ + uint32_t api_value = 10041; /* from _tee10041 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, signature_length); @@ -1206,7 +1237,7 @@ void OPK_Unpack_GetMaxBccKeyCoseSign1Size_Request(ODK_Message* msg, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10041) + if (api_value != 10042) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1217,7 +1248,7 @@ void OPK_Unpack_GetMaxBccKeyCoseSign1Size_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBccKeyCoseSign1Size_Response( OEMCryptoResult result, const size_t* out_length) { - uint32_t api_value = 10041; /* from _tee10041 */ + uint32_t api_value = 10042; /* from _tee10042 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1231,7 +1262,7 @@ void OPK_Unpack_GetDeviceFusedStatus_Request(ODK_Message* msg, bool** is_fused) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10042) + if (api_value != 10043) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1242,7 +1273,7 @@ void OPK_Unpack_GetDeviceFusedStatus_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetDeviceFusedStatus_Response(OEMCryptoResult result, const bool* is_fused) { - uint32_t api_value = 10042; /* from _tee10042 */ + uint32_t api_value = 10043; /* from _tee10043 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1255,7 +1286,7 @@ ODK_Message OPK_Pack_GetDeviceFusedStatus_Response(OEMCryptoResult result, void OPK_Unpack_Crc32Init_Request(ODK_Message* msg, uint32_t** initial_hash) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10043) + if (api_value != 10044) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1266,7 +1297,7 @@ void OPK_Unpack_Crc32Init_Request(ODK_Message* msg, uint32_t** initial_hash) { ODK_Message OPK_Pack_Crc32Init_Response(OEMCryptoResult result, const uint32_t* initial_hash) { - uint32_t api_value = 10043; /* from _tee10043 */ + uint32_t api_value = 10044; /* from _tee10044 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1281,7 +1312,7 @@ void OPK_Unpack_Crc32Cont_Request(ODK_Message* msg, uint8_t** in, uint32_t** new_crc) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10044) + if (api_value != 10045) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1295,7 +1326,7 @@ void OPK_Unpack_Crc32Cont_Request(ODK_Message* msg, uint8_t** in, ODK_Message OPK_Pack_Crc32Cont_Response(OEMCryptoResult result, const uint32_t* new_crc) { - uint32_t api_value = 10044; /* from _tee10044 */ + uint32_t api_value = 10045; /* from _tee10045 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1310,7 +1341,7 @@ void OPK_Unpack_Crc32Cont_OutputBuffer_Request( size_t* in_length, uint32_t* prev_crc, uint32_t** new_crc) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10045) + if (api_value != 10046) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1351,7 +1382,7 @@ void OPK_Unpack_Crc32Cont_OutputBuffer_Request( ODK_Message OPK_Pack_Crc32Cont_OutputBuffer_Response(OEMCryptoResult result, const uint32_t* new_crc) { - uint32_t api_value = 10045; /* from _tee10045 */ + uint32_t api_value = 10046; /* from _tee10046 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1364,7 +1395,7 @@ ODK_Message OPK_Pack_Crc32Cont_OutputBuffer_Response(OEMCryptoResult result, void OPK_Unpack_GetTrustedTime_Request(ODK_Message* msg, uint64_t** time_in_s) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10046) + if (api_value != 10047) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1375,7 +1406,7 @@ void OPK_Unpack_GetTrustedTime_Request(ODK_Message* msg, uint64_t** time_in_s) { ODK_Message OPK_Pack_GetTrustedTime_Response(OEMCryptoResult result, const uint64_t* time_in_s) { - uint32_t api_value = 10046; /* from _tee10046 */ + uint32_t api_value = 10047; /* from _tee10047 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1388,7 +1419,7 @@ ODK_Message OPK_Pack_GetTrustedTime_Response(OEMCryptoResult result, void OPK_Unpack_InitializeClock_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10047) + if (api_value != 10048) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1397,7 +1428,7 @@ void OPK_Unpack_InitializeClock_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_InitializeClock_Response(OEMCryptoResult result) { - uint32_t api_value = 10047; /* from _tee10047 */ + uint32_t api_value = 10048; /* from _tee10048 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1409,7 +1440,7 @@ ODK_Message OPK_Pack_InitializeClock_Response(OEMCryptoResult result) { void OPK_Unpack_TerminateClock_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10048) + if (api_value != 10049) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1418,7 +1449,7 @@ void OPK_Unpack_TerminateClock_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_TerminateClock_Response(OEMCryptoResult result) { - uint32_t api_value = 10048; /* from _tee10048 */ + uint32_t api_value = 10049; /* from _tee10049 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1430,7 +1461,7 @@ ODK_Message OPK_Pack_TerminateClock_Response(OEMCryptoResult result) { void OPK_Unpack_GetClockType_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10049) + if (api_value != 10050) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1440,7 +1471,7 @@ void OPK_Unpack_GetClockType_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetClockType_Response( OEMCrypto_Clock_Security_Level result) { - uint32_t api_value = 10049; /* from _tee10049 */ + uint32_t api_value = 10050; /* from _tee10050 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_Clock_Security_Level(&msg, &result); @@ -1452,7 +1483,7 @@ ODK_Message OPK_Pack_GetClockType_Response( void OPK_Unpack_GetSecurityLevel_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10050) + if (api_value != 10051) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1462,7 +1493,7 @@ void OPK_Unpack_GetSecurityLevel_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetSecurityLevel_Response( OEMCrypto_Security_Level result) { - uint32_t api_value = 10050; /* from _tee10050 */ + uint32_t api_value = 10051; /* from _tee10051 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_Security_Level(&msg, &result); @@ -1474,7 +1505,7 @@ ODK_Message OPK_Pack_GetSecurityLevel_Response( void OPK_Unpack_GetProvisioningMethod_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10051) + if (api_value != 10052) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1484,7 +1515,7 @@ void OPK_Unpack_GetProvisioningMethod_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetProvisioningMethod_Response( OEMCrypto_ProvisioningMethod result) { - uint32_t api_value = 10051; /* from _tee10051 */ + uint32_t api_value = 10052; /* from _tee10052 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_ProvisioningMethod(&msg, &result); @@ -1496,7 +1527,7 @@ ODK_Message OPK_Pack_GetProvisioningMethod_Response( void OPK_Unpack_GetResourceRatingTier_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10052) + if (api_value != 10053) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1505,7 +1536,7 @@ void OPK_Unpack_GetResourceRatingTier_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_GetResourceRatingTier_Response(uint32_t result) { - uint32_t api_value = 10052; /* from _tee10052 */ + uint32_t api_value = 10053; /* from _tee10053 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1517,7 +1548,7 @@ ODK_Message OPK_Pack_GetResourceRatingTier_Response(uint32_t result) { void OPK_Unpack_IsTAAntiRollbackEnabled_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10053) + if (api_value != 10054) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1527,7 +1558,7 @@ void OPK_Unpack_IsTAAntiRollbackEnabled_Request(ODK_Message* msg) { ODK_Message OPK_Pack_IsTAAntiRollbackEnabled_Response( OPK_FeatureStatus result) { - uint32_t api_value = 10053; /* from _tee10053 */ + uint32_t api_value = 10054; /* from _tee10054 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1539,7 +1570,7 @@ ODK_Message OPK_Pack_IsTAAntiRollbackEnabled_Response( void OPK_Unpack_IsProductionReady_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10054) + if (api_value != 10055) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1548,7 +1579,7 @@ void OPK_Unpack_IsProductionReady_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsProductionReady_Response(bool result) { - uint32_t api_value = 10054; /* from _tee10054 */ + uint32_t api_value = 10055; /* from _tee10055 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1560,7 +1591,7 @@ ODK_Message OPK_Pack_IsProductionReady_Response(bool result) { void OPK_Unpack_GetWatermarkingSupport_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10055) + if (api_value != 10056) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1570,7 +1601,7 @@ void OPK_Unpack_GetWatermarkingSupport_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetWatermarkingSupport_Response( OEMCrypto_WatermarkingSupport result) { - uint32_t api_value = 10055; /* from _tee10055 */ + uint32_t api_value = 10056; /* from _tee10056 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_WatermarkingSupport(&msg, &result); @@ -1583,7 +1614,7 @@ void OPK_Unpack_GetCurrentSRMVersion_Request(ODK_Message* msg, uint32_t** srm_version) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10056) + if (api_value != 10057) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1594,7 +1625,7 @@ void OPK_Unpack_GetCurrentSRMVersion_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetCurrentSRMVersion_Response( OEMCryptoResult result, const uint32_t* srm_version) { - uint32_t api_value = 10056; /* from _tee10056 */ + uint32_t api_value = 10057; /* from _tee10057 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1607,7 +1638,7 @@ ODK_Message OPK_Pack_GetCurrentSRMVersion_Response( void OPK_Unpack_IsAntiRollbackHWPresent_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10057) + if (api_value != 10058) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1616,7 +1647,7 @@ void OPK_Unpack_IsAntiRollbackHWPresent_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsAntiRollbackHWPresent_Response(bool result) { - uint32_t api_value = 10057; /* from _tee10057 */ + uint32_t api_value = 10058; /* from _tee10058 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1628,7 +1659,7 @@ ODK_Message OPK_Pack_IsAntiRollbackHWPresent_Response(bool result) { void OPK_Unpack_IsCGMS_AActive_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10058) + if (api_value != 10059) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1637,7 +1668,7 @@ void OPK_Unpack_IsCGMS_AActive_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsCGMS_AActive_Response(bool result) { - uint32_t api_value = 10058; /* from _tee10058 */ + uint32_t api_value = 10059; /* from _tee10059 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1649,7 +1680,7 @@ ODK_Message OPK_Pack_IsCGMS_AActive_Response(bool result) { void OPK_Unpack_SupportsCGMS_A_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10059) + if (api_value != 10060) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1658,7 +1689,7 @@ void OPK_Unpack_SupportsCGMS_A_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_SupportsCGMS_A_Response(bool result) { - uint32_t api_value = 10059; /* from _tee10059 */ + uint32_t api_value = 10060; /* from _tee10060 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1670,7 +1701,7 @@ ODK_Message OPK_Pack_SupportsCGMS_A_Response(bool result) { void OPK_Unpack_HasAnalogDisplay_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10060) + if (api_value != 10061) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1679,7 +1710,7 @@ void OPK_Unpack_HasAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_HasAnalogDisplay_Response(bool result) { - uint32_t api_value = 10060; /* from _tee10060 */ + uint32_t api_value = 10061; /* from _tee10061 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1691,7 +1722,7 @@ ODK_Message OPK_Pack_HasAnalogDisplay_Response(bool result) { void OPK_Unpack_IsAnalogDisplayActive_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10061) + if (api_value != 10062) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1700,7 +1731,7 @@ void OPK_Unpack_IsAnalogDisplayActive_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsAnalogDisplayActive_Response(bool result) { - uint32_t api_value = 10061; /* from _tee10061 */ + uint32_t api_value = 10062; /* from _tee10062 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1712,7 +1743,7 @@ ODK_Message OPK_Pack_IsAnalogDisplayActive_Response(bool result) { void OPK_Unpack_CanDisableAnalogDisplay_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10062) + if (api_value != 10063) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1721,7 +1752,7 @@ void OPK_Unpack_CanDisableAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_CanDisableAnalogDisplay_Response(bool result) { - uint32_t api_value = 10062; /* from _tee10062 */ + uint32_t api_value = 10063; /* from _tee10063 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1733,7 +1764,7 @@ ODK_Message OPK_Pack_CanDisableAnalogDisplay_Response(bool result) { void OPK_Unpack_DisableAnalogDisplay_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10063) + if (api_value != 10064) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1742,7 +1773,7 @@ void OPK_Unpack_DisableAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_DisableAnalogDisplay_Response(bool result) { - uint32_t api_value = 10063; /* from _tee10063 */ + uint32_t api_value = 10064; /* from _tee10064 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1754,7 +1785,7 @@ ODK_Message OPK_Pack_DisableAnalogDisplay_Response(bool result) { void OPK_Unpack_MaxOutputSizeForDecrypt_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10064) + if (api_value != 10065) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1763,7 +1794,7 @@ void OPK_Unpack_MaxOutputSizeForDecrypt_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxOutputSizeForDecrypt_Response(size_t result) { - uint32_t api_value = 10064; /* from _tee10064 */ + uint32_t api_value = 10065; /* from _tee10065 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1775,7 +1806,7 @@ ODK_Message OPK_Pack_MaxOutputSizeForDecrypt_Response(size_t result) { void OPK_Unpack_IsClosedPlatform_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10065) + if (api_value != 10066) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1784,7 +1815,7 @@ void OPK_Unpack_IsClosedPlatform_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsClosedPlatform_Response(bool result) { - uint32_t api_value = 10065; /* from _tee10065 */ + uint32_t api_value = 10066; /* from _tee10066 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1796,7 +1827,7 @@ ODK_Message OPK_Pack_IsClosedPlatform_Response(bool result) { void OPK_Unpack_CurrentHDCPCapability_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10066) + if (api_value != 10067) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1806,7 +1837,7 @@ void OPK_Unpack_CurrentHDCPCapability_Request(ODK_Message* msg) { ODK_Message OPK_Pack_CurrentHDCPCapability_Response( OEMCrypto_HDCP_Capability result) { - uint32_t api_value = 10066; /* from _tee10066 */ + uint32_t api_value = 10067; /* from _tee10067 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_HDCP_Capability(&msg, &result); @@ -1818,7 +1849,7 @@ ODK_Message OPK_Pack_CurrentHDCPCapability_Response( void OPK_Unpack_MaxHDCPCapability_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10067) + if (api_value != 10068) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1828,7 +1859,7 @@ void OPK_Unpack_MaxHDCPCapability_Request(ODK_Message* msg) { ODK_Message OPK_Pack_MaxHDCPCapability_Response( OEMCrypto_HDCP_Capability result) { - uint32_t api_value = 10067; /* from _tee10067 */ + uint32_t api_value = 10068; /* from _tee10068 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_HDCP_Capability(&msg, &result); @@ -1840,7 +1871,7 @@ ODK_Message OPK_Pack_MaxHDCPCapability_Response( void OPK_Unpack_MaxBufferSizeForGenericCrypto_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10068) + if (api_value != 10069) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1849,7 +1880,7 @@ void OPK_Unpack_MaxBufferSizeForGenericCrypto_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxBufferSizeForGenericCrypto_Response(size_t result) { - uint32_t api_value = 10068; /* from _tee10068 */ + uint32_t api_value = 10069; /* from _tee10069 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1861,7 +1892,7 @@ ODK_Message OPK_Pack_MaxBufferSizeForGenericCrypto_Response(size_t result) { void OPK_Unpack_MaxSampleSize_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10069) + if (api_value != 10070) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1870,7 +1901,7 @@ void OPK_Unpack_MaxSampleSize_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxSampleSize_Response(size_t result) { - uint32_t api_value = 10069; /* from _tee10069 */ + uint32_t api_value = 10070; /* from _tee10070 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1882,7 +1913,7 @@ ODK_Message OPK_Pack_MaxSampleSize_Response(size_t result) { void OPK_Unpack_SupportedCertificates_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10070) + if (api_value != 10071) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1891,7 +1922,7 @@ void OPK_Unpack_SupportedCertificates_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_SupportedCertificates_Response(uint32_t result) { - uint32_t api_value = 10070; /* from _tee10070 */ + uint32_t api_value = 10071; /* from _tee10071 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1903,7 +1934,7 @@ ODK_Message OPK_Pack_SupportedCertificates_Response(uint32_t result) { void OPK_Unpack_ContentDecryptBypassesTA_Request(ODK_Message* msg) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10071) + if (api_value != 10072) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1912,7 +1943,7 @@ void OPK_Unpack_ContentDecryptBypassesTA_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_ContentDecryptBypassesTA_Response(bool result) { - uint32_t api_value = 10071; /* from _tee10071 */ + uint32_t api_value = 10072; /* from _tee10072 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1927,7 +1958,7 @@ void OPK_Unpack_GetEncryptAndSignSize_Request(ODK_Message* msg, size_t** wrapped_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10072) + if (api_value != 10073) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1940,7 +1971,7 @@ void OPK_Unpack_GetEncryptAndSignSize_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetEncryptAndSignSize_Response( OEMCryptoResult result, const size_t* wrapped_length) { - uint32_t api_value = 10072; /* from _tee10072 */ + uint32_t api_value = 10073; /* from _tee10073 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1955,7 +1986,7 @@ void OPK_Unpack_EncryptAndSign_Request(ODK_Message* msg, uint32_t* context, uint8_t** out, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10073) + if (api_value != 10074) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1972,7 +2003,7 @@ void OPK_Unpack_EncryptAndSign_Request(ODK_Message* msg, uint32_t* context, ODK_Message OPK_Pack_EncryptAndSign_Response(OEMCryptoResult result, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10073; /* from _tee10073 */ + uint32_t api_value = 10074; /* from _tee10074 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -1991,7 +2022,7 @@ void OPK_Unpack_VerifyAndDecrypt_Request(ODK_Message* msg, uint32_t* context, size_t** out_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10074) + if (api_value != 10075) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -2008,7 +2039,7 @@ void OPK_Unpack_VerifyAndDecrypt_Request(ODK_Message* msg, uint32_t* context, ODK_Message OPK_Pack_VerifyAndDecrypt_Response(OEMCryptoResult result, const uint8_t* out, const size_t* out_length) { - uint32_t api_value = 10074; /* from _tee10074 */ + uint32_t api_value = 10075; /* from _tee10075 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -2026,7 +2057,7 @@ void OPK_Unpack_VerifyAndDecryptUsageData_Legacy_Request( uint8_t** signature, uint8_t** iv, uint8_t** out) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10075) + if (api_value != 10076) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -2041,7 +2072,7 @@ void OPK_Unpack_VerifyAndDecryptUsageData_Legacy_Request( ODK_Message OPK_Pack_VerifyAndDecryptUsageData_Legacy_Response( OEMCryptoResult result, const uint8_t* out) { - uint32_t api_value = 10075; /* from _tee10075 */ + uint32_t api_value = 10076; /* from _tee10076 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.h b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.h index ac7c4f7..ede631c 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_tee_serializer.h @@ -124,7 +124,7 @@ void OPK_Unpack_CreateAsymmetricKeyHandle_Request( ODK_Message OPK_Pack_CreateAsymmetricKeyHandle_Response( OEMCryptoResult result, const WTPI_AsymmetricKey_Handle* key_handle); void OPK_Unpack_UnwrapIntoAsymmetricKeyHandle_Request( - ODK_Message* msg, uint8_t** input, size_t* input_length, + ODK_Message* msg, uint32_t* context, uint8_t** input, size_t* input_length, AsymmetricKeyType* key_type, WTPI_AsymmetricKey_Handle** key_handle, uint32_t** allowed_schemes); ODK_Message OPK_Pack_UnwrapIntoAsymmetricKeyHandle_Response( @@ -138,7 +138,8 @@ void OPK_Unpack_GetWrappedAsymmetricKeySize_Request( AsymmetricKeyType* key_type, size_t** buffer_size); ODK_Message OPK_Pack_GetWrappedAsymmetricKeySize_Response( OEMCryptoResult result, const size_t* buffer_size); -void OPK_Unpack_WrapAsymmetricKey_Request(ODK_Message* msg, uint8_t** output, +void OPK_Unpack_WrapAsymmetricKey_Request(ODK_Message* msg, uint32_t* context, + uint8_t** output, size_t* output_length, AsymmetricKeyType* key_type, uint8_t** clear_key, @@ -189,6 +190,10 @@ void OPK_Unpack_GetSignatureHashAlgorithm_Request( ODK_Message OPK_Pack_GetSignatureHashAlgorithm_Response( OEMCryptoResult result, const OEMCrypto_SignatureHashAlgorithm* hash_algorithm); +void OPK_Unpack_CreateAsymmetricKeyHandleFromOEMKey_Request( + ODK_Message* msg, WTPI_AsymmetricKey_Handle** key_handle); +ODK_Message OPK_Pack_CreateAsymmetricKeyHandleFromOEMKey_Response( + OEMCryptoResult result, const WTPI_AsymmetricKey_Handle* key_handle); void OPK_Unpack_GetBootCertificateChain_Request(ODK_Message* msg, uint8_t** out, size_t** out_length); ODK_Message OPK_Pack_GetBootCertificateChain_Response(OEMCryptoResult result, @@ -199,9 +204,10 @@ void OPK_Unpack_GetMaxBootCertificateChainSize_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBootCertificateChainSize_Response( OEMCryptoResult result, const size_t* out_length); void OPK_Unpack_GenerateRandomCertificateKeyPair_Request( - ODK_Message* msg, AsymmetricKeyType** key_type, - uint8_t** wrapped_private_key, size_t** wrapped_private_key_length, - uint8_t** public_key, size_t** public_key_length); + ODK_Message* msg, CertSignatureType* cert_type, + AsymmetricKeyType** key_type, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length, uint8_t** public_key, + size_t** public_key_length); ODK_Message OPK_Pack_GenerateRandomCertificateKeyPair_Response( OEMCryptoResult result, const AsymmetricKeyType* key_type, const uint8_t* wrapped_private_key, diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.c b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.c index ae66c73..e6e0b7e 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.c @@ -101,6 +101,12 @@ void OPK_Init_OEMCrypto_HDCP_Capability(OEMCrypto_HDCP_Capability* obj) { } } +void OPK_Init_CertSignatureType(CertSignatureType* obj) { + if (obj) { + memset(obj, 0, sizeof(CertSignatureType)); + } +} + void OPK_Unpack_WTPI_K1_SymmetricKey_Handle(ODK_Message* message, WTPI_K1_SymmetricKey_Handle* value); void OPK_Unpack_C1_HMAC_SHA256_Verify_Request(ODK_Message* msg, diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.h b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.h index ea9cf8b..b4dcae4 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/tee_special_cases.h @@ -25,6 +25,7 @@ void OPK_Init_OEMCrypto_Security_Level(OEMCrypto_Security_Level* obj); void OPK_Init_OEMCrypto_ProvisioningMethod(OEMCrypto_ProvisioningMethod* obj); void OPK_Init_OEMCrypto_WatermarkingSupport(OEMCrypto_WatermarkingSupport* obj); void OPK_Init_OEMCrypto_HDCP_Capability(OEMCrypto_HDCP_Capability* obj); +void OPK_Init_CertSignatureType(CertSignatureType* obj); void OPK_Unpack_C1_HMAC_SHA256_Verify_Request(ODK_Message* msg, WTPI_K1_SymmetricKey_Handle* key, diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_common.h b/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_common.h index 6fdd918..8c7a91f 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_common.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_common.h @@ -6,6 +6,11 @@ #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" +#define TEST_RSA_KEY_DER_LEN 1216 +#define HELLO_WORLD_ENC_LEN 256 +extern uint8_t test_rsa_key_der[TEST_RSA_KEY_DER_LEN]; +extern uint8_t hello_world_encrypted[HELLO_WORLD_ENC_LEN]; + using WtpiSymmetricKeyType = std::remove_pointer::type; const auto wtpi_symmetric_key_free = [](WtpiSymmetricKeyType* key) { diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/wtpi_test.gyp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/wtpi_test.gyp index 5f94f5f..27febc0 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/wtpi_test.gyp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/wtpi_test.gyp @@ -57,6 +57,7 @@ 'ssl_util.cpp', 'cose_util.cpp', 'test_rsa_key.cpp', + 'legacy_keywrap_test.cpp', '<(DEPTH)/linux/src/log.cpp', '<(DEPTH)/util/src/string_conversions.cpp', ], diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_useless/wtpi_root_of_trust_layer2.c b/oemcrypto/opk/oemcrypto_ta/wtpi_useless/wtpi_root_of_trust_layer2.c index fb211a3..066156a 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_useless/wtpi_root_of_trust_layer2.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_useless/wtpi_root_of_trust_layer2.c @@ -7,8 +7,11 @@ #include #include +#include "config/default.h" +#include "oemcrypto_compiler_attributes.h" #include "wtpi_config_interface.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" +#include "wtpi_device_key_interface.h" #include "wtpi_logging_interface.h" // In practice, ROT_SIZE is the size of a keybox. @@ -16,6 +19,11 @@ static size_t gBufferSize = 0; static uint8_t gBuffer[MAX_ROT_SIZE]; +static size_t gOEMCertBufferSize = 0; +static uint8_t gOEMCertBuffer[MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE]; +static size_t gOEMPrivateKeyBufferSize = 0; +static uint8_t gOEMPrivateKeyBuffer[MAX_PROV30_OEM_KEY_SIZE]; + OEMCryptoResult WTPI_UnwrapRootOfTrust(const uint8_t* input, size_t input_length, uint8_t* output, size_t* output_length) { @@ -44,3 +52,57 @@ OEMCryptoResult WTPI_LoadRootOfTrust(uint8_t* output, size_t* length) { memcpy(output, gBuffer, gBufferSize); return OEMCrypto_SUCCESS; } + +OEMCryptoResult WTPI_WrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length) { + return WTPI_EncryptAndSign(DEVICE_KEY_WRAP_DRM_CERT, input, input_length, + output, output_length); +} + +OEMCryptoResult WTPI_UnwrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length) { + return WTPI_VerifyAndDecrypt(DEVICE_KEY_WRAP_DRM_CERT, input, input_length, + output, output_length); +} + +OEMCryptoResult WTPI_SaveOEMPrivateKey30(const uint8_t* input, + size_t input_length) { + if (input == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (input_length > MAX_PROV30_OEM_KEY_SIZE) + return OEMCrypto_ERROR_INVALID_CONTEXT; + gOEMPrivateKeyBufferSize = input_length; + memcpy(&gOEMPrivateKeyBuffer, input, input_length); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult WTPI_LoadOEMPrivateKey30(uint8_t* output, + size_t* output_length) { + if (output_length == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (output == NULL || *output_length < gOEMPrivateKeyBufferSize) + return OEMCrypto_ERROR_SHORT_BUFFER; + *output_length = gOEMPrivateKeyBufferSize; + memcpy(output, gOEMPrivateKeyBuffer, gOEMPrivateKeyBufferSize); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult WTPI_SaveOEMPublicCertificate30(const uint8_t* input UNUSED, + size_t input_length UNUSED) { + if (input == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (input_length > MAX_PROV30_OEM_CERT_CHAIN_PKCS7_SIZE) + return OEMCrypto_ERROR_INVALID_CONTEXT; + gOEMCertBufferSize = input_length; + memcpy(&gOEMCertBuffer, input, input_length); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult WTPI_LoadOEMPublicCertificate30(uint8_t* output, + size_t* output_length) { + if (output_length == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (output == NULL || *output_length < gOEMCertBufferSize) + return OEMCrypto_ERROR_SHORT_BUFFER; + *output_length = gOEMCertBufferSize; + memcpy(output, gOEMCertBuffer, gOEMCertBufferSize); + return OEMCrypto_SUCCESS; +} diff --git a/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk b/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk index ea56b37..a24587e 100644 --- a/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk +++ b/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk @@ -29,6 +29,7 @@ wtpi_impl_sources += \ $(wtpi_ref_dir)/wtpi_device_key.c \ $(wtpi_ref_dir)/crypto_util.c \ $(wtpi_ref_dir)/device_key_util.c \ + $(wtpi_ref_dir)/prov30_factory_util.c \ $(wtpi_ref_dir)/rsa_util.c \ $(wtpi_ref_dir)/ecc_util.c \ $(wtpi_ref_dir)/cose_util.c \ diff --git a/oemcrypto/opk/ports/optee/README.md b/oemcrypto/opk/ports/optee/README.md index 9720f26..9f689e1 100644 --- a/oemcrypto/opk/ports/optee/README.md +++ b/oemcrypto/opk/ports/optee/README.md @@ -7,23 +7,27 @@ other targets, be sure to set up the OP-TEE repos with the corresponding manifest (eg to build OPK against an NXP chip target, use the correct NXP manifest when cloning and building OP-TEE). -1. Download and build OP-TEE following their online documentation. Set that - destination to the environment variable OPTEE_DIR. For security purposes, - prefer OP-TEE version 3.20.0 or later since targeted stack protection with - `-fstack-protector-strong` is enabled by default and `__stack_chk_guard` is - initialized to a secure, random value at runtime. On AArch64 targets, build - OP-TEE with `CFG_CORE_BTI=y`, `CFG_CORE_PAUTH=y`, `CFG_TA_BTI=y`, - and `CFG_TA_PAUTH=y` to enable branch protection with - `-mbranch-protection=pac-ret+leaf+bti`. Branch protection requires that the - GCC toolchain is compiled with `--enable-standard-branch-protection`. -2. If the GCC toolchain is separate from the one included in +1. Download and build OP-TEE following their online documentation and these + security considerations: + - Prefer OP-TEE version 3.20.0 or later since targeted stack protection with + `-fstack-protector-strong` is enabled by default and `__stack_chk_guard` is + initialized to a secure, random value at runtime. + - On AArch64 targets, build OP-TEE with `CFG_CORE_BTI=y`, `CFG_CORE_PAUTH=y`, + `CFG_TA_BTI=y`, and `CFG_TA_PAUTH=y` to enable branch protection with + `-mbranch-protection=pac-ret+leaf+bti`. Branch protection requires that the + GCC toolchain is compiled with `--enable-standard-branch-protection`. + - Build OP-TEE with `CFG_WITH_SOFTWARE_PRNG=n` and, if not provided by the + platform, implement `hw_get_random_bytes` to generate random data using a + cryptographically-secure hardware RNG instead of the software PRNG. +2. Set the OP-TEE download destination to the environment variable OPTEE_DIR. +3. If the GCC toolchain is separate from the one included in $OPTEE_DIR/toolchains, set that path to OPTEE_TOOLCHAIN_DIR. -3. Set up the third_party directory with the required dependencies. All of these +4. Set up the third_party directory with the required dependencies. All of these dependencies are for unit tests. Run `oemcrypto/opk/setup.sh` to download all of the required libraries to `$CDM_DIR/third_party`. -4. From the top level of this repo (CDM), run `make -j32 -C +5. From the top level of this repo (CDM), run `make -j32 -C ./oemcrypto/opk/ports/optee host ta` -5. Run on QEMU +6. Run on QEMU: ``` export QEMU=$OPTEE_DIR/qemu/build/arm-softmmu/qemu-system-arm && \ export GTEST_FILTER="-*Reboot*" && \ diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_ecc.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_ecc.c index 18ff0fd..1b86de9 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_ecc.c +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_ecc.c @@ -7,6 +7,7 @@ #include "der_parse.h" #include "oemcrypto_check_macros.h" #include "opk_config.h" +#include "wtpi_device_key_interface.h" #include "wtpi_logging_interface.h" #include "wtpi_provisioning_4_interface.h" @@ -96,9 +97,9 @@ static OEMCryptoResult NewEccKeyPair(uint8_t* private_key_data, } OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( - AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length, uint8_t* public_key, - size_t* public_key_length) { + CertSignatureType cert_type, AsymmetricKeyType* key_type, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, + uint8_t* public_key, size_t* public_key_length) { RETURN_INVALID_CONTEXT_IF_NULL(key_type); RETURN_INVALID_CONTEXT_IF_NULL(wrapped_private_key_length); RETURN_INVALID_CONTEXT_IF_NULL(public_key_length); @@ -148,8 +149,19 @@ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( return OEMCrypto_ERROR_SHORT_BUFFER; } + uint32_t context = 0; + if (cert_type == CERT_SIGNATURE_DRM) { + context = DEVICE_KEY_WRAP_DRM_CERT; + } else if (cert_type == CERT_SIGNATURE_OEM) { + context = DEVICE_KEY_WRAP_OEM_CERT; + } else { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + *wrapped_private_key_length = actual_wrapped_private_key_length; - return WTPI_WrapAsymmetricKey(wrapped_private_key, - *wrapped_private_key_length, *key_type, - clear_private_key, clear_private_key_length); + result = WTPI_WrapAsymmetricKey(context, wrapped_private_key, + *wrapped_private_key_length, *key_type, + clear_private_key, clear_private_key_length); + + return result; } diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_rsa.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_rsa.c index 5f2cf8f..f14e40f 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_rsa.c +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/genkeypair_rsa.c @@ -8,12 +8,13 @@ #include "der_parse.h" #include "oemcrypto_check_macros.h" #include "opk_config.h" +#include "wtpi_device_key_interface.h" #include "wtpi_provisioning_4_interface.h" OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( - AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length, uint8_t* public_key, - size_t* public_key_length) { + CertSignatureType cert_type, AsymmetricKeyType* key_type, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, + uint8_t* public_key, size_t* public_key_length) { RETURN_INVALID_CONTEXT_IF_NULL(key_type); RETURN_INVALID_CONTEXT_IF_NULL(wrapped_private_key_length); RETURN_INVALID_CONTEXT_IF_NULL(public_key_length); @@ -130,7 +131,17 @@ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( } *wrapped_private_key_length = required_size; - return WTPI_WrapAsymmetricKey(wrapped_private_key, - *wrapped_private_key_length, *key_type, - encoded_priv, encoded_priv_len); + uint32_t context = 0; + if (cert_type == CERT_SIGNATURE_DRM) { + context = DEVICE_KEY_WRAP_DRM_CERT; + } else if (cert_type == CERT_SIGNATURE_OEM) { + context = DEVICE_KEY_WRAP_OEM_CERT; + } else { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + result = WTPI_WrapAsymmetricKey(context, wrapped_private_key, + *wrapped_private_key_length, *key_type, + encoded_priv, encoded_priv_len); + return result; } diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_root_of_trust_layer1.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_root_of_trust_layer1.c index 5fc4f0d..fcd1a91 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_root_of_trust_layer1.c +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_root_of_trust_layer1.c @@ -305,3 +305,29 @@ OEMCryptoResult WTPI_K1_CreateKeyHandleFromKeybox( DERIVING_KEY, out); } } + +OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input UNUSED, + size_t input_length UNUSED, + uint8_t* wrapped_cert UNUSED, + size_t* wrapped_cert_length UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert( + const uint8_t* input UNUSED, size_t input_length UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output UNUSED, + size_t* output_length UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_ValidateOEMCertAndKey(void) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( + WTPI_AsymmetricKey_Handle* key_handle UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} diff --git a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_clock_layer2.c b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_clock_layer2.c index a9a7ac4..7ea83fe 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_clock_layer2.c +++ b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_clock_layer2.c @@ -19,12 +19,16 @@ #include #include +#include #include OEMCryptoResult WTPI_GetSecureTimer(uint64_t* time_in_s) { int64_t now; - trusty_gettime(0, &now); + int rc = trusty_gettime(0, &now); + if (rc != NO_ERROR) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } *time_in_s = now / 1000000000ll; return OEMCrypto_SUCCESS; } diff --git a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_provisioning_4.c b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_provisioning_4.c index 4e0703e..1ff61ab 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_provisioning_4.c +++ b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_provisioning_4.c @@ -33,6 +33,7 @@ #include "ecc_util.h" #include "oemcrypto_check_macros.h" #include "wtpi_crypto_asymmetric_interface.h" +#include "wtpi_device_key_interface.h" #include "wtpi_logging_interface.h" #define MAX_DEVICE_INFO_SIZE 768 @@ -71,9 +72,9 @@ OEMCryptoResult WTPI_GetMaxBootCertificateChainSize(size_t* out_length) { } OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( - AsymmetricKeyType* key_type, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length, uint8_t* public_key, - size_t* public_key_length) { + CertSignatureType cert_type, AsymmetricKeyType* key_type, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, + uint8_t* public_key, size_t* public_key_length) { if (key_type == NULL || wrapped_private_key_length == NULL || public_key_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -119,10 +120,21 @@ OEMCryptoResult WTPI_GenerateRandomCertificateKeyPair( return OEMCrypto_ERROR_SHORT_BUFFER; } + uint32_t context = 0; + if (cert_type == CERT_SIGNATURE_DRM) { + context = DEVICE_KEY_WRAP_DRM_CERT; + } else if (cert_type == CERT_SIGNATURE_OEM) { + context = DEVICE_KEY_WRAP_OEM_CERT; + } else { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + *wrapped_private_key_length = actual_wrapped_private_key_length; - return WTPI_WrapAsymmetricKey(wrapped_private_key, - *wrapped_private_key_length, *key_type, - clear_private_key, clear_private_key_length); + result = WTPI_WrapAsymmetricKey(context, wrapped_private_key, + *wrapped_private_key_length, *key_type, + clear_private_key, clear_private_key_length); + + return result; } OEMCryptoResult WTPI_BccKeyCoseSign1(const uint8_t* message, diff --git a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_root_of_trust_layer2.c b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_root_of_trust_layer2.c index fa13341..26cb2a4 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_root_of_trust_layer2.c +++ b/oemcrypto/opk/ports/trusty/ta/reference/interface_impls/wtpi_root_of_trust_layer2.c @@ -34,135 +34,187 @@ static const char* kKeyboxPath = "widevine_keybox"; OEMCryptoResult WTPI_UnwrapRootOfTrust(const uint8_t* input, - size_t input_length, - uint8_t* output, + size_t input_length, uint8_t* output, size_t* output_length) { - TLOGD("WTPI_UnwrapRootOfTrust\n"); + TLOGD("WTPI_UnwrapRootOfTrust\n"); - if (input == NULL || output == NULL || output_length == NULL) { - TLOGE("WTPI_UnwrapRootOfTrust: invalid parameters\n"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } + if (input == NULL || output == NULL || output_length == NULL) { + TLOGE("WTPI_UnwrapRootOfTrust: invalid parameters\n"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } - /* Try to unwrap the keybox. */ - int rc = keybox_unwrap(input, input_length, output, *output_length, - output_length); - if (rc == KEYBOX_STATUS_SUCCESS) { - return OEMCrypto_SUCCESS; - } - - /* If unwrapping failed, assume the keybox is cleartext. */ - TLOGW("WTPI_UnwrapRootOfTrust: decryption failed (%d), assuming cleartext\n", - rc); - - /* The output buffer needs to be at least the size of the input buffer. */ - size_t min_output_length = input_length; - if (min_output_length > *output_length) { - *output_length = min_output_length; - TLOGE("WTPI_UnwrapRootOfTrust: output buffer too short, should be at least %zu bytes\n", - min_output_length); - return OEMCrypto_ERROR_SHORT_BUFFER; - } - - *output_length = min_output_length; - memcpy(output, input, *output_length); + /* Try to unwrap the keybox. */ + int rc = + keybox_unwrap(input, input_length, output, *output_length, output_length); + if (rc == KEYBOX_STATUS_SUCCESS) { return OEMCrypto_SUCCESS; + } + + /* If unwrapping failed, assume the keybox is cleartext. */ + TLOGW("WTPI_UnwrapRootOfTrust: decryption failed (%d), assuming cleartext\n", + rc); + + /* The output buffer needs to be at least the size of the input buffer. */ + size_t min_output_length = input_length; + if (min_output_length > *output_length) { + *output_length = min_output_length; + TLOGE( + "WTPI_UnwrapRootOfTrust: output buffer too short, should be at least " + "%zu bytes\n", + min_output_length); + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + *output_length = min_output_length; + memcpy(output, input, *output_length); + return OEMCrypto_SUCCESS; } OEMCryptoResult WTPI_SaveRootOfTrust(const uint8_t* keybox, size_t length) { - TLOGD("WTPI_SaveRootOfTrust\n"); - tee_context* ctx = get_tee_context(); - assert(ctx->new_provisioning_session != STORAGE_INVALID_SESSION); + TLOGD("WTPI_SaveRootOfTrust\n"); + tee_context* ctx = get_tee_context(); + assert(ctx->new_provisioning_session != STORAGE_INVALID_SESSION); - if (!system_state_provisioning_allowed()) { - TLOGE("provisioning not allowed\n"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } + if (!system_state_provisioning_allowed()) { + TLOGE("provisioning not allowed\n"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } - if (keybox == NULL) { - TLOGE("WTPI_SaveRootOfTrust: no keybox provided\n"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } + if (keybox == NULL) { + TLOGE("WTPI_SaveRootOfTrust: no keybox provided\n"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } - file_handle_t handle; - int rc = storage_open_file( - ctx->new_provisioning_session, &handle, kKeyboxPath, - STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE, 0); - if (rc < 0) { - TLOGE("WTPI_SaveRootOfTrust: failed to create keybox: %d\n", rc); - return OEMCrypto_ERROR_OPEN_FAILURE; - } - rc = storage_write(handle, 0, keybox, length, STORAGE_OP_COMPLETE); - storage_close_file(handle); - if (rc < 0) { - TLOGE("WTPI_SaveRootOfTrust: failed to write keybox: %d\n", rc); - return OEMCrypto_ERROR_CLOSE_FAILURE; - } + file_handle_t handle; + int rc = storage_open_file( + ctx->new_provisioning_session, &handle, kKeyboxPath, + STORAGE_FILE_OPEN_CREATE | STORAGE_FILE_OPEN_TRUNCATE, 0); + if (rc < 0) { + TLOGE("WTPI_SaveRootOfTrust: failed to create keybox: %d\n", rc); + return OEMCrypto_ERROR_OPEN_FAILURE; + } + rc = storage_write(handle, 0, keybox, length, STORAGE_OP_COMPLETE); + storage_close_file(handle); + if (rc < 0) { + TLOGE("WTPI_SaveRootOfTrust: failed to write keybox: %d\n", rc); + return OEMCrypto_ERROR_CLOSE_FAILURE; + } - return OEMCrypto_SUCCESS; + return OEMCrypto_SUCCESS; } OEMCryptoResult WTPI_LoadRootOfTrust(uint8_t* keybox, size_t* length) { - TLOGD("WTPI_LoadRootOfTrust\n"); - tee_context* ctx = get_tee_context(); - assert(ctx->new_provisioning_session != STORAGE_INVALID_SESSION); + TLOGD("WTPI_LoadRootOfTrust\n"); + tee_context* ctx = get_tee_context(); + assert(ctx->new_provisioning_session != STORAGE_INVALID_SESSION); - if (keybox == NULL || length == NULL) { - TLOGE("WTPI_LoadRootOfTrust: invalid parameters\n"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } + if (keybox == NULL || length == NULL) { + TLOGE("WTPI_LoadRootOfTrust: invalid parameters\n"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } - file_handle_t handle; - int rc = storage_open_file(ctx->new_provisioning_session, &handle, - kKeyboxPath, 0, 0); - bool loading_from_backup = false; + file_handle_t handle; + int rc = storage_open_file(ctx->new_provisioning_session, &handle, + kKeyboxPath, 0, 0); + bool loading_from_backup = false; + if (rc < 0) { + TLOGE( + "WTPI_LoadRootOfTrust: error opening keybox on TP. Attempting TDP.\n"); + assert(ctx->old_provisioning_session != STORAGE_INVALID_SESSION); + rc = storage_open_file(ctx->old_provisioning_session, &handle, kKeyboxPath, + 0, 0); if (rc < 0) { - TLOGE("WTPI_LoadRootOfTrust: error opening keybox on TP. Attempting TDP.\n"); - assert(ctx->old_provisioning_session != STORAGE_INVALID_SESSION); - rc = storage_open_file(ctx->old_provisioning_session, &handle, - kKeyboxPath, 0, 0); - if (rc < 0) { - TLOGE("WTPI_LoadRootOfTrust: error opening keybox: %d\n", rc); - return OEMCrypto_ERROR_OPEN_FAILURE; - } - - loading_from_backup = true; + TLOGE("WTPI_LoadRootOfTrust: error opening keybox: %d\n", rc); + return OEMCrypto_ERROR_OPEN_FAILURE; } - storage_off_t keysize; - rc = storage_get_file_size(handle, &keysize); - if (rc < 0) { - TLOGE("WTPI_LoadRootOfTrust: couldn't get file size: %d\n", rc); - storage_close_file(handle); - return OEMCrypto_ERROR_OPEN_FAILURE; - } + loading_from_backup = true; + } - if (*length < keysize) { - TLOGE("WTPI_LoadRootOfTrust: output buffer too small, should be at least %zu bytes\n", - (size_t)keysize); - storage_close_file(handle); - *length = keysize; - return OEMCrypto_ERROR_SHORT_BUFFER; - } - - rc = storage_read(handle, 0, keybox, keysize); + storage_off_t keysize; + rc = storage_get_file_size(handle, &keysize); + if (rc < 0) { + TLOGE("WTPI_LoadRootOfTrust: couldn't get file size: %d\n", rc); storage_close_file(handle); - if (rc < 0) { - TLOGE("WTPI_LoadRootOfTrust: error reading keybox: %d\n", rc); - return OEMCrypto_ERROR_KEYBOX_INVALID; - } - assert((size_t)rc == keysize); - - if (loading_from_backup) { - TLOGD("WTPI_LoadRootOfTrust: attempting to copy keybox from TDP to TP\n"); - rc = WTPI_SaveRootOfTrust(keybox, keysize); - if (rc != OEMCrypto_SUCCESS) { - TLOGE("WTPI_LoadRootOfTrust: failed to copy keybox from TDP to TP\n"); - } - } - - TLOGD("WTPI_LoadRootOfTrust: read %lu bytes for keybox\n", keysize); + return OEMCrypto_ERROR_OPEN_FAILURE; + } + if (*length < keysize) { + TLOGE( + "WTPI_LoadRootOfTrust: output buffer too small, should be at least %zu " + "bytes\n", + (size_t)keysize); + storage_close_file(handle); *length = keysize; - return OEMCrypto_SUCCESS; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + rc = storage_read(handle, 0, keybox, keysize); + storage_close_file(handle); + if (rc < 0) { + TLOGE("WTPI_LoadRootOfTrust: error reading keybox: %d\n", rc); + return OEMCrypto_ERROR_KEYBOX_INVALID; + } + assert((size_t)rc == keysize); + + if (loading_from_backup) { + TLOGD("WTPI_LoadRootOfTrust: attempting to copy keybox from TDP to TP\n"); + rc = WTPI_SaveRootOfTrust(keybox, keysize); + if (rc != OEMCrypto_SUCCESS) { + TLOGE("WTPI_LoadRootOfTrust: failed to copy keybox from TDP to TP\n"); + } + } + + TLOGD("WTPI_LoadRootOfTrust: read %lu bytes for keybox\n", keysize); + + *length = keysize; + return OEMCrypto_SUCCESS; } + +OEMCryptoResult WTPI_WrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length) { + (void)input; + (void)input_length; + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_UnwrapRootOfTrust30(const uint8_t* input, + size_t input_length, uint8_t* output, + size_t* output_length) { + (void)input; + (void)input_length; + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_SaveOEMPrivateKey30(const uint8_t* input, + size_t input_length) { + (void)input; + (void)input_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_LoadOEMPrivateKey30(uint8_t* output, + size_t* output_length) { + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_SaveOEMPublicCertificate30(const uint8_t* input, + size_t input_length) { + (void)input; + (void)input_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult WTPI_LoadOEMPublicCertificate30(uint8_t* output, + size_t* output_length) { + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} \ No newline at end of file diff --git a/oemcrypto/opk/ports/trusty/ta/reference/rules.mk b/oemcrypto/opk/ports/trusty/ta/reference/rules.mk index 443873d..fe434ef 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/rules.mk +++ b/oemcrypto/opk/ports/trusty/ta/reference/rules.mk @@ -79,6 +79,7 @@ MODULE_SRCS += \ $(APP_DIR)/wtpi_reference/cose_util.c \ $(APP_DIR)/wtpi_reference/crypto_util.c \ $(APP_DIR)/wtpi_reference/ecc_util.c \ + $(APP_DIR)/wtpi_reference/prov30_factory_util.c \ $(APP_DIR)/wtpi_reference/renewal_util.c \ $(APP_DIR)/wtpi_reference/rsa_util.c \ $(APP_DIR)/wtpi_reference/wtpi_abort.c \ diff --git a/oemcrypto/opk/serialization/common/GEN_common_serializer.c b/oemcrypto/opk/serialization/common/GEN_common_serializer.c index dc23290..d0fa5a3 100644 --- a/oemcrypto/opk/serialization/common/GEN_common_serializer.c +++ b/oemcrypto/opk/serialization/common/GEN_common_serializer.c @@ -745,6 +745,21 @@ void OPK_UnpackNullable_OEMCrypto_DestBufferDesc( OPK_Unpack_OEMCrypto_DestBufferDesc(msg, NULL); } } +void OPK_PackNullable_uint8_t(ODK_Message* msg, const uint8_t* value) { + OPK_PackBoolValue(msg, value == NULL); + if (value) { + OPK_Pack_uint8_t(msg, value); + } +} +void OPK_UnpackNullable_uint8_t(ODK_Message* msg, uint8_t** value) { + if (OPK_UnpackIsNull(msg)) { + if (value) *value = NULL; + } else if (value) { + OPK_Unpack_uint8_t(msg, *value); + } else { + OPK_Unpack_uint8_t(msg, NULL); + } +} void OPK_PackNullable_uint16_t(ODK_Message* msg, const uint16_t* value) { OPK_PackBoolValue(msg, value == NULL); if (value) { diff --git a/oemcrypto/opk/serialization/common/GEN_common_serializer.h b/oemcrypto/opk/serialization/common/GEN_common_serializer.h index 3362471..74c2728 100644 --- a/oemcrypto/opk/serialization/common/GEN_common_serializer.h +++ b/oemcrypto/opk/serialization/common/GEN_common_serializer.h @@ -107,6 +107,8 @@ void OPK_PackNullable_OEMCrypto_DestBufferDesc( ODK_Message* msg, const OEMCrypto_DestBufferDesc* value); void OPK_UnpackNullable_OEMCrypto_DestBufferDesc( ODK_Message* msg, OEMCrypto_DestBufferDesc** value); +void OPK_PackNullable_uint8_t(ODK_Message* msg, const uint8_t* value); +void OPK_UnpackNullable_uint8_t(ODK_Message* msg, uint8_t** value); void OPK_PackNullable_uint16_t(ODK_Message* msg, const uint16_t* value); void OPK_UnpackNullable_uint16_t(ODK_Message* msg, uint16_t** value); void OPK_UnpackAlloc_uint16_t(ODK_Message* msg, uint16_t** value); diff --git a/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c b/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c index b9418cc..e8f2e88 100644 --- a/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c +++ b/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c @@ -1287,6 +1287,42 @@ cleanup_and_return: return result; } +OEMCRYPTO_API OEMCryptoResult OEMCrypto_WrapClearPrivateKey( + const uint8_t* clear_private_key_bytes, size_t clear_private_key_length, + uint8_t* wrapped_private_key, size_t* wrapped_private_key_length) { + pthread_mutex_lock(&api_lock); + OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + ODK_Message request = ODK_Message_Create(NULL, 0); + ODK_Message response = ODK_Message_Create(NULL, 0); + + API_Initialize(); + request = OPK_Pack_WrapClearPrivateKey_Request( + clear_private_key_bytes, clear_private_key_length, wrapped_private_key, + wrapped_private_key_length); + if (ODK_Message_GetStatus(&request) != MESSAGE_STATUS_OK) { + if (ODK_Message_GetStatus(&request) == MESSAGE_STATUS_BUFFER_TOO_LARGE) { + api_result = OEMCrypto_ERROR_BUFFER_TOO_LARGE; + } else { + api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + goto cleanup_and_return; + } + response = API_Transact(&request); + OPK_Unpack_WrapClearPrivateKey_Response( + &response, &result, &wrapped_private_key, &wrapped_private_key_length); + + if (ODK_Message_GetStatus(&response) != MESSAGE_STATUS_OK) { + api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + } +cleanup_and_return: + TOS_Transport_ReleaseMessage(&request); + TOS_Transport_ReleaseMessage(&response); + + result = API_CheckResult(result); + pthread_mutex_unlock(&api_lock); + return result; +} + OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data, size_t* key_data_length) { pthread_mutex_lock(&api_lock); diff --git a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c index ec0cd5f..9eb73a5 100644 --- a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c +++ b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c @@ -1359,6 +1359,51 @@ void OPK_Unpack_GetDeviceID_Response(ODK_Message* msg, OEMCryptoResult* result, } } +ODK_Message OPK_Pack_WrapClearPrivateKey_Request( + const uint8_t* clear_private_key_bytes, size_t clear_private_key_length, + const uint8_t* wrapped_private_key, + const size_t* wrapped_private_key_length) { + uint32_t api_value = 154; /* from _oecc154 */ + ODK_Message msg = TOS_Transport_GetRequest(); + OPK_Pack_uint32_t(&msg, &api_value); + uint64_t timestamp = time(0); + OPK_Pack_uint64_t(&msg, ×tamp); + OPK_PackNullable_size_t(&msg, wrapped_private_key_length); + OPK_PackNullable_uint8_t(&msg, clear_private_key_bytes); + OPK_Pack_size_t(&msg, &clear_private_key_length); + OPK_PackAlloc(&msg, wrapped_private_key); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + +void OPK_Unpack_WrapClearPrivateKey_Response( + ODK_Message* msg, OEMCryptoResult* result, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 154) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + OPK_UnpackNullable_size_t(msg, wrapped_private_key_length); + OPK_Unpack_uint32_t(msg, result); + if (!Is_Valid_OEMCryptoResult(*result)) { + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_INVALID_ENUM_VALUE); + } + if (SuccessResult(*result)) { + uint8_t* p; + OPK_UnpackInPlace(msg, &p, OPK_FromSizeTPtrPtr(wrapped_private_key_length)); + if (p && *wrapped_private_key) { + memcpy(*wrapped_private_key, p, + OPK_SafeDerefSizeTPtrPtr(wrapped_private_key_length)); + } + } + OPK_UnpackEOM(msg); + + if (SuccessResult(*result)) { + OPK_SharedBuffer_FinalizeUnpacking(); + } +} + ODK_Message OPK_Pack_GetKeyData_Request(const uint8_t* key_data, const size_t* key_data_length) { uint32_t api_value = 4; /* from _oecc4 */ diff --git a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h index f44c8f8..7f72cbb 100644 --- a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h +++ b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h @@ -201,6 +201,13 @@ ODK_Message OPK_Pack_GetDeviceID_Request(const uint8_t* device_id, void OPK_Unpack_GetDeviceID_Response(ODK_Message* msg, OEMCryptoResult* result, uint8_t** device_id, size_t** device_id_length); +ODK_Message OPK_Pack_WrapClearPrivateKey_Request( + const uint8_t* clear_private_key_bytes, size_t clear_private_key_length, + const uint8_t* wrapped_private_key, + const size_t* wrapped_private_key_length); +void OPK_Unpack_WrapClearPrivateKey_Response( + ODK_Message* msg, OEMCryptoResult* result, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length); ODK_Message OPK_Pack_GetKeyData_Request(const uint8_t* key_data, const size_t* key_data_length); void OPK_Unpack_GetKeyData_Response(ODK_Message* msg, OEMCryptoResult* result, diff --git a/oemcrypto/opk/serialization/tee/GEN_dispatcher.c b/oemcrypto/opk/serialization/tee/GEN_dispatcher.c index 787fac8..1cdc271 100644 --- a/oemcrypto/opk/serialization/tee/GEN_dispatcher.c +++ b/oemcrypto/opk/serialization/tee/GEN_dispatcher.c @@ -874,6 +874,32 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetDeviceID_Response(result, device_id, device_id_length); break; } + case 154: /* OEMCrypto_WrapClearPrivateKey */ + { + size_t* wrapped_private_key_length = + (size_t*)OPK_VarAlloc(sizeof(size_t)); + OPK_Init_size_t(wrapped_private_key_length); + uint8_t* clear_private_key_bytes = + (uint8_t*)OPK_VarAlloc(sizeof(uint8_t)); + OPK_Init_uint8_t((uint8_t*)clear_private_key_bytes); + size_t clear_private_key_length; + OPK_Init_size_t((size_t*)&clear_private_key_length); + uint8_t* wrapped_private_key; + OPK_InitPointer((uint8_t**)&wrapped_private_key); + OPK_Unpack_WrapClearPrivateKey_Request( + request, &clear_private_key_bytes, &clear_private_key_length, + &wrapped_private_key, &wrapped_private_key_length); + if (!ODK_Message_IsValid(request)) goto handle_invalid_request; + OEMCryptoResult result; + OPK_Init_uint32_t((uint32_t*)&result); + LOGD("WrapClearPrivateKey"); + result = OEMCrypto_WrapClearPrivateKey( + clear_private_key_bytes, clear_private_key_length, + wrapped_private_key, wrapped_private_key_length); + *response = OPK_Pack_WrapClearPrivateKey_Response( + result, wrapped_private_key, wrapped_private_key_length); + break; + } case 4: /* OEMCrypto_GetKeyData */ { size_t* key_data_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); diff --git a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c index 87d9997..c0a7062 100644 --- a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c +++ b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c @@ -1151,6 +1151,42 @@ ODK_Message OPK_Pack_GetDeviceID_Response(OEMCryptoResult result, return msg; } +void OPK_Unpack_WrapClearPrivateKey_Request( + ODK_Message* msg, uint8_t** clear_private_key_bytes, + size_t* clear_private_key_length, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 154) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + uint64_t timestamp; + OPK_Unpack_uint64_t(msg, ×tamp); + OPK_UnpackNullable_size_t(msg, wrapped_private_key_length); + OPK_UnpackNullable_uint8_t(msg, clear_private_key_bytes); + OPK_Unpack_size_t(msg, clear_private_key_length); + *wrapped_private_key = (uint8_t*)OPK_UnpackAllocBuffer( + msg, OPK_FromSizeTPtrPtr(wrapped_private_key_length), sizeof(uint8_t)); + OPK_UnpackEOM(msg); + OPK_SharedBuffer_FinalizeUnpacking(); +} + +ODK_Message OPK_Pack_WrapClearPrivateKey_Response( + OEMCryptoResult result, const uint8_t* wrapped_private_key, + const size_t* wrapped_private_key_length) { + uint32_t api_value = 154; /* from _oecc154 */ + ODK_Message msg = TOS_Transport_GetResponse(); + OPK_Pack_uint32_t(&msg, &api_value); + OPK_PackNullable_size_t(&msg, wrapped_private_key_length); + OPK_Pack_uint32_t(&msg, &result); + if (SuccessResult(result)) { + OPK_PackMemory(&msg, (const uint8_t*)wrapped_private_key, + OPK_FromSizeTPtr(wrapped_private_key_length)); + } + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + void OPK_Unpack_GetKeyData_Request(ODK_Message* msg, uint8_t** key_data, size_t** key_data_length) { uint32_t api_value = UINT32_MAX; diff --git a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h index 83b81e1..0e6990d 100644 --- a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h +++ b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h @@ -199,6 +199,13 @@ void OPK_Unpack_GetDeviceID_Request(ODK_Message* msg, uint8_t** device_id, ODK_Message OPK_Pack_GetDeviceID_Response(OEMCryptoResult result, const uint8_t* device_id, const size_t* device_id_length); +void OPK_Unpack_WrapClearPrivateKey_Request( + ODK_Message* msg, uint8_t** clear_private_key_bytes, + size_t* clear_private_key_length, uint8_t** wrapped_private_key, + size_t** wrapped_private_key_length); +ODK_Message OPK_Pack_WrapClearPrivateKey_Response( + OEMCryptoResult result, const uint8_t* wrapped_private_key, + const size_t* wrapped_private_key_length); void OPK_Unpack_GetKeyData_Request(ODK_Message* msg, uint8_t** key_data, size_t** key_data_length); ODK_Message OPK_Pack_GetKeyData_Response(OEMCryptoResult result, diff --git a/oemcrypto/test/GEN_api_lock_file.c b/oemcrypto/test/GEN_api_lock_file.c index a60a6cf..e1d5925 100644 --- a/oemcrypto/test/GEN_api_lock_file.c +++ b/oemcrypto/test/GEN_api_lock_file.c @@ -375,3 +375,12 @@ OEMCryptoResult _oecc143(uint8_t* public_cert, size_t* public_cert_length); // OEMCrypto_UseSecondaryKey defined in v18.5 OEMCryptoResult _oecc144(OEMCrypto_SESSION session_id, bool dual_key); + +// OEMCrypto_MarkOfflineSession defined in v18.6 +OEMCryptoResult _oecc153(OEMCrypto_SESSION session); + +// OEMCrypto_WrapClearPrivateKey defined in v18.6 +OEMCryptoResult _oecc154(const uint8_t* clear_private_key_bytes, + size_t clear_private_key_length, + uint8_t* wrapped_private_key, + size_t* wrapped_private_key_length); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h index a322ebc..c5e6c1f 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h +++ b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h @@ -122,6 +122,8 @@ class OEMCryptoRenewalAPIFuzz { void Initialize() { license_api_fuzz_.Initialize(); } + void LoadLicense() { license_api_fuzz_.LoadLicense(); } + void Terminate() { license_api_fuzz_.Terminate(); } LicenseRoundTrip& license_messages() { diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc index 658bdc1..03cf860 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc @@ -20,6 +20,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::vector input(data, data + size); wvoec::OEMCryptoRenewalAPIFuzz renewal_api_fuzz; renewal_api_fuzz.Initialize(); + renewal_api_fuzz.LoadLicense(); renewal_api_fuzz.renewal_messages().InjectFuzzedRequestData(input.data(), input.size()); renewal_api_fuzz.Terminate(); diff --git a/oemcrypto/test/install_prov30_oem_cert_tool.cpp b/oemcrypto/test/install_prov30_oem_cert_tool.cpp new file mode 100644 index 0000000..25eac6d --- /dev/null +++ b/oemcrypto/test/install_prov30_oem_cert_tool.cpp @@ -0,0 +1,154 @@ +// Copyright 2024 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. + +#include +#include +#include + +#include "OEMCryptoCENC.h" +#include "oec_test_data.h" +#include "platform.h" +#include "string_conversions.h" + +namespace { + +constexpr size_t kAesBlockSize = 16; + +/* +This function concatenates the test Prov30 OEM certificate chain and key to the +format below: + ++-----------------------+----------------------+--------------------------+ +| Cert Chain Length | Certificate Chain | Key Length | ++-----------------------+----------------------+--------------------------+ +| (4 bytes, big-endian) | (DER-encoded PKCS#7) | (4 bytes, big-endian) | ++-----------------------+----------------------+--------------------------+ +| Private Key | ++-----------------------+ + +|oem_private_key| should be a RSA key in PKCS#8 PrivateKeyInfo format. +|oem_public_cert| should be a DER-encoded PKCS#7 certificate chain. + +The output will be consumed by OEMCrypto Prov30 factory functions: +1. It is wrapped by OEMCrypto_WrapKeyboxOrOEMCert(), and +2. The wrapped root of trust will be installed by +OEMCrypto_InstallKeyboxOrOEMCert(). Therefore, the OEMCrypto implementation of +the factory functions and the tool must have an agreement on the format above. +*/ +std::vector PrepareProv30OEMCertAndKey( + const uint8_t* oem_public_cert, const size_t oem_public_cert_size, + const uint8_t* oem_private_key, const size_t oem_private_key_size) { + std::vector oem_cert_and_key; + // Calculate total size + size_t total_size = sizeof(uint32_t) + oem_public_cert_size + + sizeof(uint32_t) + oem_private_key_size; + oem_cert_and_key.resize(total_size); + + // Offset to track where to write in the output vector + size_t offset = 0; + // 1. Store public cert size (big-endian) + uint32_t networkOrderCertSize = htonl((uint32_t)oem_public_cert_size); + std::copy(reinterpret_cast(&networkOrderCertSize), + reinterpret_cast(&networkOrderCertSize) + + sizeof(uint32_t), + oem_cert_and_key.begin()); + offset += sizeof(uint32_t); + + // 2. Store public cert content + std::copy(oem_public_cert, oem_public_cert + oem_public_cert_size, + oem_cert_and_key.begin() + offset); + offset += oem_public_cert_size; + + // 3. Store private key size (big-endian) + uint32_t networkOrderKeySize = htonl((uint32_t)oem_private_key_size); + std::copy( + reinterpret_cast(&networkOrderKeySize), + reinterpret_cast(&networkOrderKeySize) + sizeof(uint32_t), + oem_cert_and_key.begin() + offset); + offset += sizeof(uint32_t); + + // 4. Store private key content + std::copy(oem_private_key, oem_private_key + oem_private_key_size, + oem_cert_and_key.begin() + offset); + return oem_cert_and_key; +} + +OEMCryptoResult InstallTestProv30RootOfTrust( + const uint8_t* oem_public_cert, const size_t oem_public_cert_size, + const uint8_t* oem_private_key, const size_t oem_private_key_size) { + if (oem_public_cert == nullptr || oem_private_key == nullptr || + oem_public_cert_size == 0 || oem_private_key_size == 0) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + // 1. Prepare OEM cert and key. + std::vector oem_cert_and_key = + PrepareProv30OEMCertAndKey(oem_public_cert, oem_public_cert_size, + oem_private_key, oem_private_key_size); + if (oem_cert_and_key.empty()) { + std::cerr << "Failed to prepare OEM cert and key" << std::endl; + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // Add padding. + const uint8_t padding = + kAesBlockSize - (oem_cert_and_key.size() % kAesBlockSize); + for (size_t i = 0; i < padding; i++) { + oem_cert_and_key.push_back(padding); + } + + // 2: Initialize OEMCrypto. + OEMCryptoResult sts = OEMCrypto_Initialize(); + if (sts != OEMCrypto_SUCCESS) { + std::cerr << "Failed to initialize: result = " << sts << std::endl; + return sts; + } + + // 3: Wrap OEM cert and key before calling install function. + const OEMCrypto_ProvisioningMethod method = OEMCrypto_GetProvisioningMethod(); + if (method != OEMCrypto_OEMCertificate) { + std::cerr << "OEMCrypto is not OEMCrypto_OEMCertificate: method = "; + std::cerr << method << std::endl; + OEMCrypto_Terminate(); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + std::vector wrapped_oem_cert_and_key; + size_t wrapped_oem_cert_and_key_size = 0; + sts = OEMCrypto_WrapKeyboxOrOEMCert( + oem_cert_and_key.data(), oem_cert_and_key.size(), + wrapped_oem_cert_and_key.data(), &wrapped_oem_cert_and_key_size, nullptr, + 0); + if (sts != OEMCrypto_ERROR_SHORT_BUFFER) { + OEMCrypto_Terminate(); + return sts; + } + wrapped_oem_cert_and_key.resize(wrapped_oem_cert_and_key_size); + sts = OEMCrypto_WrapKeyboxOrOEMCert( + oem_cert_and_key.data(), oem_cert_and_key.size(), + wrapped_oem_cert_and_key.data(), &wrapped_oem_cert_and_key_size, nullptr, + 0); + if (sts != OEMCrypto_SUCCESS) { + OEMCrypto_Terminate(); + return sts; + } + + // 4: Install the wrapped OEM cert and key. + sts = OEMCrypto_InstallKeyboxOrOEMCert(wrapped_oem_cert_and_key.data(), + wrapped_oem_cert_and_key_size); + OEMCrypto_Terminate(); + return sts; +} +} // namespace + +int main() { + const OEMCryptoResult result = InstallTestProv30RootOfTrust( + wvoec::kTestOEMPublicCertInfo2, sizeof(wvoec::kTestOEMPublicCertInfo2), + wvoec::kTestRSAPKCS8PrivateKeyInfo2_2048, + sizeof(wvoec::kTestRSAPKCS8PrivateKeyInfo2_2048)); + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to install OEM cert and key with result: " << result + << std::endl; + return 1; + } + return 0; +} diff --git a/oemcrypto/test/oec_device_features.cpp b/oemcrypto/test/oec_device_features.cpp index 77538c7..49f0d8c 100644 --- a/oemcrypto/test/oec_device_features.cpp +++ b/oemcrypto/test/oec_device_features.cpp @@ -65,7 +65,8 @@ void DeviceFeatures::Initialize() { // baked in certificate. loads_certificate = provisioning_method == OEMCrypto_Keybox || provisioning_method == OEMCrypto_OEMCertificate || - provisioning_method == OEMCrypto_BootCertificateChain; + provisioning_method == OEMCrypto_BootCertificateChain || + provisioning_method == OEMCrypto_DrmReprovisioning; printf("loads_certificate = %s.\n", loads_certificate ? "true" : "false"); generic_crypto = (OEMCrypto_ERROR_NOT_IMPLEMENTED != diff --git a/oemcrypto/test/oec_session_util.cpp b/oemcrypto/test/oec_session_util.cpp index 783caa1..e562c3f 100644 --- a/oemcrypto/test/oec_session_util.cpp +++ b/oemcrypto/test/oec_session_util.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -353,6 +354,11 @@ void ProvisioningRoundTrip::PrepareSession( session_->LoadOEMCert(true); session_->GenerateRsaSessionKey(&message_key_, &encrypted_message_key_); encryptor_.set_enc_key(message_key_); + } else if (global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + session_->SetTestRsaPublicKey(); + session_->GenerateRsaSessionKey(&message_key_, &encrypted_message_key_); + encryptor_.set_enc_key(message_key_); } else { EXPECT_EQ(global_features.provisioning_method, OEMCrypto_OEMCertificate); session_->LoadOEMCert(true); @@ -367,6 +373,15 @@ void ProvisioningRoundTrip::VerifyRequestSignature( if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { session()->VerifyRsaSignature(data, generated_signature.data(), generated_signature.size(), kSign_RSASSA_PSS); + } else if (global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + // DRM Reprovisioning uses protocol 2.2 which computes signatures for the + // sha512 hash of the message and not the full message. + std::vector signature_source; + signature_source.resize(SHA512_DIGEST_LENGTH); + SHA512(data.data(), data.size(), signature_source.data()); + session()->VerifyRsaSignature(signature_source, generated_signature.data(), + generated_signature.size(), kSign_RSASSA_PSS); } else { EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); ASSERT_EQ(HMAC_SHA256_SIGNATURE_SIZE, generated_signature.size()); @@ -460,9 +475,6 @@ void ProvisioningRoundTrip::SignResponse() { memcpy(encrypted_response_.data() + serialized_core_message_.size(), reinterpret_cast(&encrypted_response_data_), sizeof(encrypted_response_data_)); - if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { - session()->GenerateDerivedKeysFromSessionKey(); - } session()->key_deriver().ServerSignBuffer(encrypted_response_.data(), encrypted_response_.size(), &response_signature_); diff --git a/oemcrypto/test/oec_test_data.h b/oemcrypto/test/oec_test_data.h index d279217..eec25c2 100644 --- a/oemcrypto/test/oec_test_data.h +++ b/oemcrypto/test/oec_test_data.h @@ -8,6 +8,7 @@ #define CDM_OEC_TEST_DATA_H_ #include +#include #include "OEMCryptoCENC.h" #include "oemcrypto_types.h" @@ -193,6 +194,206 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = { 0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03}; +// Counterpart of kTestRSAPKCS8PrivateKeyInfo2_2048[] +static const uint8_t kTestOEMPublicCertInfo2[] = { + 0x30, 0x82, 0x09, 0x2d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0x1e, 0x30, 0x82, 0x09, 0x1a, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x08, + 0xfe, 0x30, 0x82, 0x03, 0x71, 0x30, 0x82, 0x02, 0x59, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x11, 0x00, 0xc2, 0x8d, 0x20, 0x22, 0x82, 0x8b, 0x9e, + 0x63, 0x9d, 0x15, 0x89, 0x2c, 0xa9, 0x8f, 0xd9, 0x5d, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x30, 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x02, 0x57, 0x41, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x39, 0x31, + 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x32, 0x36, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x38, 0x30, 0x31, + 0x30, 0x36, 0x31, 0x33, 0x32, 0x36, 0x32, 0x32, 0x5a, 0x30, 0x65, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x39, + 0x31, 0x33, 0x2d, 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, + 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, + 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7, + 0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57, 0x67, 0x5e, 0x56, + 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa, 0x9d, 0xb4, 0x4e, + 0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3, 0x34, + 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda, 0x3f, 0xce, 0x31, + 0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb, 0x3e, + 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2, 0x73, 0x9e, 0x39, + 0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4, 0xf2, + 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a, 0x13, 0x8b, 0x54, + 0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda, 0xb3, + 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56, 0x57, 0x54, 0x71, + 0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03, 0x96, + 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83, 0x06, 0x51, 0x5a, + 0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b, 0x4c, + 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f, 0xf8, 0x12, 0x7f, + 0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01, 0xca, + 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46, 0x0b, 0x3a, 0x77, + 0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed, 0x27, + 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b, 0x3d, 0xdb, 0x9c, + 0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb, 0x2c, + 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x16, + 0x30, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, + 0x79, 0x04, 0x01, 0x01, 0x04, 0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x88, 0x95, 0xec, 0xcd, 0x8b, 0xa7, + 0x51, 0xda, 0x74, 0x81, 0xa5, 0x39, 0x62, 0x1a, 0x0e, 0x2e, 0xde, 0x3c, + 0x37, 0xea, 0xad, 0x7c, 0xee, 0x9b, 0x26, 0x8e, 0xe2, 0xd6, 0x34, 0xcd, + 0xb7, 0x70, 0xba, 0xbf, 0xa0, 0xa3, 0xfe, 0xb3, 0x4b, 0xbc, 0xf4, 0x1c, + 0x72, 0x66, 0x81, 0xd5, 0x09, 0x33, 0x78, 0x0c, 0x61, 0x21, 0xa8, 0xf1, + 0xe2, 0xc9, 0xe2, 0x83, 0xc2, 0x19, 0x02, 0xf2, 0xe8, 0xab, 0x17, 0x36, + 0x3a, 0x0b, 0x20, 0xaf, 0x0f, 0xae, 0x2e, 0x73, 0x68, 0xac, 0x15, 0xee, + 0x9c, 0xc0, 0x92, 0x03, 0x7e, 0x95, 0x63, 0xaa, 0xad, 0x15, 0x96, 0x43, + 0x20, 0x3b, 0xe5, 0x9b, 0x1f, 0xca, 0x02, 0xba, 0xf0, 0x07, 0x76, 0x80, + 0xd7, 0xa3, 0x1a, 0xeb, 0xc8, 0xdb, 0x03, 0x7b, 0x43, 0x56, 0xe5, 0x96, + 0x6b, 0x86, 0xfe, 0x08, 0x58, 0x8a, 0x84, 0xbd, 0xe9, 0x47, 0x18, 0xee, + 0xb2, 0xa8, 0x05, 0x7b, 0xf0, 0xfd, 0xaa, 0xb9, 0x85, 0xcd, 0x7a, 0x0e, + 0x6b, 0x6c, 0x9f, 0xc6, 0x75, 0xd2, 0x2a, 0xfe, 0x5b, 0xf3, 0xb7, 0x31, + 0x6c, 0xac, 0xe3, 0x00, 0x9f, 0xe7, 0xdd, 0xe3, 0x81, 0xc1, 0x36, 0xc3, + 0x1c, 0x5f, 0xdf, 0xf2, 0xc3, 0x5e, 0xfa, 0x55, 0x32, 0xd8, 0x5c, 0xa8, + 0xe5, 0xcc, 0xb6, 0x4a, 0xe9, 0xe2, 0xcc, 0x38, 0x44, 0x07, 0x46, 0x59, + 0x34, 0x84, 0x79, 0xf9, 0xee, 0x3c, 0x4b, 0x48, 0x90, 0xab, 0x73, 0xb0, + 0xa1, 0x92, 0xc3, 0xd6, 0x83, 0x87, 0x81, 0xca, 0x12, 0x81, 0xd6, 0x5d, + 0xf7, 0x6f, 0x7a, 0x35, 0x5e, 0x4f, 0x02, 0x66, 0x8a, 0x47, 0x88, 0x82, + 0xab, 0xf0, 0x12, 0x1d, 0xb9, 0x75, 0x3b, 0x7b, 0xa8, 0x36, 0x15, 0xef, + 0xa8, 0x12, 0x0e, 0x53, 0xb4, 0x83, 0x78, 0x53, 0xc0, 0x52, 0xae, 0xa6, + 0x0a, 0xa0, 0x53, 0xdc, 0x1c, 0x15, 0x22, 0xdd, 0x17, 0x98, 0x30, 0x82, + 0x05, 0x85, 0x30, 0x82, 0x03, 0x6d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x10, 0x03, 0xb1, 0xf7, 0x58, 0xdf, 0x1d, 0xe3, 0x25, 0x00, 0x0b, 0x10, + 0x3d, 0xd5, 0xe6, 0xe4, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7e, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, + 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, + 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, + 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, + 0x70, 0x72, 0x6f, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x31, + 0x31, 0x38, 0x30, 0x31, 0x31, 0x33, 0x33, 0x35, 0x5a, 0x17, 0x0d, 0x32, + 0x37, 0x31, 0x31, 0x31, 0x38, 0x30, 0x31, 0x31, 0x33, 0x31, 0x33, 0x5a, + 0x30, 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x02, 0x57, 0x41, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x39, 0x31, + 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, + 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0xc8, + 0x71, 0xae, 0x08, 0x0c, 0x06, 0x06, 0x2d, 0x81, 0x7c, 0xa9, 0x8b, 0xb3, + 0xd6, 0x66, 0xe4, 0xf6, 0x08, 0x5e, 0x5a, 0x75, 0xe8, 0x74, 0x61, 0x7a, + 0x88, 0xca, 0x85, 0x14, 0x0d, 0x58, 0xa4, 0x09, 0x19, 0x6c, 0x60, 0xc9, + 0xad, 0x91, 0x1c, 0xbf, 0x04, 0xb3, 0x47, 0x10, 0x63, 0x7f, 0x02, 0x58, + 0xc2, 0x1e, 0xbd, 0xcc, 0x07, 0x77, 0xaa, 0x7e, 0x14, 0xa8, 0xc2, 0x01, + 0xcd, 0xe8, 0x46, 0x60, 0x53, 0x6f, 0x2f, 0xda, 0x17, 0x2d, 0x4d, 0x9d, + 0x0e, 0x5d, 0xb5, 0x50, 0x95, 0xae, 0xab, 0x6e, 0x43, 0xe3, 0xb0, 0x00, + 0x12, 0xb4, 0x05, 0x82, 0x4a, 0x2b, 0x14, 0x63, 0x0d, 0x1f, 0x06, 0x12, + 0xaa, 0xe1, 0x9d, 0xe7, 0xba, 0xda, 0xe3, 0xfc, 0x7c, 0x6c, 0x73, 0xae, + 0x56, 0xf8, 0xab, 0xf7, 0x51, 0x93, 0x31, 0xef, 0x8f, 0xe4, 0xb6, 0x01, + 0x2c, 0xeb, 0x7b, 0xe4, 0xd8, 0xb3, 0xea, 0x70, 0x37, 0x89, 0x05, 0xa9, + 0x51, 0x57, 0x72, 0x98, 0x9e, 0xa8, 0x46, 0xdb, 0xeb, 0x7a, 0x38, 0x2b, + 0x2f, 0xc0, 0x27, 0xb7, 0xc2, 0xe1, 0x9a, 0x17, 0xdf, 0xf5, 0xd6, 0x9c, + 0xd5, 0x8c, 0xb8, 0x66, 0x42, 0xd5, 0x04, 0x1e, 0x7c, 0x36, 0x4c, 0x1e, + 0x3e, 0x45, 0x51, 0x4d, 0x41, 0x72, 0x22, 0x53, 0x3d, 0xf4, 0x57, 0x7c, + 0x6c, 0x33, 0x34, 0x24, 0x45, 0xdf, 0x84, 0x87, 0x4a, 0xa6, 0xcb, 0x7c, + 0x03, 0xa3, 0xaa, 0x8e, 0x2d, 0x82, 0x01, 0x27, 0x87, 0x74, 0x82, 0x1a, + 0xbc, 0x0f, 0x76, 0x69, 0xab, 0xe0, 0x4e, 0x70, 0xbe, 0x37, 0xfc, 0xc8, + 0x2c, 0x91, 0x17, 0x4f, 0xd5, 0x26, 0x3b, 0x7b, 0x90, 0xb5, 0x2d, 0x64, + 0xba, 0xf7, 0xd2, 0x8a, 0xb4, 0x8f, 0x38, 0x9d, 0x8e, 0xba, 0xe7, 0x5c, + 0x52, 0xf1, 0x0a, 0xb8, 0xc0, 0x1b, 0xb6, 0xb1, 0x70, 0x7e, 0x47, 0x59, + 0x94, 0x59, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, + 0x82, 0x01, 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x02, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0x4b, 0xcb, 0xdf, 0xaa, 0x02, 0xde, 0x8d, 0xc3, 0xe7, 0xe5, + 0x85, 0xdb, 0x2e, 0x8a, 0xbe, 0x75, 0x6b, 0x8a, 0x67, 0x58, 0x30, 0x81, + 0xb2, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7, + 0x80, 0x14, 0x04, 0x94, 0x66, 0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, + 0xf7, 0x13, 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a, 0x8f, 0xa1, 0x81, + 0x83, 0xa4, 0x81, 0x80, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, + 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, + 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, + 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, + 0x82, 0x09, 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe, 0x9a, 0x9a, 0x30, + 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, + 0x01, 0x04, 0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0x61, 0x3f, 0x2f, 0x43, 0xe4, 0xbe, 0x66, 0x34, 0xef, + 0x92, 0x06, 0xe9, 0x88, 0xba, 0x6a, 0x1d, 0x4f, 0x54, 0x5a, 0x97, 0xb1, + 0x75, 0xd7, 0x93, 0xf8, 0x45, 0xc6, 0x83, 0x92, 0x36, 0xfd, 0x55, 0xa9, + 0x21, 0x0b, 0xdc, 0xf6, 0xae, 0x11, 0xdc, 0x62, 0x21, 0x44, 0xbd, 0x04, + 0x1d, 0x58, 0x2c, 0x03, 0xf8, 0xe4, 0xe2, 0x1e, 0xba, 0xe6, 0xdd, 0x19, + 0xdd, 0x56, 0xfd, 0xce, 0x06, 0x73, 0x5f, 0x94, 0x1e, 0xb6, 0x03, 0xdb, + 0x3d, 0x7b, 0xab, 0xab, 0x72, 0x64, 0x7b, 0xde, 0x7d, 0x4d, 0xcf, 0x7e, + 0xf0, 0x91, 0x29, 0xc1, 0x77, 0x13, 0xc2, 0x6f, 0x80, 0xab, 0x7a, 0xa8, + 0xce, 0xb0, 0x1c, 0x2a, 0xc5, 0x9c, 0xfb, 0x0b, 0xe5, 0x9f, 0x9c, 0x1b, + 0xc9, 0x4b, 0x58, 0xdf, 0x96, 0x18, 0xf7, 0x67, 0x67, 0x89, 0xa4, 0xe9, + 0x14, 0x48, 0xac, 0xfa, 0x9d, 0x86, 0x2a, 0xeb, 0x75, 0x2c, 0x2b, 0xbf, + 0x63, 0x7d, 0xc7, 0x4e, 0x7e, 0xad, 0x39, 0x2d, 0xb4, 0x7c, 0x07, 0xa5, + 0x5a, 0xe8, 0x3a, 0xd4, 0xf5, 0x0c, 0x4f, 0xf3, 0xa2, 0x9c, 0x3c, 0x32, + 0xed, 0x9d, 0x4b, 0x49, 0x05, 0xbc, 0x1f, 0xa0, 0x13, 0xe6, 0xdd, 0x82, + 0x79, 0x06, 0x31, 0x3b, 0xc6, 0x97, 0xec, 0x8d, 0xaa, 0x4f, 0xef, 0x14, + 0x3c, 0x21, 0xf6, 0x72, 0xb2, 0x09, 0x42, 0xc7, 0x74, 0xfe, 0xef, 0x70, + 0xbd, 0xe9, 0x85, 0x41, 0x30, 0x0b, 0xb3, 0x6b, 0x59, 0x0c, 0x0f, 0x11, + 0x75, 0xd4, 0xbb, 0xb1, 0xdf, 0xb1, 0xdf, 0xb3, 0xfa, 0xb3, 0x3a, 0x43, + 0x17, 0x7d, 0x8a, 0x82, 0xae, 0xa2, 0x07, 0xf8, 0x83, 0x51, 0xfb, 0x16, + 0xfb, 0x64, 0xb6, 0x46, 0xda, 0xbe, 0x32, 0x2b, 0xc0, 0xee, 0x78, 0x2a, + 0x84, 0xa9, 0x54, 0x0a, 0xf9, 0x2d, 0x61, 0x65, 0xde, 0xa5, 0x97, 0x66, + 0x79, 0x02, 0xf8, 0x97, 0x17, 0xe2, 0xd4, 0x9f, 0x9e, 0xac, 0xcc, 0xae, + 0x99, 0x9a, 0x03, 0x04, 0xbb, 0x45, 0xfe, 0xb2, 0xf5, 0x80, 0xba, 0xbf, + 0xdd, 0x24, 0xe5, 0xe6, 0x1e, 0x5d, 0x36, 0xa5, 0x87, 0x0c, 0xdf, 0x60, + 0x81, 0x6f, 0xb7, 0x5f, 0xb9, 0x1f, 0xca, 0x75, 0x3c, 0x1a, 0x63, 0xb0, + 0xeb, 0xe6, 0x95, 0x86, 0x0d, 0xae, 0xa6, 0xc9, 0x2a, 0x94, 0xf1, 0xd0, + 0xbe, 0x75, 0xc8, 0xf8, 0x07, 0xd7, 0x88, 0xff, 0xec, 0xf9, 0xcd, 0x49, + 0xc6, 0xfe, 0x4d, 0x7f, 0x44, 0x1e, 0xd8, 0xaf, 0xa9, 0x72, 0x27, 0x98, + 0xe2, 0x5a, 0x08, 0xea, 0x55, 0xd3, 0xb3, 0xea, 0xdc, 0x76, 0x69, 0x51, + 0x10, 0x01, 0x46, 0x7d, 0x33, 0x94, 0x9c, 0x94, 0xef, 0xfe, 0x76, 0x1c, + 0xc6, 0xd7, 0x15, 0x53, 0x3e, 0x8d, 0x3d, 0x29, 0x9a, 0x58, 0x6a, 0xf1, + 0x75, 0x9e, 0xea, 0x1b, 0x4c, 0xf0, 0x47, 0x76, 0xac, 0xc6, 0xa2, 0x32, + 0x44, 0x40, 0xdf, 0xfe, 0xff, 0x9d, 0xf4, 0xe2, 0xc2, 0xfa, 0xa1, 0x5f, + 0x2e, 0x66, 0xe9, 0x97, 0xcb, 0x27, 0x26, 0x6e, 0x53, 0xe4, 0xe8, 0x86, + 0x2c, 0xea, 0xd3, 0x69, 0x6c, 0x61, 0x4f, 0xfe, 0xc1, 0xc9, 0x8b, 0x05, + 0x92, 0x6f, 0x47, 0x96, 0xce, 0xf0, 0x33, 0xfa, 0x7c, 0x78, 0x24, 0x9b, + 0xd7, 0x8d, 0x36, 0x56, 0x37, 0x86, 0xbc, 0x72, 0x5a, 0xf9, 0xb9, 0xb0, + 0x93, 0xf0, 0x81, 0x78, 0x10, 0xf2, 0xb0, 0xc2, 0x79, 0x91, 0x5e, 0xcf, + 0xbc, 0x8c, 0xf2, 0x32, 0x0f, 0xf7, 0x2d, 0x30, 0xd8, 0x13, 0x77, 0x4f, + 0x78, 0x9e, 0x40, 0x8d, 0xe6, 0x3a, 0x98, 0xb2, 0xaa, 0x13, 0x4d, 0x25, + 0x49, 0x34, 0x6c, 0x80, 0x9e, 0x19, 0x03, 0xdb, 0xcd, 0xf5, 0xb1, 0x54, + 0x74, 0x1b, 0x67, 0x3c, 0x46, 0xac, 0x3e, 0x5d, 0xa2, 0xd9, 0x13, 0x83, + 0x30, 0xeb, 0x82, 0x3b, 0x06, 0xab, 0x3c, 0x39, 0x7d, 0xd0, 0x68, 0x31, + 0x00}; + // A 3072 bit RSA key in PKCS#8 PrivateKeyInfo format // Used to verify the functions that manipulate RSA keys. static const uint8_t kTestRSAPKCS8PrivateKeyInfo3_3072[] = { diff --git a/oemcrypto/test/oemcrypto_basic_test.cpp b/oemcrypto/test/oemcrypto_basic_test.cpp index 015a14b..42f638a 100644 --- a/oemcrypto/test/oemcrypto_basic_test.cpp +++ b/oemcrypto/test/oemcrypto_basic_test.cpp @@ -156,7 +156,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 18.5. Tests last updated 2024-03-21"; + "OEMCrypto unit tests for API 18.6. Tests last updated 2024-06-04"; cout << " " << log_message << "\n"; cout << " " << "These tests are part of Android U." @@ -165,7 +165,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) { // If any of the following fail, then it is time to update the log message // above. EXPECT_EQ(ODK_MAJOR_VERSION, 18); - EXPECT_EQ(ODK_MINOR_VERSION, 5); + EXPECT_EQ(ODK_MINOR_VERSION, 6); EXPECT_EQ(kCurrentAPI, static_cast(ODK_MAJOR_VERSION)); OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); EXPECT_GT(level, OEMCrypto_Level_Unknown); diff --git a/oemcrypto/test/oemcrypto_provisioning_test.cpp b/oemcrypto/test/oemcrypto_provisioning_test.cpp index 47d7228..db5e9bd 100644 --- a/oemcrypto/test/oemcrypto_provisioning_test.cpp +++ b/oemcrypto/test/oemcrypto_provisioning_test.cpp @@ -6,6 +6,7 @@ #include "oemcrypto_provisioning_test.h" #include "log.h" +#include "oec_device_features.h" #include "platform.h" #include "test_sleep.h" @@ -161,10 +162,6 @@ TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) { public_cert.resize(public_cert_length); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetOEMPublicCertificate( public_cert.data(), &public_cert_length)); - // Derive keys from the session key -- this should use the DRM Cert's key. - // It should NOT use the OEM Private key because that key should not have - // been loaded. - ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey()); // Now fill a message and try to load it. LicenseRoundTrip license_messages(&s); license_messages.set_control(0); @@ -739,6 +736,9 @@ TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) { ASSERT_NO_FATAL_FAILURE(s.open()); if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { s.LoadOEMCert(true); + } else if (global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + s.SetTestRsaPublicKey(); } else { EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); s.GenerateDerivedKeysFromKeybox(keybox_); @@ -758,6 +758,9 @@ TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) { ASSERT_NO_FATAL_FAILURE(s.open()); if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { s.LoadOEMCert(true); + } else if (global_features.provisioning_method == + OEMCrypto_DrmReprovisioning) { + s.SetTestRsaPublicKey(); } else { EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); s.GenerateDerivedKeysFromKeybox(keybox_); @@ -798,6 +801,12 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } + Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -820,6 +829,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -842,6 +856,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -866,6 +885,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -893,6 +917,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) { if (global_features.provisioning_method != OEMCrypto_OEMCertificate) { GTEST_SKIP() << "Test for Prov 3.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -940,6 +969,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonce_API16) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -959,6 +993,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates and do not support + // key rewrapping. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } Session s; ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); provisioning_messages.PrepareSession(keybox_); @@ -1125,6 +1164,10 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); Session s1; // Session s1 loads the default rsa key, but doesn't use it // until after s2 uses its key. @@ -1166,6 +1209,10 @@ TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { GTEST_SKIP() << "Test for non Prov 4.0 devices only."; } + // DRM Reprovisioning CDMs have embedded certificates. + if (global_features.provisioning_method == OEMCrypto_DrmReprovisioning) { + GTEST_SKIP() << "Test for non DRM Reprovisioning devices."; + } const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys); std::vector> sessions; std::vector> licenses; @@ -1243,123 +1290,6 @@ TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) { << "Supported certificates is only " << OEMCrypto_SupportedCertificates(); } -// This test is not run by default, because it takes a long time and -// is used to measure RSA performance, not test functionality. -TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { - // TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for - // provisioning 4. Disabled here temporarily. - if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { - GTEST_SKIP() << "Test for non Prov 4.0 devices only."; - } - const std::chrono::milliseconds kTestDuration(5000); - OEMCryptoResult sts; - std::chrono::steady_clock clock; - wvutil::TestSleep::Sleep(kShortSleep); // Make sure we are not nonce limited. - - auto start_time = clock.now(); - int count = 15; - for (int i = 0; i < count; i++) { // Only 20 nonce available. - ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); - } - auto delta_time = clock.now() - start_time; - const double provision_time = - delta_time / std::chrono::milliseconds(1) / count; - - Session session; - ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); - start_time = clock.now(); - count = 0; - while (clock.now() - start_time < kTestDuration) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); - const size_t size = 50; - vector licenseRequest(size); - GetRandBytes(licenseRequest.data(), licenseRequest.size()); - size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), - licenseRequest.size(), nullptr, - &signature_length, kSign_RSASSA_PSS); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_NE(static_cast(0), signature_length); - - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generate_rsa_signature_fuzz_seed_corpus"); - OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure; - fuzzed_structure.padding_scheme = kSign_RSASSA_PSS; - fuzzed_structure.signature_length = signature_length; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, - reinterpret_cast(licenseRequest.data()), - licenseRequest.size()); - } - - std::vector signature(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), - signature.data(), &signature_length, kSign_RSASSA_PSS); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - count++; - } - delta_time = clock.now() - start_time; - const double license_request_time = - delta_time / std::chrono::milliseconds(1) / count; - - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); - vector session_key; - vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - s.FillDefaultContext(&mac_context, &enc_context); - - enc_session_key = wvutil::a2b_hex( - "7789c619aa3b9fa3c0a53f57a4abc6" - "02157c8aa57e3c6fb450b0bea22667fb" - "0c3200f9d9d618e397837c720dc2dadf" - "486f33590744b2a4e54ca134ae7dbf74" - "434c2fcf6b525f3e132262f05ea3b3c1" - "198595c0e52b573335b2e8a3debd0d0d" - "d0306f8fcdde4e76476be71342957251" - "e1688c9ca6c1c34ed056d3b989394160" - "cf6937e5ce4d39cc73d11a2e93da21a2" - "fa019d246c852fe960095b32f120c3c2" - "7085f7b64aac344a68d607c0768676ce" - "d4c5b2d057f7601921b453a451e1dea0" - "843ebfef628d9af2784d68e86b730476" - "e136dfe19989de4be30a4e7878efcde5" - "ad2b1254f80c0c5dd3cf111b56572217" - "b9f58fc1dacbf74b59d354a1e62cfa0e" - "bf"); - start_time = clock.now(); - while (clock.now() - start_time < kTestDuration) { - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_DeriveKeysFromSessionKey( - s.session_id(), enc_session_key.data(), - enc_session_key.size(), mac_context.data(), - mac_context.size(), enc_context.data(), enc_context.size())); - count++; - } - delta_time = clock.now() - start_time; - const double derive_keys_time = - delta_time / std::chrono::milliseconds(1) / count; - - OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); - printf( - "PERF:head, security, provision (ms), lic req(ms), derive " - "keys(ms)\n"); - printf("PERF:stat, %u, %8.3f, %8.3f, %8.3f\n", - static_cast(level), provision_time, license_request_time, - derive_keys_time); -} - // Test DeriveKeysFromSessionKey using the maximum size for the HMAC context. TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { vector session_key; diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.h b/oemcrypto/test/oemcrypto_session_tests_helper.h index 1b35239..eba241b 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.h +++ b/oemcrypto/test/oemcrypto_session_tests_helper.h @@ -44,7 +44,7 @@ class SessionUtil { // Create a new DRM Cert. Only for provisioning 4.0 void CreateProv4DRMKey(); - void CreateProv4CastKey(Session *s, bool load_drm_before_prov_req); + void CreateProv4CastKey(Session* s, bool load_drm_before_prov_req); // Used by prov2.0, prov3.0, and prov 4.0 std::vector encoded_rsa_key_; diff --git a/oemcrypto/test/oemcrypto_test.cpp b/oemcrypto/test/oemcrypto_test.cpp index 1b6d5b4..089c3b2 100644 --- a/oemcrypto/test/oemcrypto_test.cpp +++ b/oemcrypto/test/oemcrypto_test.cpp @@ -780,6 +780,9 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitlementKeyAPI17) { // This verifies that entitled key sessions can be created and removed. TEST_P(OEMCryptoLicenseTest, EntitledKeySessionsAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } license_messages_.set_license_type(OEMCrypto_EntitlementLicense); ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); diff --git a/util/include/wv_attributes.h b/util/include/wv_attributes.h index c817f1c..c890c93 100644 --- a/util/include/wv_attributes.h +++ b/util/include/wv_attributes.h @@ -13,4 +13,12 @@ # endif #endif +#ifndef WEAK +# if defined(__GNUC__) || defined(__clang__) +# define WEAK __attribute__((weak)) +# else +# define WEAK +# endif +#endif + #endif // WVCDM_UTIL_WV_ATTRIBUTES_H_ diff --git a/util/src/string_conversions.cpp b/util/src/string_conversions.cpp index 37ac2ef..0470d3a 100644 --- a/util/src/string_conversions.cpp +++ b/util/src/string_conversions.cpp @@ -32,12 +32,12 @@ const char kBase64SafeCodes[] = // Decodes a single Base64 encoded character into its 6-bit value. // The provided |codes| must be a Base64 character map. -int DecodeBase64Char(char c, const char* codes) { +int32_t DecodeBase64Char(char c, const char* codes) { const char* c_in_codes = strchr(codes, c); if (c_in_codes == nullptr) return -1; const uintptr_t c_in_codes_int = reinterpret_cast(c_in_codes); const uintptr_t codes_int = reinterpret_cast(codes); - return static_cast(c_in_codes_int - codes_int); + return static_cast(c_in_codes_int - codes_int); } bool DecodeHexChar(char ch, uint8_t* digit) { @@ -124,7 +124,7 @@ std::vector Base64DecodeInternal(const char* encoded, size_t length, break; } - const int decoded = DecodeBase64Char(encoded[i], codes); + const int32_t decoded = DecodeBase64Char(encoded[i], codes); if (decoded < 0) { LOGE("base64Decode failed"); return std::vector(); @@ -167,8 +167,8 @@ std::vector a2b_hex(const std::string& byte) { } for (size_t i = 0; i < count / 2; ++i) { - unsigned char msb = 0; // most significant 4 bits - unsigned char lsb = 0; // least significant 4 bits + uint8_t msb = 0; // most significant 4 bits + uint8_t lsb = 0; // least significant 4 bits if (!DecodeHexChar(byte[i * 2], &msb) || !DecodeHexChar(byte[i * 2 + 1], &lsb)) { LOGE("Invalid hex value %c%c at index %zu", byte[i * 2], byte[i * 2 + 1], @@ -219,7 +219,7 @@ std::string unlimited_b2a_hex(const std::string& byte) { } std::string HexEncode(const uint8_t* in_buffer, size_t size) { - constexpr unsigned int kMaxSafeSize = 2048; + constexpr size_t kMaxSafeSize = 2048; if (size > kMaxSafeSize) size = kMaxSafeSize; return UnlimitedHexEncode(in_buffer, size); } @@ -229,7 +229,7 @@ std::string UnlimitedHexEncode(const uint8_t* in_buffer, size_t size) { if (size == 0) return ""; // Each input byte creates two output hex characters. std::string out_buffer(size * 2, '\0'); - for (unsigned int i = 0; i < size; ++i) { + for (size_t i = 0; i < size; ++i) { char byte = in_buffer[i]; out_buffer[(i << 1)] = kHexChars[(byte >> 4) & 0xf]; out_buffer[(i << 1) + 1] = kHexChars[byte & 0xf]; @@ -331,7 +331,7 @@ int64_t htonll64(int64_t x) { } // Encode unsigned integer into a big endian formatted string -std::string EncodeUint32(unsigned int u) { +std::string EncodeUint32(uint32_t u) { std::string s; s.push_back((u >> 24) & 0xFF); s.push_back((u >> 16) & 0xFF);