diff --git a/CHANGELOG.md b/CHANGELOG.md index e1478c5..9d1bdf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,46 @@ [TOC] +## [Version 18.7][v18.7] + +This release adds new tests that provide stricter enforcement of the existing +OEMCrypto specification. + +This release of OPK fixes some rare but possible null dereference bugs and +improves on the Provisioning 3.0 support introduced in v18.6, including support +for OP-TEE. + +### Tests + +- Added new tests to better validate the behavior of + `OEMCrypto_BuildInformation()` + - Verifies output length is set correctly + - Verifies content is ASCII JSON without trailing null bytes + - Verifies documented JSON fields: required fields are present, and optional + and required fields are the correct JSON types +- Removed OEMCryptoLicenseTest.RejectCbc1API16 +- Fixed erroneous failures on devices with low TEE memory caused by sending an + output buffer to decrypt that was much larger than necessary + +### API + +- Added a new API for CAS: `OEMCrypto_SetSessionUsage()` +- Clarified the expected handling of the pattern (0,0) in cbcs mode. For more + information, please check the [OEMCrypto v18 Delta Document][delta-18]. + +### OPK + +- Fixed several potential null dereferences that could occur if the allocator + runs out of memory +- Fixed incorrect behavior of `OEMCrypto_RemoveEntitledKeySession()` when the + session is already closed +- Provisioning 3.0 support is now gated by a `USE_PROVISIONING_30` compiler flag + so that it can be excluded from builds on devices that do not use Provisioning + 3.0 +- Added Provisioning 3.0 support on OP-TEE + +[delta-18]: https://developers.google.com/widevine/drm/client/oemcrypto/v18/delta + ## [Version 18.6][v18.6] This patch provides provisioning 3.0 for OEMs using OPK. Also includes bug @@ -547,3 +587,4 @@ Public release for OEMCrypto API and ODK library version 16.4. [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 +[v18.7]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v18.7 diff --git a/docs/Widevine_Open_Source_License_Terms.pdf b/docs/Widevine_Open_Source_License_Terms.pdf new file mode 100644 index 0000000..eee3844 Binary files /dev/null and b/docs/Widevine_Open_Source_License_Terms.pdf differ diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index bf771c1..42184e2 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -3,7 +3,7 @@ // License Agreement. /** - * @mainpage OEMCrypto API v18.6 + * @mainpage OEMCrypto API v18.7 * * 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 @@ -721,6 +721,7 @@ typedef enum OEMCrypto_SignatureHashAlgorithm { #define OEMCrypto_UseSecondaryKey _oecc144 #define OEMCrypto_MarkOfflineSession _oecc153 #define OEMCrypto_WrapClearPrivateKey _oecc154 +#define OEMCrypto_SetSessionUsage _oecc155 // clang-format on /// @addtogroup initcontrol @@ -1941,6 +1942,33 @@ OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session, uint8_t* key_token, size_t* key_token_length); +/** + * Sets the session's usage information and scrambling mode, allowing the + * descrambler to be set up to decode one or more streams encrypted by the + * Conditional Access System (CAS). This method is currently used exclusively by + * CAS. + * + * @param[in] session: session id. + * @param[in] intent: session usage information. A constant defined by MediaCaS. + * @param[in] mode: scrambling mode. A constant defined by MediaCaS. + * + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It is as if the CDM holds a write lock for this session, + * and a read lock on the OEMCrypto system. + * + * @version + * This method is new in API version 19. + */ +OEMCryptoResult OEMCrypto_SetSessionUsage(OEMCrypto_SESSION session, + uint32_t intent, uint32_t mode); + /// @} /// @addtogroup decryption @@ -2236,10 +2264,20 @@ OEMCryptoResult OEMCrypto_GetKeyHandle(OEMCrypto_SESSION session, * usually be non-zero. This mode allows devices to decrypt FMP4 HLS content, * SAMPLE-AES HLS content, as well as content using the DASH 'cbcs' scheme. * - * The skip field of OEMCrypto_CENCEncryptPatternDesc may also be zero. If - * the skip field is zero, then patterns are not in use and all crypto blocks - * in the encrypted part of the subsample are encrypted. It is not valid for - * the encrypt field to be zero. + * The skip field of OEMCrypto_CENCEncryptPatternDesc may be zero. If the skip + * field is zero, then patterns are not in use and all crypto blocks in the + * encrypted part of the subsample are encrypted, except for any partial crypto + * blocks at the end. The most common pattern with a skip field of zero is + * (10,0), but all patterns with a skip field of zero are functionally the same. + * + * If the skip field of OEMCrypto_CENCEncryptPatternDesc is zero, the encrypt + * field may also be zero. This pattern sometimes appears in content, + * particularly in audio tracks. This (0,0) pattern should be treated as + * equivalent to the pattern (10,0). e.g. All complete crypto blocks should be + * decrypted. + * + * It is not valid for the encrypt field of OEMCrypto_CENCEncryptPatternDesc to + * be zero if the skip field is non-zero. * * The length of a crypto block in AES-128 is 16 bytes. In the 'cbcs' scheme, * if the encrypted part of a subsample has a length that is not a multiple diff --git a/oemcrypto/include/level3.h b/oemcrypto/include/level3.h index ab32177..3085523 100644 --- a/oemcrypto/include/level3.h +++ b/oemcrypto/include/level3.h @@ -120,6 +120,8 @@ #define Level3_UseSecondaryKey _lcc142 #define Level3_GetEmbeddedDrmCertificate _lcc143 #define Level3_MarkOfflineSession _lcc144 +// Added in OEMCrypto v19.3, but back ported to v18 +#define Level3_SetSessionUsage _lcc155 #else #define Level3_Initialize _oecc01 #define Level3_Terminate _oecc02 @@ -224,6 +226,8 @@ #define Level3_GetEmbeddedDrmCertificate _oecc143 #define Level3_UseSecondaryKey _oecc144 #define Level3_MarkOfflineSession _oecc145 +// Added in OEMCrypto v19.3, but back ported to v18 +#define Level3_SetSessionUsage _oecc155 #endif #define Level3_GetInitializationState _oecl3o01 @@ -448,6 +452,8 @@ OEMCrypto_WatermarkingSupport Level3_GetWatermarkingSupport(); OEMCryptoResult Level3_GetOEMKeyToken(OEMCrypto_SESSION key_session, uint8_t* key_token, size_t* key_token_length); +OEMCryptoResult Level3_SetSessionUsage(OEMCrypto_SESSION session, + uint32_t intent, uint32_t mode); OEMCryptoResult Level3_GetDeviceInformation(uint8_t* device_info, size_t* device_info_length); OEMCryptoResult Level3_GetDeviceSignedCsrPayload( @@ -497,7 +503,7 @@ OEMCryptoResult Level3_GetSignatureHashAlgorithm( OEMCrypto_SESSION session, OEMCrypto_SignatureHashAlgorithm* algorithm); OEMCryptoResult Level3_EnterTestMode(void); OEMCryptoResult Level3_GetEmbeddedDrmCertificate(uint8_t* public_cert, - size_t* public_cert_length); + size_t* public_cert_length); OEMCryptoResult Level3_UseSecondaryKey(OEMCrypto_SESSION session_id, bool dual_key); OEMCryptoResult Level3_MarkOfflineSession(OEMCrypto_SESSION session_id); diff --git a/oemcrypto/odk/include/core_message_features.h b/oemcrypto/odk/include/core_message_features.h index 5fd71c3..3779f02 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.6. + // number. The default is 18.7. uint32_t maximum_major_version = 18; - uint32_t maximum_minor_version = 6; + uint32_t maximum_minor_version = 7; 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 12f9723..cabe6f0 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 6 +#define ODK_MINOR_VERSION 7 /* ODK Version string. Date changed automatically on each release. */ -#define ODK_RELEASE_DATE "ODK v18.6 2024-06-04" +#define ODK_RELEASE_DATE "ODK v18.7 2024-09-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 f312583..e9e075c 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 = 6; // 18.6 + features.maximum_minor_version = 7; // 18.7 break; default: features.maximum_minor_version = 0; diff --git a/oemcrypto/odk/src/odk_timer.c b/oemcrypto/odk/src/odk_timer.c index 934717f..b79ac05 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 = 6; + nonce_values->api_minor_version = 7; 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 118077e..fe172bd 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, 6}, + {18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 7}, // 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}, @@ -1229,6 +1229,7 @@ std::vector TestCases() { {ODK_MAJOR_VERSION, 18, 4, 18, 4}, {ODK_MAJOR_VERSION, 18, 5, 18, 5}, {ODK_MAJOR_VERSION, 18, 6, 18, 6}, + {ODK_MAJOR_VERSION, 18, 7, 18, 7}, {0, 16, 3, 16, 3}, {0, 16, 4, 16, 4}, {0, 16, 5, 16, 5}, @@ -1237,6 +1238,7 @@ std::vector TestCases() { {0, 18, 4, 18, 4}, {0, 18, 5, 18, 5}, {0, 18, 6, 18, 6}, + {0, 18, 7, 18, 7}, }; return test_cases; } diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto.c b/oemcrypto/opk/oemcrypto_ta/oemcrypto.c index 7fd9935..a3c83e3 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto.c +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto.c @@ -4306,6 +4306,13 @@ OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session UNUSED, } #endif +// CAS only, currently not implemented +OEMCryptoResult OEMCrypto_SetSessionUsage(OEMCrypto_SESSION session UNUSED, + uint32_t intent UNUSED, + uint32_t mode UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + OEMCryptoResult OEMCrypto_GetEmbeddedDrmCertificate( uint8_t* public_cert UNUSED, size_t* public_cert_length UNUSED) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h index 26898fe..afdf953 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 6 +#define API_MINOR_VERSION 7 #define OPK_PATCH_VERSION 0 #endif /* OEMCRYPTO_TA_OEMCRYPTO_API_MACROS_H_ */ diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/README.md b/oemcrypto/opk/oemcrypto_ta/wtpi/README.md index 1aaa299..066082d 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/README.md +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/README.md @@ -31,6 +31,7 @@ WTPI interfaces that are currently covered by wtpi_test: * wtpi_crypto_and_key_management_interface_layer1.h, * wtpi_crypto_asymmetric_interface.h, * wtpi_crc32_interface.h, +* wtpi_provisioning_4_interface.h, Please be cautious when updating parameter names in these interfaces. It can potentially break the auto-generated serialization functions used by the WTPI 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 2463edd..e4e564d 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_crypto_asymmetric_interface.h @@ -327,22 +327,6 @@ 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_root_of_trust_interface_layer1.h b/oemcrypto/opk/oemcrypto_ta/wtpi/wtpi_root_of_trust_interface_layer1.h index b36406f..491150b 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 @@ -17,7 +17,8 @@ extern "C" { #endif /** @defgroup layer1-rot Layer 1 Root Of Trust - * Keybox access functions called directly by OPK code. + * Keybox(Provisioning 2.0) or OEMCertificate(Provisioning 3.0) access + * functions called directly by OPK code. * * This is the top layer of the porting layer. The OPK directly calls * functions in this file. Partners have the option to implement these functions @@ -179,8 +180,7 @@ OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, * @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_INVALID_KEY if the OEM private key is not valid * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE otherwise */ OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert( @@ -211,9 +211,8 @@ OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, * 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_INVALID_CONTEXT if the OEM cert is not valid + * @retval 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); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c index b9d5a4c..9e40578 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/prov30_factory_util.c @@ -24,6 +24,8 @@ Input format for |certs_and_key|: +-----------------------+----------------------+--------------------------+ | Private Key | +-----------------------+ +| (DER-encoded PKCS#8) | ++-----------------------+ */ OEMCryptoResult ParseCertificateChainAndKey(const uint8_t* certs_and_key, size_t certs_and_key_length, diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp index 7886a09..41d9b97 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/wtpi_reference.gyp @@ -6,6 +6,7 @@ 'variables': { # TODO(b/207176111): add test scripts to cover both reference crypto impl 'reference_crypto_impl%': 'software', + 'use_provisioning_30%': 'none', 'test_renewal%': 0, }, 'includes': [ @@ -117,7 +118,6 @@ 'device_key_util.c', 'cose_util.c', 'ecc_util.c', - 'prov30_factory_util.c', 'rsa_util.c', 'wtpi_crc32.c', 'wtpi_crypto_asymmetric.c', @@ -135,6 +135,11 @@ 'wtpi_crypto_and_key_management_layer1_openssl.c', ], }], + ['use_provisioning_30', { + 'sources': [ + 'prov30_factory_util.c', + ], + }], ], 'variables': { # Needed for BoringSSL dependency build files. These SHOULD already be 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 7a8fa70..939514c 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 @@ -16,7 +16,9 @@ #include "odk_endian.h" #include "oemcrypto_compiler_attributes.h" #include "oemcrypto_key_types.h" -#include "prov30_factory_util.h" +#ifdef USE_PROVISIONING_30 +# include "prov30_factory_util.h" +#endif #include "renewal_util.h" #include "wtpi_abort_interface.h" #include "wtpi_config_interface.h" @@ -236,6 +238,7 @@ static OEMCryptoResult GetProv4DeviceID(uint8_t* device_id, return result; } +#ifdef USE_PROVISIONING_30 static OEMCryptoResult GetProv3DeviceID(uint8_t* device_id, size_t device_id_length) { if (device_id == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -253,6 +256,7 @@ static OEMCryptoResult GetProv3DeviceID(uint8_t* device_id, WTPI_C1_SHA256(public_cert_buffer, public_cert_buffer_size, device_id); return result; } +#endif OEMCryptoResult WTPI_GetDeviceID(uint8_t* device_id, size_t device_id_length) { if (device_id == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -262,10 +266,11 @@ OEMCryptoResult WTPI_GetDeviceID(uint8_t* device_id, size_t device_id_length) { if (provisioning_method == OEMCrypto_BootCertificateChain) { return GetProv4DeviceID(device_id, device_id_length); } +#ifdef USE_PROVISIONING_30 if (provisioning_method == OEMCrypto_OEMCertificate) { return GetProv3DeviceID(device_id, device_id_length); } - +#endif if (provisioning_method != OEMCrypto_Keybox) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } @@ -338,6 +343,7 @@ OEMCryptoResult WTPI_K1_CreateKeyHandleFromKeybox( } } +#ifdef USE_PROVISIONING_30 // Load Provisioning 3.0 OEM private key to output buffer static OEMCryptoResult LoadOEMPrivateKey(uint8_t* output, size_t* output_length) { @@ -350,10 +356,12 @@ static OEMCryptoResult LoadOEMPrivateKey(uint8_t* output, } return WTPI_LoadOEMPrivateKey30(output, output_length); } +#endif OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, uint8_t* wrapped_cert, size_t* wrapped_cert_length) { +#ifdef USE_PROVISIONING_30 if (input == NULL || input_length == 0 || wrapped_cert_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -372,10 +380,18 @@ OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, *wrapped_cert_length = required_size; return WTPI_WrapRootOfTrust30(input, input_length, wrapped_cert, wrapped_cert_length); +#else + (void)input; + (void)input_length; + (void)wrapped_cert; + (void)wrapped_cert_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert(const uint8_t* input, size_t input_length) { +#ifdef USE_PROVISIONING_30 if (input == NULL || input_length == 0) { return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -408,10 +424,16 @@ OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert(const uint8_t* input, return result; } return WTPI_SaveOEMPublicCertificate30(cert_chain, cert_chain_length); +#else + (void)input; + (void)input_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, size_t* output_length) { +#ifdef USE_PROVISIONING_30 if (output_length == NULL) { return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -420,9 +442,15 @@ OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, return OEMCrypto_ERROR_SHORT_BUFFER; } return WTPI_LoadOEMPublicCertificate30(output, output_length); +#else + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_ValidateOEMCertAndKey(void) { +#ifdef USE_PROVISIONING_30 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 = @@ -434,10 +462,14 @@ OEMCryptoResult WTPI_ValidateOEMCertAndKey(void) { if (result != OEMCrypto_SUCCESS) return result; return ValidateCertificateChainAndKey(cert_chain, cert_chain_length, private_key, private_key_length); +#else + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( WTPI_AsymmetricKey_Handle* key_handle) { +#ifdef USE_PROVISIONING_30 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); @@ -457,4 +489,8 @@ OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( } memset(oem_key, 0, sizeof(oem_key)); return OEMCrypto_SUCCESS; +#else + (void)key_handle; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } 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 b62a8a2..367d025 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 @@ -1225,40 +1225,6 @@ 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; 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 ee162ee..39b0e41 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 @@ -1250,45 +1250,9 @@ 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 = 10035; /* from _tee10035 */ + 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); @@ -1306,7 +1270,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 != 10035) + if (api_value != 10034) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -1329,7 +1293,7 @@ void OPK_Unpack_GetBootCertificateChain_Response(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBootCertificateChainSize_Request( const size_t* out_length) { - uint32_t api_value = 10036; /* from _tee10036 */ + 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); @@ -1345,7 +1309,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 != 10036) + if (api_value != 10035) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1368,7 +1332,7 @@ ODK_Message OPK_Pack_GenerateRandomCertificateKeyPair_Request( 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 = 10037; /* from _tee10037 */ + 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); @@ -1390,7 +1354,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 != 10037) + if (api_value != 10036) 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); @@ -1430,7 +1394,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 = 10038; /* from _tee10038 */ + 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); @@ -1453,7 +1417,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 != 10038) + if (api_value != 10037) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, signed_csr_payload_length); OPK_Unpack_uint32_t(msg, result); @@ -1476,7 +1440,7 @@ void OPK_Unpack_GetSignedCsrPayload_Response( } ODK_Message OPK_Pack_MaxDeviceInfoSize_Request(void) { - uint32_t api_value = 10039; /* from _tee10039 */ + 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); @@ -1489,7 +1453,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 != 10039) + if (api_value != 10038) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -1498,7 +1462,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 = 10040; /* from _tee10040 */ + 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); @@ -1516,7 +1480,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 != 10040) + if (api_value != 10039) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -1541,7 +1505,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 = 10041; /* from _tee10041 */ + 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); @@ -1562,7 +1526,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 != 10041) + if (api_value != 10040) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, signature_length); OPK_Unpack_uint32_t(msg, result); @@ -1585,7 +1549,7 @@ void OPK_Unpack_BccKeyCoseSign1_Response(ODK_Message* msg, ODK_Message OPK_Pack_GetMaxBccKeyCoseSign1Size_Request( const size_t* out_length) { - uint32_t api_value = 10042; /* from _tee10042 */ + 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); @@ -1601,7 +1565,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 != 10042) + if (api_value != 10041) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1620,7 +1584,7 @@ void OPK_Unpack_GetMaxBccKeyCoseSign1Size_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetDeviceFusedStatus_Request(const bool* is_fused) { - uint32_t api_value = 10043; /* from _tee10043 */ + 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); @@ -1636,7 +1600,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 != 10043) + if (api_value != 10042) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1655,7 +1619,7 @@ void OPK_Unpack_GetDeviceFusedStatus_Response(ODK_Message* msg, } ODK_Message OPK_Pack_Crc32Init_Request(const uint32_t* initial_hash) { - uint32_t api_value = 10044; /* from _tee10044 */ + 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); @@ -1670,7 +1634,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 != 10044) + if (api_value != 10043) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1691,7 +1655,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 = 10045; /* from _tee10045 */ + 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); @@ -1709,7 +1673,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 != 10045) + if (api_value != 10044) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1732,7 +1696,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 = 10046; /* from _tee10046 */ + 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); @@ -1764,7 +1728,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 != 10046) + if (api_value != 10045) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1783,7 +1747,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 = 10047; /* from _tee10047 */ + 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); @@ -1799,7 +1763,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 != 10047) + if (api_value != 10046) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -1818,7 +1782,7 @@ void OPK_Unpack_GetTrustedTime_Response(ODK_Message* msg, } ODK_Message OPK_Pack_InitializeClock_Request(void) { - uint32_t api_value = 10048; /* from _tee10048 */ + 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); @@ -1832,6 +1796,34 @@ 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); @@ -1845,36 +1837,8 @@ void OPK_Unpack_InitializeClock_Response(ODK_Message* msg, } } -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); - 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 != 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 */ + uint32_t api_value = 10049; /* from _tee10049 */ ODK_Message msg = TOS_Transport_GetRequest(); OPK_Pack_uint32_t(&msg, &api_value); uint64_t timestamp = time(0); @@ -1888,7 +1852,7 @@ 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 != 10050) + if (api_value != 10049) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_Clock_Security_Level(msg, result); OPK_UnpackEOM(msg); @@ -1896,7 +1860,7 @@ void OPK_Unpack_GetClockType_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetSecurityLevel_Request(void) { - uint32_t api_value = 10051; /* from _tee10051 */ + 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); @@ -1910,7 +1874,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 != 10051) + if (api_value != 10050) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_Security_Level(msg, result); OPK_UnpackEOM(msg); @@ -1918,7 +1882,7 @@ void OPK_Unpack_GetSecurityLevel_Response(ODK_Message* msg, } ODK_Message OPK_Pack_GetProvisioningMethod_Request(void) { - uint32_t api_value = 10052; /* from _tee10052 */ + 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); @@ -1932,7 +1896,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 != 10052) + if (api_value != 10051) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_ProvisioningMethod(msg, result); OPK_UnpackEOM(msg); @@ -1940,7 +1904,7 @@ void OPK_Unpack_GetProvisioningMethod_Response( } ODK_Message OPK_Pack_GetResourceRatingTier_Request(void) { - uint32_t api_value = 10053; /* from _tee10053 */ + 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); @@ -1954,7 +1918,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 != 10053) + if (api_value != 10052) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); OPK_UnpackEOM(msg); @@ -1962,7 +1926,7 @@ void OPK_Unpack_GetResourceRatingTier_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsTAAntiRollbackEnabled_Request(void) { - uint32_t api_value = 10054; /* from _tee10054 */ + 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); @@ -1976,7 +1940,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 != 10054) + if (api_value != 10053) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OPK_FeatureStatus(*result)) { @@ -1987,7 +1951,7 @@ void OPK_Unpack_IsTAAntiRollbackEnabled_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsProductionReady_Request(void) { - uint32_t api_value = 10055; /* from _tee10055 */ + 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); @@ -2000,7 +1964,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 != 10055) + if (api_value != 10054) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2008,7 +1972,7 @@ void OPK_Unpack_IsProductionReady_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_GetWatermarkingSupport_Request(void) { - uint32_t api_value = 10056; /* from _tee10056 */ + 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); @@ -2022,7 +1986,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 != 10056) + if (api_value != 10055) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_WatermarkingSupport(msg, result); OPK_UnpackEOM(msg); @@ -2030,7 +1994,7 @@ void OPK_Unpack_GetWatermarkingSupport_Response( } ODK_Message OPK_Pack_GetCurrentSRMVersion_Request(const uint32_t* srm_version) { - uint32_t api_value = 10057; /* from _tee10057 */ + 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); @@ -2046,7 +2010,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 != 10057) + if (api_value != 10056) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -2065,7 +2029,7 @@ void OPK_Unpack_GetCurrentSRMVersion_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsAntiRollbackHWPresent_Request(void) { - uint32_t api_value = 10058; /* from _tee10058 */ + 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); @@ -2079,7 +2043,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 != 10058) + if (api_value != 10057) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2087,7 +2051,7 @@ void OPK_Unpack_IsAntiRollbackHWPresent_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsCGMS_AActive_Request(void) { - uint32_t api_value = 10059; /* from _tee10059 */ + 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); @@ -2100,7 +2064,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 != 10059) + if (api_value != 10058) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2108,7 +2072,7 @@ void OPK_Unpack_IsCGMS_AActive_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_SupportsCGMS_A_Request(void) { - uint32_t api_value = 10060; /* from _tee10060 */ + 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); @@ -2121,7 +2085,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 != 10060) + if (api_value != 10059) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2129,7 +2093,7 @@ void OPK_Unpack_SupportsCGMS_A_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_HasAnalogDisplay_Request(void) { - uint32_t api_value = 10061; /* from _tee10061 */ + 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); @@ -2142,7 +2106,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 != 10061) + if (api_value != 10060) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2150,7 +2114,7 @@ void OPK_Unpack_HasAnalogDisplay_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_IsAnalogDisplayActive_Request(void) { - uint32_t api_value = 10062; /* from _tee10062 */ + 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); @@ -2163,7 +2127,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 != 10062) + if (api_value != 10061) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2171,7 +2135,7 @@ void OPK_Unpack_IsAnalogDisplayActive_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_CanDisableAnalogDisplay_Request(void) { - uint32_t api_value = 10063; /* from _tee10063 */ + 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); @@ -2185,7 +2149,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 != 10063) + if (api_value != 10062) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2193,7 +2157,7 @@ void OPK_Unpack_CanDisableAnalogDisplay_Response(ODK_Message* msg, } ODK_Message OPK_Pack_DisableAnalogDisplay_Request(void) { - uint32_t api_value = 10064; /* from _tee10064 */ + 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); @@ -2206,7 +2170,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 != 10064) + if (api_value != 10063) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2214,7 +2178,7 @@ void OPK_Unpack_DisableAnalogDisplay_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_MaxOutputSizeForDecrypt_Request(void) { - uint32_t api_value = 10065; /* from _tee10065 */ + 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); @@ -2228,7 +2192,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 != 10065) + if (api_value != 10064) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2236,7 +2200,7 @@ void OPK_Unpack_MaxOutputSizeForDecrypt_Response(ODK_Message* msg, } ODK_Message OPK_Pack_IsClosedPlatform_Request(void) { - uint32_t api_value = 10066; /* from _tee10066 */ + 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); @@ -2249,7 +2213,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 != 10066) + if (api_value != 10065) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2257,7 +2221,7 @@ void OPK_Unpack_IsClosedPlatform_Response(ODK_Message* msg, bool* result) { } ODK_Message OPK_Pack_CurrentHDCPCapability_Request(void) { - uint32_t api_value = 10067; /* from _tee10067 */ + 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); @@ -2271,7 +2235,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 != 10067) + if (api_value != 10066) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_HDCP_Capability(msg, result); OPK_UnpackEOM(msg); @@ -2279,7 +2243,7 @@ void OPK_Unpack_CurrentHDCPCapability_Response( } ODK_Message OPK_Pack_MaxHDCPCapability_Request(void) { - uint32_t api_value = 10068; /* from _tee10068 */ + 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); @@ -2293,7 +2257,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 != 10068) + if (api_value != 10067) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_OEMCrypto_HDCP_Capability(msg, result); OPK_UnpackEOM(msg); @@ -2301,7 +2265,7 @@ void OPK_Unpack_MaxHDCPCapability_Response(ODK_Message* msg, } ODK_Message OPK_Pack_MaxBufferSizeForGenericCrypto_Request(void) { - uint32_t api_value = 10069; /* from _tee10069 */ + 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); @@ -2315,7 +2279,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 != 10069) + if (api_value != 10068) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2323,7 +2287,7 @@ void OPK_Unpack_MaxBufferSizeForGenericCrypto_Response(ODK_Message* msg, } ODK_Message OPK_Pack_MaxSampleSize_Request(void) { - uint32_t api_value = 10070; /* from _tee10070 */ + 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); @@ -2336,7 +2300,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 != 10070) + if (api_value != 10069) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_size_t(msg, result); OPK_UnpackEOM(msg); @@ -2344,7 +2308,7 @@ void OPK_Unpack_MaxSampleSize_Response(ODK_Message* msg, size_t* result) { } ODK_Message OPK_Pack_SupportedCertificates_Request(void) { - uint32_t api_value = 10071; /* from _tee10071 */ + 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); @@ -2358,7 +2322,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 != 10071) + if (api_value != 10070) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); OPK_UnpackEOM(msg); @@ -2366,7 +2330,7 @@ void OPK_Unpack_SupportedCertificates_Response(ODK_Message* msg, } ODK_Message OPK_Pack_ContentDecryptBypassesTA_Request(void) { - uint32_t api_value = 10072; /* from _tee10072 */ + 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); @@ -2380,7 +2344,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 != 10072) + if (api_value != 10071) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_bool(msg, result); OPK_UnpackEOM(msg); @@ -2389,7 +2353,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 = 10073; /* from _tee10073 */ + 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); @@ -2407,7 +2371,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 != 10073) + if (api_value != 10072) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_Unpack_uint32_t(msg, result); if (!Is_Valid_OEMCryptoResult(*result)) { @@ -2430,7 +2394,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 = 10074; /* from _tee10074 */ + 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); @@ -2450,7 +2414,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 != 10074) + if (api_value != 10073) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); OPK_UnpackNullable_size_t(msg, out_length); OPK_Unpack_uint32_t(msg, result); @@ -2476,7 +2440,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 = 10075; /* from _tee10075 */ + 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); @@ -2497,7 +2461,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 != 10075) + 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); @@ -2521,7 +2485,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 = 10076; /* from _tee10076 */ + 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); @@ -2541,7 +2505,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 != 10076) + if (api_value != 10075) 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 ab40914..194670c 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 @@ -205,11 +205,6 @@ 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, 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 6f7ccb1..42618bb 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/tee/GEN_dispatcher.c @@ -804,22 +804,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetSignatureHashAlgorithm_Response(result, hash_algorithm); break; } - 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 */ + case 10034: /* WTPI_GetBootCertificateChain */ { size_t* out_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(out_length); @@ -835,7 +820,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetBootCertificateChain_Response(result, out, out_length); break; } - case 10036: /* WTPI_GetMaxBootCertificateChainSize */ + case 10035: /* WTPI_GetMaxBootCertificateChainSize */ { size_t* out_length; OPK_InitPointer((uint8_t**)&out_length); @@ -849,7 +834,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetMaxBootCertificateChainSize_Response(result, out_length); break; } - case 10037: /* WTPI_GenerateRandomCertificateKeyPair */ + case 10036: /* WTPI_GenerateRandomCertificateKeyPair */ { size_t* wrapped_private_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); @@ -879,7 +864,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, public_key, public_key_length); break; } - case 10038: /* WTPI_GetSignedCsrPayload */ + case 10037: /* WTPI_GetSignedCsrPayload */ { size_t challenge_length; OPK_Init_size_t((size_t*)&challenge_length); @@ -909,7 +894,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, result, signed_csr_payload, signed_csr_payload_length); break; } - case 10039: /* WTPI_MaxDeviceInfoSize */ + case 10038: /* WTPI_MaxDeviceInfoSize */ { OPK_Unpack_MaxDeviceInfoSize_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -920,7 +905,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxDeviceInfoSize_Response(result); break; } - case 10040: /* WTPI_GetDeviceInformation */ + case 10039: /* WTPI_GetDeviceInformation */ { size_t* out_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); OPK_Init_size_t(out_length); @@ -936,7 +921,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetDeviceInformation_Response(result, out, out_length); break; } - case 10041: /* WTPI_BccKeyCoseSign1 */ + case 10040: /* WTPI_BccKeyCoseSign1 */ { size_t message_length; OPK_Init_size_t((size_t*)&message_length); @@ -958,7 +943,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, signature_length); break; } - case 10042: /* WTPI_GetMaxBccKeyCoseSign1Size */ + case 10041: /* WTPI_GetMaxBccKeyCoseSign1Size */ { size_t* out_length; OPK_InitPointer((uint8_t**)&out_length); @@ -972,7 +957,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetMaxBccKeyCoseSign1Size_Response(result, out_length); break; } - case 10043: /* WTPI_GetDeviceFusedStatus */ + case 10042: /* WTPI_GetDeviceFusedStatus */ { bool* is_fused; OPK_InitPointer((uint8_t**)&is_fused); @@ -985,7 +970,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetDeviceFusedStatus_Response(result, is_fused); break; } - case 10044: /* WTPI_Crc32Init */ + case 10043: /* WTPI_Crc32Init */ { uint32_t* initial_hash; OPK_InitPointer((uint8_t**)&initial_hash); @@ -998,7 +983,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Init_Response(result, initial_hash); break; } - case 10045: /* WTPI_Crc32Cont */ + case 10044: /* WTPI_Crc32Cont */ { size_t in_length; OPK_Init_size_t((size_t*)&in_length); @@ -1018,7 +1003,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Cont_Response(result, new_crc); break; } - case 10046: /* WTPI_Crc32Cont_OutputBuffer */ + case 10045: /* WTPI_Crc32Cont_OutputBuffer */ { size_t in_length; OPK_Init_size_t((size_t*)&in_length); @@ -1041,7 +1026,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_Crc32Cont_OutputBuffer_Response(result, new_crc); break; } - case 10047: /* WTPI_GetTrustedTime */ + case 10046: /* WTPI_GetTrustedTime */ { uint64_t* time_in_s; OPK_InitPointer((uint8_t**)&time_in_s); @@ -1054,7 +1039,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetTrustedTime_Response(result, time_in_s); break; } - case 10048: /* WTPI_InitializeClock */ + case 10047: /* WTPI_InitializeClock */ { OPK_Unpack_InitializeClock_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1065,7 +1050,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_InitializeClock_Response(result); break; } - case 10049: /* WTPI_TerminateClock */ + case 10048: /* WTPI_TerminateClock */ { OPK_Unpack_TerminateClock_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1076,7 +1061,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_TerminateClock_Response(result); break; } - case 10050: /* WTPI_GetClockType */ + case 10049: /* WTPI_GetClockType */ { OPK_Unpack_GetClockType_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1088,7 +1073,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetClockType_Response(result); break; } - case 10051: /* WTPI_GetSecurityLevel */ + case 10050: /* WTPI_GetSecurityLevel */ { OPK_Unpack_GetSecurityLevel_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1099,7 +1084,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetSecurityLevel_Response(result); break; } - case 10052: /* WTPI_GetProvisioningMethod */ + case 10051: /* WTPI_GetProvisioningMethod */ { OPK_Unpack_GetProvisioningMethod_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1111,7 +1096,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetProvisioningMethod_Response(result); break; } - case 10053: /* WTPI_GetResourceRatingTier */ + case 10052: /* WTPI_GetResourceRatingTier */ { OPK_Unpack_GetResourceRatingTier_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1122,7 +1107,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetResourceRatingTier_Response(result); break; } - case 10054: /* WTPI_IsTAAntiRollbackEnabled */ + case 10053: /* WTPI_IsTAAntiRollbackEnabled */ { OPK_Unpack_IsTAAntiRollbackEnabled_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1133,7 +1118,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsTAAntiRollbackEnabled_Response(result); break; } - case 10055: /* WTPI_IsProductionReady */ + case 10054: /* WTPI_IsProductionReady */ { OPK_Unpack_IsProductionReady_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1144,7 +1129,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsProductionReady_Response(result); break; } - case 10056: /* WTPI_GetWatermarkingSupport */ + case 10055: /* WTPI_GetWatermarkingSupport */ { OPK_Unpack_GetWatermarkingSupport_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1156,7 +1141,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetWatermarkingSupport_Response(result); break; } - case 10057: /* WTPI_GetCurrentSRMVersion */ + case 10056: /* WTPI_GetCurrentSRMVersion */ { uint32_t* srm_version; OPK_InitPointer((uint8_t**)&srm_version); @@ -1169,7 +1154,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_GetCurrentSRMVersion_Response(result, srm_version); break; } - case 10058: /* WTPI_IsAntiRollbackHWPresent */ + case 10057: /* WTPI_IsAntiRollbackHWPresent */ { OPK_Unpack_IsAntiRollbackHWPresent_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1180,7 +1165,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsAntiRollbackHWPresent_Response(result); break; } - case 10059: /* WTPI_IsCGMS_AActive */ + case 10058: /* WTPI_IsCGMS_AActive */ { OPK_Unpack_IsCGMS_AActive_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1191,7 +1176,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsCGMS_AActive_Response(result); break; } - case 10060: /* WTPI_SupportsCGMS_A */ + case 10059: /* WTPI_SupportsCGMS_A */ { OPK_Unpack_SupportsCGMS_A_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1202,7 +1187,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_SupportsCGMS_A_Response(result); break; } - case 10061: /* WTPI_HasAnalogDisplay */ + case 10060: /* WTPI_HasAnalogDisplay */ { OPK_Unpack_HasAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1213,7 +1198,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_HasAnalogDisplay_Response(result); break; } - case 10062: /* WTPI_IsAnalogDisplayActive */ + case 10061: /* WTPI_IsAnalogDisplayActive */ { OPK_Unpack_IsAnalogDisplayActive_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1224,7 +1209,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsAnalogDisplayActive_Response(result); break; } - case 10063: /* WTPI_CanDisableAnalogDisplay */ + case 10062: /* WTPI_CanDisableAnalogDisplay */ { OPK_Unpack_CanDisableAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1235,7 +1220,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_CanDisableAnalogDisplay_Response(result); break; } - case 10064: /* WTPI_DisableAnalogDisplay */ + case 10063: /* WTPI_DisableAnalogDisplay */ { OPK_Unpack_DisableAnalogDisplay_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1246,7 +1231,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_DisableAnalogDisplay_Response(result); break; } - case 10065: /* WTPI_MaxOutputSizeForDecrypt */ + case 10064: /* WTPI_MaxOutputSizeForDecrypt */ { OPK_Unpack_MaxOutputSizeForDecrypt_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1257,7 +1242,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxOutputSizeForDecrypt_Response(result); break; } - case 10066: /* WTPI_IsClosedPlatform */ + case 10065: /* WTPI_IsClosedPlatform */ { OPK_Unpack_IsClosedPlatform_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1268,7 +1253,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_IsClosedPlatform_Response(result); break; } - case 10067: /* WTPI_CurrentHDCPCapability */ + case 10066: /* WTPI_CurrentHDCPCapability */ { OPK_Unpack_CurrentHDCPCapability_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1279,7 +1264,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_CurrentHDCPCapability_Response(result); break; } - case 10068: /* WTPI_MaxHDCPCapability */ + case 10067: /* WTPI_MaxHDCPCapability */ { OPK_Unpack_MaxHDCPCapability_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1290,7 +1275,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxHDCPCapability_Response(result); break; } - case 10069: /* WTPI_MaxBufferSizeForGenericCrypto */ + case 10068: /* WTPI_MaxBufferSizeForGenericCrypto */ { OPK_Unpack_MaxBufferSizeForGenericCrypto_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1301,7 +1286,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxBufferSizeForGenericCrypto_Response(result); break; } - case 10070: /* WTPI_MaxSampleSize */ + case 10069: /* WTPI_MaxSampleSize */ { OPK_Unpack_MaxSampleSize_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1312,7 +1297,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_MaxSampleSize_Response(result); break; } - case 10071: /* WTPI_SupportedCertificates */ + case 10070: /* WTPI_SupportedCertificates */ { OPK_Unpack_SupportedCertificates_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1323,7 +1308,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_SupportedCertificates_Response(result); break; } - case 10072: /* WTPI_ContentDecryptBypassesTA */ + case 10071: /* WTPI_ContentDecryptBypassesTA */ { OPK_Unpack_ContentDecryptBypassesTA_Request(request); if (!ODK_Message_IsValid(request)) goto handle_invalid_request; @@ -1334,7 +1319,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_ContentDecryptBypassesTA_Response(result); break; } - case 10073: /* WTPI_GetEncryptAndSignSize */ + case 10072: /* WTPI_GetEncryptAndSignSize */ { uint32_t context; OPK_Init_uint32_t((uint32_t*)&context); @@ -1353,7 +1338,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetEncryptAndSignSize_Response(result, wrapped_length); break; } - case 10074: /* WTPI_EncryptAndSign */ + case 10073: /* WTPI_EncryptAndSign */ { size_t data_length; OPK_Init_size_t((size_t*)&data_length); @@ -1375,7 +1360,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_EncryptAndSign_Response(result, out, out_length); break; } - case 10075: /* WTPI_VerifyAndDecrypt */ + case 10074: /* WTPI_VerifyAndDecrypt */ { size_t wrapped_length; OPK_Init_size_t((size_t*)&wrapped_length); @@ -1398,7 +1383,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, *response = OPK_Pack_VerifyAndDecrypt_Response(result, out, out_length); break; } - case 10076: /* WTPI_VerifyAndDecryptUsageData_Legacy */ + case 10075: /* 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 3caf4f5..2444eec 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 @@ -975,37 +975,11 @@ 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 != 10035) + if (api_value != 10034) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1018,7 +992,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 = 10035; /* from _tee10035 */ + uint32_t api_value = 10034; /* from _tee10034 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -1035,7 +1009,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 != 10036) + if (api_value != 10035) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1046,7 +1020,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 = 10036; /* from _tee10036 */ + uint32_t api_value = 10035; /* from _tee10035 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1063,7 +1037,7 @@ void OPK_Unpack_GenerateRandomCertificateKeyPair_Request( size_t** public_key_length) { uint32_t api_value = UINT32_MAX; OPK_Unpack_uint32_t(msg, &api_value); - if (api_value != 10037) + if (api_value != 10036) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1085,7 +1059,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 = 10037; /* from _tee10037 */ + uint32_t api_value = 10036; /* from _tee10036 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, wrapped_private_key_length); @@ -1111,7 +1085,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 != 10038) + if (api_value != 10037) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1131,7 +1105,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 = 10038; /* from _tee10038 */ + 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, signed_csr_payload_length); @@ -1148,7 +1122,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 != 10039) + if (api_value != 10038) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1157,7 +1131,7 @@ void OPK_Unpack_MaxDeviceInfoSize_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxDeviceInfoSize_Response(size_t result) { - uint32_t api_value = 10039; /* from _tee10039 */ + uint32_t api_value = 10038; /* from _tee10038 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1170,7 +1144,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 != 10040) + if (api_value != 10039) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1184,7 +1158,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 = 10040; /* from _tee10040 */ + uint32_t api_value = 10039; /* from _tee10039 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -1203,7 +1177,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 != 10041) + if (api_value != 10040) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1219,7 +1193,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 = 10041; /* from _tee10041 */ + 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, signature_length); @@ -1237,7 +1211,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 != 10042) + if (api_value != 10041) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1248,7 +1222,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 = 10042; /* from _tee10042 */ + uint32_t api_value = 10041; /* from _tee10041 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1262,7 +1236,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 != 10043) + if (api_value != 10042) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1273,7 +1247,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 = 10043; /* from _tee10043 */ + 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); @@ -1286,7 +1260,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 != 10044) + if (api_value != 10043) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1297,7 +1271,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 = 10044; /* from _tee10044 */ + 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); @@ -1312,7 +1286,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 != 10045) + if (api_value != 10044) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1326,7 +1300,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 = 10045; /* from _tee10045 */ + 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); @@ -1341,7 +1315,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 != 10046) + if (api_value != 10045) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1382,7 +1356,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 = 10046; /* from _tee10046 */ + 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); @@ -1395,7 +1369,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 != 10047) + if (api_value != 10046) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1406,7 +1380,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 = 10047; /* from _tee10047 */ + 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); @@ -1419,7 +1393,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 != 10048) + if (api_value != 10047) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1428,7 +1402,7 @@ void OPK_Unpack_InitializeClock_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_InitializeClock_Response(OEMCryptoResult result) { - uint32_t api_value = 10048; /* from _tee10048 */ + 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); @@ -1440,7 +1414,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 != 10049) + if (api_value != 10048) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1449,7 +1423,7 @@ void OPK_Unpack_TerminateClock_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_TerminateClock_Response(OEMCryptoResult result) { - uint32_t api_value = 10049; /* from _tee10049 */ + 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); @@ -1461,7 +1435,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 != 10050) + if (api_value != 10049) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1471,7 +1445,7 @@ void OPK_Unpack_GetClockType_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetClockType_Response( OEMCrypto_Clock_Security_Level result) { - uint32_t api_value = 10050; /* from _tee10050 */ + uint32_t api_value = 10049; /* from _tee10049 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_Clock_Security_Level(&msg, &result); @@ -1483,7 +1457,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 != 10051) + if (api_value != 10050) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1493,7 +1467,7 @@ void OPK_Unpack_GetSecurityLevel_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetSecurityLevel_Response( OEMCrypto_Security_Level result) { - uint32_t api_value = 10051; /* from _tee10051 */ + uint32_t api_value = 10050; /* from _tee10050 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_Security_Level(&msg, &result); @@ -1505,7 +1479,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 != 10052) + if (api_value != 10051) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1515,7 +1489,7 @@ void OPK_Unpack_GetProvisioningMethod_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetProvisioningMethod_Response( OEMCrypto_ProvisioningMethod result) { - uint32_t api_value = 10052; /* from _tee10052 */ + uint32_t api_value = 10051; /* from _tee10051 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_ProvisioningMethod(&msg, &result); @@ -1527,7 +1501,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 != 10053) + if (api_value != 10052) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1536,7 +1510,7 @@ void OPK_Unpack_GetResourceRatingTier_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_GetResourceRatingTier_Response(uint32_t result) { - uint32_t api_value = 10053; /* from _tee10053 */ + uint32_t api_value = 10052; /* from _tee10052 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1548,7 +1522,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 != 10054) + if (api_value != 10053) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1558,7 +1532,7 @@ void OPK_Unpack_IsTAAntiRollbackEnabled_Request(ODK_Message* msg) { ODK_Message OPK_Pack_IsTAAntiRollbackEnabled_Response( OPK_FeatureStatus result) { - uint32_t api_value = 10054; /* from _tee10054 */ + 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); @@ -1570,7 +1544,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 != 10055) + if (api_value != 10054) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1579,7 +1553,7 @@ void OPK_Unpack_IsProductionReady_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsProductionReady_Response(bool result) { - uint32_t api_value = 10055; /* from _tee10055 */ + uint32_t api_value = 10054; /* from _tee10054 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1591,7 +1565,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 != 10056) + if (api_value != 10055) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1601,7 +1575,7 @@ void OPK_Unpack_GetWatermarkingSupport_Request(ODK_Message* msg) { ODK_Message OPK_Pack_GetWatermarkingSupport_Response( OEMCrypto_WatermarkingSupport result) { - uint32_t api_value = 10056; /* from _tee10056 */ + uint32_t api_value = 10055; /* from _tee10055 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_WatermarkingSupport(&msg, &result); @@ -1614,7 +1588,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 != 10057) + if (api_value != 10056) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1625,7 +1599,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 = 10057; /* from _tee10057 */ + uint32_t api_value = 10056; /* from _tee10056 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1638,7 +1612,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 != 10058) + if (api_value != 10057) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1647,7 +1621,7 @@ void OPK_Unpack_IsAntiRollbackHWPresent_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsAntiRollbackHWPresent_Response(bool result) { - uint32_t api_value = 10058; /* from _tee10058 */ + uint32_t api_value = 10057; /* from _tee10057 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1659,7 +1633,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 != 10059) + if (api_value != 10058) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1668,7 +1642,7 @@ void OPK_Unpack_IsCGMS_AActive_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsCGMS_AActive_Response(bool result) { - uint32_t api_value = 10059; /* from _tee10059 */ + 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); @@ -1680,7 +1654,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 != 10060) + if (api_value != 10059) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1689,7 +1663,7 @@ void OPK_Unpack_SupportsCGMS_A_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_SupportsCGMS_A_Response(bool result) { - uint32_t api_value = 10060; /* from _tee10060 */ + 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); @@ -1701,7 +1675,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 != 10061) + if (api_value != 10060) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1710,7 +1684,7 @@ void OPK_Unpack_HasAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_HasAnalogDisplay_Response(bool result) { - uint32_t api_value = 10061; /* from _tee10061 */ + 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); @@ -1722,7 +1696,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 != 10062) + if (api_value != 10061) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1731,7 +1705,7 @@ void OPK_Unpack_IsAnalogDisplayActive_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsAnalogDisplayActive_Response(bool result) { - uint32_t api_value = 10062; /* from _tee10062 */ + 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); @@ -1743,7 +1717,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 != 10063) + if (api_value != 10062) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1752,7 +1726,7 @@ void OPK_Unpack_CanDisableAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_CanDisableAnalogDisplay_Response(bool result) { - uint32_t api_value = 10063; /* from _tee10063 */ + 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); @@ -1764,7 +1738,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 != 10064) + if (api_value != 10063) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1773,7 +1747,7 @@ void OPK_Unpack_DisableAnalogDisplay_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_DisableAnalogDisplay_Response(bool result) { - uint32_t api_value = 10064; /* from _tee10064 */ + 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); @@ -1785,7 +1759,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 != 10065) + if (api_value != 10064) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1794,7 +1768,7 @@ void OPK_Unpack_MaxOutputSizeForDecrypt_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxOutputSizeForDecrypt_Response(size_t result) { - uint32_t api_value = 10065; /* from _tee10065 */ + uint32_t api_value = 10064; /* from _tee10064 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1806,7 +1780,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 != 10066) + if (api_value != 10065) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1815,7 +1789,7 @@ void OPK_Unpack_IsClosedPlatform_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_IsClosedPlatform_Response(bool result) { - uint32_t api_value = 10066; /* from _tee10066 */ + uint32_t api_value = 10065; /* from _tee10065 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1827,7 +1801,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 != 10067) + if (api_value != 10066) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1837,7 +1811,7 @@ void OPK_Unpack_CurrentHDCPCapability_Request(ODK_Message* msg) { ODK_Message OPK_Pack_CurrentHDCPCapability_Response( OEMCrypto_HDCP_Capability result) { - uint32_t api_value = 10067; /* from _tee10067 */ + uint32_t api_value = 10066; /* from _tee10066 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_OEMCrypto_HDCP_Capability(&msg, &result); @@ -1849,7 +1823,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 != 10068) + if (api_value != 10067) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1859,7 +1833,7 @@ void OPK_Unpack_MaxHDCPCapability_Request(ODK_Message* msg) { ODK_Message OPK_Pack_MaxHDCPCapability_Response( OEMCrypto_HDCP_Capability result) { - uint32_t api_value = 10068; /* from _tee10068 */ + 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); @@ -1871,7 +1845,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 != 10069) + if (api_value != 10068) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1880,7 +1854,7 @@ void OPK_Unpack_MaxBufferSizeForGenericCrypto_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxBufferSizeForGenericCrypto_Response(size_t result) { - uint32_t api_value = 10069; /* from _tee10069 */ + uint32_t api_value = 10068; /* from _tee10068 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_size_t(&msg, &result); @@ -1892,7 +1866,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 != 10070) + if (api_value != 10069) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1901,7 +1875,7 @@ void OPK_Unpack_MaxSampleSize_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_MaxSampleSize_Response(size_t result) { - uint32_t api_value = 10070; /* from _tee10070 */ + 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); @@ -1913,7 +1887,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 != 10071) + if (api_value != 10070) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1922,7 +1896,7 @@ void OPK_Unpack_SupportedCertificates_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_SupportedCertificates_Response(uint32_t result) { - uint32_t api_value = 10071; /* from _tee10071 */ + uint32_t api_value = 10070; /* from _tee10070 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1934,7 +1908,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 != 10072) + if (api_value != 10071) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1943,7 +1917,7 @@ void OPK_Unpack_ContentDecryptBypassesTA_Request(ODK_Message* msg) { } ODK_Message OPK_Pack_ContentDecryptBypassesTA_Response(bool result) { - uint32_t api_value = 10072; /* from _tee10072 */ + uint32_t api_value = 10071; /* from _tee10071 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_bool(&msg, &result); @@ -1958,7 +1932,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 != 10073) + if (api_value != 10072) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -1971,7 +1945,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 = 10073; /* from _tee10073 */ + uint32_t api_value = 10072; /* from _tee10072 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_Pack_uint32_t(&msg, &result); @@ -1986,7 +1960,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 != 10074) + if (api_value != 10073) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -2003,7 +1977,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 = 10074; /* from _tee10074 */ + uint32_t api_value = 10073; /* from _tee10073 */ ODK_Message msg = TOS_Transport_GetResponse(); OPK_Pack_uint32_t(&msg, &api_value); OPK_PackNullable_size_t(&msg, out_length); @@ -2022,7 +1996,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 != 10075) + if (api_value != 10074) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -2039,7 +2013,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 = 10075; /* from _tee10075 */ + 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); @@ -2057,7 +2031,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 != 10076) + if (api_value != 10075) ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); uint64_t timestamp; OPK_Unpack_uint64_t(msg, ×tamp); @@ -2072,7 +2046,7 @@ void OPK_Unpack_VerifyAndDecryptUsageData_Legacy_Request( ODK_Message OPK_Pack_VerifyAndDecryptUsageData_Legacy_Response( OEMCryptoResult result, const uint8_t* out) { - uint32_t api_value = 10076; /* from _tee10076 */ + uint32_t api_value = 10075; /* from _tee10075 */ 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 ede631c..a1e7e93 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 @@ -190,10 +190,6 @@ 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, 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 066156a..85b3c18 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 @@ -19,10 +19,12 @@ static size_t gBufferSize = 0; static uint8_t gBuffer[MAX_ROT_SIZE]; +#ifdef USE_PROVISIONING_30 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]; +#endif OEMCryptoResult WTPI_UnwrapRootOfTrust(const uint8_t* input, size_t input_length, uint8_t* output, @@ -56,53 +58,93 @@ OEMCryptoResult WTPI_LoadRootOfTrust(uint8_t* output, size_t* length) { OEMCryptoResult WTPI_WrapRootOfTrust30(const uint8_t* input, size_t input_length, uint8_t* output, size_t* output_length) { +#ifdef USE_PROVISIONING_30 return WTPI_EncryptAndSign(DEVICE_KEY_WRAP_DRM_CERT, input, input_length, output, output_length); +#else + (void)input; + (void)input_length; + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_UnwrapRootOfTrust30(const uint8_t* input, size_t input_length, uint8_t* output, size_t* output_length) { +#ifdef USE_PROVISIONING_30 return WTPI_VerifyAndDecrypt(DEVICE_KEY_WRAP_DRM_CERT, input, input_length, output, output_length); +#else + (void)input; + (void)input_length; + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_SaveOEMPrivateKey30(const uint8_t* input, size_t input_length) { +#ifdef USE_PROVISIONING_30 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; +#else + (void)input; + (void)input_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_LoadOEMPrivateKey30(uint8_t* output, size_t* output_length) { +#ifdef USE_PROVISIONING_30 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; +#else + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } -OEMCryptoResult WTPI_SaveOEMPublicCertificate30(const uint8_t* input UNUSED, - size_t input_length UNUSED) { +OEMCryptoResult WTPI_SaveOEMPublicCertificate30(const uint8_t* input, + size_t input_length) { +#ifdef USE_PROVISIONING_30 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; +#else + (void)input; + (void)input_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_LoadOEMPublicCertificate30(uint8_t* output, size_t* output_length) { +#ifdef USE_PROVISIONING_30 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; +#else + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } diff --git a/oemcrypto/opk/ports/linux/cas/tee/tuner_tee_serialization.c b/oemcrypto/opk/ports/linux/cas/tee/tuner_tee_serialization.c index e75233b..1c681df 100644 --- a/oemcrypto/opk/ports/linux/cas/tee/tuner_tee_serialization.c +++ b/oemcrypto/opk/ports/linux/cas/tee/tuner_tee_serialization.c @@ -67,10 +67,9 @@ ODK_MessageStatus Tuner_DispatchMessage(ODK_Message* request, OEMCrypto_CENCEncryptPatternDesc* pattern = (OEMCrypto_CENCEncryptPatternDesc*)OPK_VarAlloc( sizeof(OEMCrypto_CENCEncryptPatternDesc)); + if (!pattern) goto handle_out_of_memory; OPK_Init_OEMCrypto_CENCEncryptPatternDesc( (OEMCrypto_CENCEncryptPatternDesc*)pattern); - // OPK_Unpack_DecryptCENC_Request(request, &session, &samples, - // &samples_length, &pattern); OPK_Unpack_TunerHal_Decrypt_Request(request, &key_token, &key_token_length, &key_parity, &samples, &samples_length, &pattern); @@ -90,6 +89,12 @@ handle_invalid_request: LOGE("invalid request"); *response = CreateEmptyMessage(); return MESSAGE_STATUS_OK; + +handle_out_of_memory: + LOGE("out of memory"); + ODK_Message_SetStatus(request, MESSAGE_STATUS_OUT_OF_MEMORY); + *response = CreateEmptyMessage(); + return MESSAGE_STATUS_OK; } void OPK_Unpack_TunerHal_Decrypt_Request( 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 a24587e..ab5c272 100644 --- a/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk +++ b/oemcrypto/opk/ports/linux/ta/common/wtpi_impl/sources.mk @@ -29,7 +29,6 @@ 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 \ @@ -50,6 +49,10 @@ wtpi_impl_sources += \ $(tos_impl_dir)/tos_secure_buffers.c \ $(tos_impl_dir)/tos_transport.cpp \ +ifdef USE_PROVISIONING_30 + wtpi_impl_sources += $(wtpi_ref_dir)/prov30_factory_util.c +endif + wtpi_impl_includes += \ $(wtpi_impl_dir) \ $(wtpi_ref_dir) \ diff --git a/oemcrypto/opk/ports/optee/Makefile b/oemcrypto/opk/ports/optee/Makefile index 82dcc6f..a9d99f1 100644 --- a/oemcrypto/opk/ports/optee/Makefile +++ b/oemcrypto/opk/ports/optee/Makefile @@ -36,7 +36,17 @@ TEE_OS := OP-TEE TEE_VERSION := 3.18 DEVICE_FORM_FACTOR := test # overridden later by OP-TEE $(PLATFORM) var. Feel free to replace with own values IMPLEMENTER := your-name-here -OPTEE_PROVISIONING_METHOD := OEMCrypto_Keybox + +# Below are configuration variables that are specific to the OPK OP-TEE port. +# Override these defaults by providing new values to the `make` call. + +# This is copied to the OPK_CONFIG_PROVISIONING_METHOD macro +OPTEE_PROVISIONING_METHOD ?= OEMCrypto_Keybox +ifeq ($(OPTEE_PROVISIONING_METHOD),OEMCrypto_OEMCertificate) +USE_PROVISIONING_30 := y +# Prov30 reference implementation requires OP-TEE 4.0.0 and after +USE_OPTEE_4 := y +endif # Key type generated by OEMCrypto_GenerateCertificateKeyPair() # Options are "RSA" or "ECC" diff --git a/oemcrypto/opk/ports/optee/README.md b/oemcrypto/opk/ports/optee/README.md index 9f689e1..6210c08 100644 --- a/oemcrypto/opk/ports/optee/README.md +++ b/oemcrypto/opk/ports/optee/README.md @@ -19,6 +19,12 @@ manifest when cloning and building OP-TEE). - 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. + - Current OP-TEE version 3.18.0 builds with `der_parse.c` under + `wtpi_impl/util/`. OP-TEE version 4.0.0 or later is required to build with + `crypto_util_mbedtls_v3.c`. This is because OP-TEE version 4 includes a + version upgrade of the MBEDTLS library v3, which introduced some + non-backward compatible changes: + https://github.com/OP-TEE/optee_os/tree/4.0.0/lib/libmbedtls 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. diff --git a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/Makefile b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/Makefile index 466a045..810f0e7 100644 --- a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/Makefile +++ b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/Makefile @@ -22,8 +22,14 @@ include $(srcdir)/oemcrypto/opk/build/ree-sources.mk srcs += \ $(oemcrypto_unittests_sources) \ +srcs := $(filter-out $(oemcrypto_unittests_dir)/oemcrypto_test_main.cpp, $(srcs)) +srcs += \ + $(OPK_REPO_TOP)/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp \ + $(OPK_REPO_TOP)/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.cpp \ + incs += \ $(oemcrypto_unittests_includes) \ + $(OPK_REPO_TOP)/oemcrypto/opk/ports/optee/host/oemcrypto_unittests \ ldflags = \ -lpthread \ diff --git a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.cpp b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.cpp new file mode 100644 index 0000000..81f9518 --- /dev/null +++ b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.cpp @@ -0,0 +1,148 @@ +// 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 "install_prov30_rot.h" + +#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, + size_t oem_public_cert_size, + const uint8_t* oem_private_key, + 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; +} +} // namespace + +namespace wvoec { + +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 wvoec diff --git a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.h b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.h new file mode 100644 index 0000000..4e9f2fc --- /dev/null +++ b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/install_prov30_rot.h @@ -0,0 +1,21 @@ +/* + * 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 INSTALL_PROV30_ROT_H_ +#define INSTALL_PROV30_ROT_H_ + +#include "OEMCryptoCENC.h" + +namespace wvoec { + +OEMCryptoResult InstallTestProv30RootOfTrust(const uint8_t* oem_public_cert, + size_t oem_public_cert_size, + const uint8_t* oem_private_key, + size_t oem_private_key_size); + +} // namespace wvoec + +#endif diff --git a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp new file mode 100644 index 0000000..56b3817 --- /dev/null +++ b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp @@ -0,0 +1,80 @@ +#include +#include + +#include "OEMCryptoCENC.h" +#include "install_prov30_rot.h" +#include "log.h" +#include "oec_device_features.h" +#include "oec_test_data.h" +#include "oemcrypto_corpus_generator_helper.h" +#include "test_sleep.h" + +static void acknowledge_cast() { + std::cout + << "==================================================================\n" + << "= This device is expected to load x509 certs as a cast receiver. =\n" + << "==================================================================\n"; +} + +int CheckAndInstallProv30ROT() { + OEMCryptoResult sts = OEMCrypto_Initialize(); + if (sts != OEMCrypto_SUCCESS) { + std::cerr << "Failed to initialize OEMCrypto: result = " << sts + << std::endl; + return 1; + } + const OEMCrypto_ProvisioningMethod method = OEMCrypto_GetProvisioningMethod(); + if (method == OEMCrypto_OEMCertificate) { + const OEMCryptoResult result = wvoec::InstallTestProv30RootOfTrust( + wvoec::kTestOEMPublicCertInfo2, sizeof(wvoec::kTestOEMPublicCertInfo2), + wvoec::kTestRSAPKCS8PrivateKeyInfo2_2048, + sizeof(wvoec::kTestRSAPKCS8PrivateKeyInfo2_2048)); + if (result != OEMCrypto_SUCCESS) { + std::cerr << "Failed to install prov30 test root of trust.\n"; + return 1; + } + } + OEMCrypto_Terminate(); + return 0; +} + +// This special main procedure is used instead of the standard GTest main, +// because we need to initialize the list of features supported by the device. +// Also, the test filter is updated based on the feature list. +int main(int argc, char** argv) { + bool is_cast_receiver = false; + int verbosity = 0; + // Skip the first element, which is the program name. + const std::vector args(argv + 1, argv + argc); + for (const std::string& arg : args) { + if (arg == "--generate_corpus") { + wvoec::SetGenerateCorpus(true); + } + if (arg == "--verbose" || arg == "-v") { + ++verbosity; + } else if (arg == "--cast") { + acknowledge_cast(); + is_cast_receiver = true; + } + if (arg == "--force_load_test_keybox") { + std::cerr << "The argument --force_load_test_keybox is obsolete.\n"; + return 1; + } + if (arg == "--fake_sleep") { + wvutil::TestSleep::set_real_sleep(false); + } + } + wvutil::g_cutoff = static_cast(verbosity); + wvoec::global_features.Initialize(); + if (is_cast_receiver) { + // Turn it on if passed in on the command line. Do not turn these tests off + // automtically -- instead, we'll let the caller filter them out if they + // need to. These tests will normally only run if the device claims to + // support being a cast receiver. + wvoec::global_features.set_cast_receiver(is_cast_receiver); + } + if (CheckAndInstallProv30ROT() != 0) return 1; + // Init GTest after device properties has been initialized. + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/sources.mk b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/sources.mk index 2af3fc7..ea1bbef 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/sources.mk +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/sources.mk @@ -8,7 +8,7 @@ # well as stubs from `wtpi_useless` that must be replaced for a production # build. # -# This is not necessary for other ports. This only exists to consoldiate all of +# This is not necessary for other ports. This only exists to consolidate all of # the OPTEE-specific code in one place for use in sub.mk OPK_REPO_TOP ?= $(CDM_DIR) @@ -37,7 +37,6 @@ dice_includes += \ wtpi_impl_sources += \ $(wtpi_impl_dir)/util/ta_log.c \ - $(wtpi_impl_dir)/util/der_parse.c \ $(wtpi_impl_dir)/util/device_info.c \ $(wtpi_ref_dir)/odk_endian.c \ $(wtpi_ref_dir)/cose_util.c \ @@ -77,6 +76,16 @@ else $(error OEMCRYPTO_GEN_KEYPAIR_TYPE make variable must be either ECC or RSA) endif +ifdef USE_OPTEE_4 +wtpi_impl_sources += $(wtpi_impl_dir)/util/crypto_util_mbedtls_v3.c +else +wtpi_impl_sources += $(wtpi_impl_dir)/util/der_parse.c +endif + +ifdef USE_PROVISIONING_30 +wtpi_impl_sources += $(wtpi_impl_dir)/util/prov30_factory_util_mbedtls_v3.c +endif + wtpi_impl_includes += \ $(wtpi_impl_dir) \ $(wtpi_impl_dir)/util \ diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/crypto_util_mbedtls_v3.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/crypto_util_mbedtls_v3.c new file mode 100644 index 0000000..3b3a53e --- /dev/null +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/crypto_util_mbedtls_v3.c @@ -0,0 +1,869 @@ +/* + * 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 "der_parse.h" + +#include +#include + +#include "asn1write.h" +#include "bignum.h" +#include "ctr_drbg.h" +#include "ecp.h" +#include "entropy.h" +#include "odk_endian.h" +#include "pk.h" +#include "rsa.h" +#include "sha256.h" + +// Helper for the mbedtls_asn1_write_* functions. Assumes the existence of +// a variable named `ret` with type `int`. +#define CHK_ASN1_WRITE(b, f) \ + do { \ + if ((ret = f) < 0) \ + return OEMCrypto_ERROR_UNKNOWN_FAILURE; \ + else \ + b += ret; \ + } while (0) + +int EntropyFunc(void* data, unsigned char* output, size_t size) { + ((void)data); + TEE_GenerateRandom(output, size); + return 0; +} + +/* + * Takes an mbedtls_mpi pointer |src|, an empty buffer pointer |dest|, and + * a 0 value |dest_len|. + * + * Extracts the length value from |src| and places that into |dest_len| + * + * Malloc's a buffer with size |dest_len| and assigns the buffer pointer to + * |dest| + * + * Extracts the data from |src| to |dest| with the mbed_mpi_write_binary + * function + * + */ +static OEMCryptoResult extract_mbedtls_mpi_param(mbedtls_mpi* src, + uint8_t** dest, + size_t* dest_len) { + if (src == NULL || dest == NULL || dest_len == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + size_t len = mbedtls_mpi_size(src); + + uint8_t* data = TEE_Malloc(len, TEE_MALLOC_FILL_ZERO); + if (data == NULL) { + EMSG("Malloc failed, out of memory"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + int ret = mbedtls_mpi_write_binary(src, data, len); + if (ret != 0 || len == 0) { + TEE_MemFill(data, 0, len); + TEE_Free(data); + EMSG("mbedtls_mpi_write_binary failed"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + *dest = data; + *dest_len = len; + + return OEMCrypto_SUCCESS; +} + +void Free_pkcs1_rsa(pkcs1_rsa* key) { + if (key == NULL) { + return; + } + + if (key->private_exp != NULL) { + TEE_MemFill(key->private_exp, 0, key->private_exp_len); + } + + TEE_Free(key->modulus); + TEE_Free(key->public_exp); + TEE_Free(key->private_exp); + TEE_Free(key->prime1); + TEE_Free(key->prime2); + TEE_Free(key->exp1); + TEE_Free(key->exp2); + TEE_Free(key->coefficient); + + TEE_MemFill(key, 0, sizeof(*key)); +} + +OEMCryptoResult DecodePKCS8RSAPrivateKey(const uint8_t* input, + size_t input_length, + pkcs1_rsa* output) { + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + mbedtls_entropy_context entropy; + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init(&ctr_drbg); + + const char* pers = "pk_parse_key"; + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, EntropyFunc, &entropy, + (const unsigned char*)pers, strlen(pers)); + if (ret != 0) { + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + ret = mbedtls_pk_parse_key(&pk_ctx, input, input_length, NULL, 0, + mbedtls_ctr_drbg_random, &ctr_drbg); + if (ret != 0) { + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + OEMCryptoResult res; + TEE_MemFill(output, 0, sizeof(*output)); + + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; + mbedtls_mpi_init(&N); + mbedtls_mpi_init(&P); + mbedtls_mpi_init(&Q); + mbedtls_mpi_init(&D); + mbedtls_mpi_init(&E); + mbedtls_mpi_init(&DP); + mbedtls_mpi_init(&DQ); + mbedtls_mpi_init(&QP); + + mbedtls_rsa_context* rsa_ctx = mbedtls_pk_rsa(pk_ctx); + + ret = mbedtls_rsa_export(rsa_ctx, &N, &P, &Q, &D, &E); + if (ret != 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + ret = mbedtls_rsa_export_crt(rsa_ctx, &DP, &DQ, &QP); + if (ret != 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&N, &output->modulus, &output->modulus_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&E, &output->public_exp, + &output->public_exp_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&D, &output->private_exp, + &output->private_exp_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&P, &output->prime1, &output->prime1_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&Q, &output->prime2, &output->prime2_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&DP, &output->exp1, &output->exp1_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&DQ, &output->exp2, &output->exp2_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&QP, &output->coefficient, + &output->coefficient_len); + +cleanup: + + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + + mbedtls_mpi_free(&N); + mbedtls_mpi_free(&P); + mbedtls_mpi_free(&Q); + mbedtls_mpi_free(&D); + mbedtls_mpi_free(&E); + mbedtls_mpi_free(&DP); + mbedtls_mpi_free(&DQ); + mbedtls_mpi_free(&QP); + + if (res != OEMCrypto_SUCCESS) { + Free_pkcs1_rsa(output); + } + + return res; +} + +static OEMCryptoResult Helper_EncodeRSAKey( + const pkcs1_rsa* key, uint8_t* output, size_t* output_length, + int (*mbedtls_write_fn)(const mbedtls_pk_context* ctx, unsigned char* buf, + size_t size)) { + // import RSA data as raw values into mbedtls_rsa_context + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + int result = + mbedtls_pk_setup(&pk_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); + if (result != 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_rsa_init(mbedtls_pk_rsa(pk_ctx)); + + result = mbedtls_rsa_import_raw(mbedtls_pk_rsa(pk_ctx), key->modulus, + key->modulus_len, NULL, 0, NULL, 0, + key->private_exp, key->private_exp_len, + key->public_exp, key->public_exp_len); + if (result < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // calculate remaining RSA parameters (P, Q) + result = mbedtls_rsa_complete(mbedtls_pk_rsa(pk_ctx)); + if (result < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // write RSA data in DER encoding to output + size_t original_output_length = *output_length; + int bytes_written = mbedtls_write_fn(&pk_ctx, output, *output_length); + if (bytes_written <= 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + *output_length = bytes_written; + + // mbedtls ASN1 write functions write backwards from the end of the buffer. + // Re-align memory to the beginning of the buffer. + TEE_MemMove(output, output + original_output_length - *output_length, + *output_length); + + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult EncodeRSAPrivateKey(const pkcs1_rsa* key, uint8_t* output, + size_t* output_length) { + if (key == NULL || key->modulus == NULL || key->private_exp == NULL || + key->public_exp == NULL || key->modulus_len == 0 || + key->private_exp_len == 0 || key->public_exp_len == 0 || output == NULL || + output_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + return Helper_EncodeRSAKey(key, output, output_length, + mbedtls_pk_write_key_der); +} + +OEMCryptoResult EncodeRSAPublicKey(const pkcs1_rsa* key, uint8_t* output, + size_t* output_length) { + if (key == NULL || key->modulus == NULL || key->public_exp == NULL || + key->modulus_len == 0 || key->public_exp_len == 0 || output == NULL || + output_length == NULL) { + EMSG("Failing because of something null or 0"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + return Helper_EncodeRSAKey(key, output, output_length, + mbedtls_pk_write_pubkey_der); +} + +static uint32_t GlobalPlatformCurveId(mbedtls_ecp_group_id id) { + switch (id) { + case MBEDTLS_ECP_DP_SECP192R1: + return TEE_ECC_CURVE_NIST_P192; + + case MBEDTLS_ECP_DP_SECP224R1: + return TEE_ECC_CURVE_NIST_P224; + + case MBEDTLS_ECP_DP_SECP256R1: + return TEE_ECC_CURVE_NIST_P256; + + case MBEDTLS_ECP_DP_SECP384R1: + return TEE_ECC_CURVE_NIST_P384; + + case MBEDTLS_ECP_DP_SECP521R1: + return TEE_ECC_CURVE_NIST_P521; + + default: + return TEE_CRYPTO_ELEMENT_NONE; + } + + return TEE_CRYPTO_ELEMENT_NONE; +} + +static mbedtls_ecp_group_id MbedTlsCurveId(uint32_t id) { + switch (id) { + case TEE_ECC_CURVE_NIST_P192: + return MBEDTLS_ECP_DP_SECP192R1; + + case TEE_ECC_CURVE_NIST_P224: + return MBEDTLS_ECP_DP_SECP224R1; + + case TEE_ECC_CURVE_NIST_P256: + return MBEDTLS_ECP_DP_SECP256R1; + + case TEE_ECC_CURVE_NIST_P384: + return MBEDTLS_ECP_DP_SECP384R1; + + case TEE_ECC_CURVE_NIST_P521: + return MBEDTLS_ECP_DP_SECP521R1; + + default: + return MBEDTLS_ECP_DP_NONE; + } + + return MBEDTLS_ECP_DP_NONE; +} + +static size_t CurveNumBits(mbedtls_ecp_group_id id) { + switch (id) { + case MBEDTLS_ECP_DP_SECP192R1: + return 192; + + case MBEDTLS_ECP_DP_SECP224R1: + return 224; + + case MBEDTLS_ECP_DP_SECP256R1: + return 256; + + case MBEDTLS_ECP_DP_SECP384R1: + return 384; + + case MBEDTLS_ECP_DP_SECP521R1: + return 521; + + default: + return 0; + } + + return 0; +} + +static size_t ECCSignatureSize(size_t num_bits) { + // ECC signature size is the length of the ASN1-encoded SEQUENCE containing + // two INTEGER elements, each large enough to contain |num_bits| of data. + // These integers represent the curve point and proof portions of the + // signature. + + if (num_bits == 0) { + return 0; + } + + size_t len = 0; + + // start with INTEGER tag portions + // tag itself is 1 byte + len++; + + // add enough space to hold num_bits + size_t num_bytes = (num_bits + 7) / 8; + len += num_bytes; + + // we have to encode this size value in ASN1, so figure out how many bytes + // that requires + while (num_bytes > 0) { + len++; + num_bytes = num_bytes >> 8; + } + + // plus 1 in case of a negative number + len++; + + // there are two such INTEGER portions. + len += len; + + // encode sequence size information + num_bytes = len; + + while (num_bytes > 0) { + len++; + num_bytes = num_bytes >> 8; + } + + // one last byte for the SEQ tag + len++; + + return len; +} + +// If src size is smaller than desired size, reallocate src and front pad with +// 0s. Set src_size to desired size if successful. +static void zero_pad_and_realloc(uint8_t** src, size_t* src_size, + size_t desired_size) { + if (*src_size >= desired_size) return; + uint8_t* const temp = TEE_Malloc(desired_size, TEE_MALLOC_FILL_ZERO); + const size_t difference = desired_size - *src_size; + TEE_MemMove(temp + difference, *src, *src_size); + TEE_MemFill(*src, 0, *src_size); + TEE_Free(*src); + *src = temp; + *src_size = desired_size; +} + +void Free_rfc5915_eckey(rfc5915_eckey* key) { + if (key == NULL) { + return; + } + + if (key->private_val != NULL) { + TEE_MemFill(key->private_val, 0, key->private_val_len); + } + + TEE_Free(key->private_val); + TEE_Free(key->public_x); + TEE_Free(key->public_y); + + TEE_MemFill(key, 0, sizeof(*key)); +} + +OEMCryptoResult DecodePKCS8ECCPrivateKey(const uint8_t* input, + size_t input_length, + rfc5915_eckey* output) { + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + mbedtls_entropy_context entropy; + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init(&ctr_drbg); + + const char* pers = "pk_parse_key"; + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, EntropyFunc, &entropy, + (const unsigned char*)pers, strlen(pers)); + if (ret != 0) { + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + ret = mbedtls_pk_parse_key(&pk_ctx, input, input_length, NULL, 0, + mbedtls_ctr_drbg_random, &ctr_drbg); + if (ret != 0) { + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_ecp_keypair* ec_ctx = mbedtls_pk_ec(pk_ctx); + + TEE_MemFill(output, 0, sizeof(*output)); + output->ecc_curve_type = + GlobalPlatformCurveId(ec_ctx->MBEDTLS_PRIVATE(grp).id); + output->ecc_curve_bits = CurveNumBits(ec_ctx->MBEDTLS_PRIVATE(grp).id); + output->max_signature_size = ECCSignatureSize(output->ecc_curve_bits); + + OEMCryptoResult res = + extract_mbedtls_mpi_param(&ec_ctx->MBEDTLS_PRIVATE(d), + &output->private_val, &output->private_val_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = + extract_mbedtls_mpi_param(&ec_ctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), + &output->public_x, &output->public_x_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = + extract_mbedtls_mpi_param(&ec_ctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), + &output->public_y, &output->public_y_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + const size_t ecc_curve_bytes = (output->ecc_curve_bits + 7) / 8; + zero_pad_and_realloc(&output->private_val, &output->private_val_len, + ecc_curve_bytes); + zero_pad_and_realloc(&output->public_x, &output->public_x_len, + ecc_curve_bytes); + zero_pad_and_realloc(&output->public_y, &output->public_y_len, + ecc_curve_bytes); + +cleanup: + mbedtls_pk_free(&pk_ctx); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + + if (res != OEMCrypto_SUCCESS) { + Free_rfc5915_eckey(output); + } + + return res; +} + +OEMCryptoResult DecodeECCPublicKey(const uint8_t* input, size_t input_length, + rfc5915_eckey* output) { + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + int ret = mbedtls_pk_parse_public_key(&pk_ctx, input, input_length); + if (ret != 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_ecp_keypair* ec_ctx = mbedtls_pk_ec(pk_ctx); + + TEE_MemFill(output, 0, sizeof(*output)); + output->ecc_curve_type = + GlobalPlatformCurveId(ec_ctx->MBEDTLS_PRIVATE(grp).id); + output->ecc_curve_bits = CurveNumBits(ec_ctx->MBEDTLS_PRIVATE(grp).id); + output->max_signature_size = ECCSignatureSize(output->ecc_curve_bits); + + OEMCryptoResult res = + extract_mbedtls_mpi_param(&ec_ctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), + &output->public_x, &output->public_x_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = + extract_mbedtls_mpi_param(&ec_ctx->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), + &output->public_y, &output->public_y_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + const size_t ecc_curve_bytes = (output->ecc_curve_bits + 7) / 8; + zero_pad_and_realloc(&output->public_x, &output->public_x_len, + ecc_curve_bytes); + zero_pad_and_realloc(&output->public_y, &output->public_y_len, + ecc_curve_bytes); + +cleanup: + mbedtls_pk_free(&pk_ctx); + + if (res != OEMCrypto_SUCCESS) { + Free_rfc5915_eckey(output); + } + + return res; +} + +// OP-TEE does not DER-encode the ECDSA signature. Instead it writes the raw +// R and S values of the signature to a buffer of key_size*2 length. The values +// are front-padded with zero so that they are each key_size in length. +OEMCryptoResult EncodeECDSASignature(const uint8_t* sig, size_t sig_length, + uint8_t* output, size_t* output_length) { + // Signature is assumed to be evenly split between R and S values. + if (sig_length % 2 != 0 || sig == NULL || output == NULL || + output_length == NULL) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // mbedtls_asn1_write_* functions work backwards from the end of the output + // buffer. Therefore, start with the last elements and work forward. + int ret = 0; + uint8_t* p = output + *output_length; + size_t b = 0; // bytes written; + size_t element_len = sig_length / 2; + + size_t s_len = element_len; + size_t r_len = element_len; + + // Write S value raw data, then length, and integer tag. + CHK_ASN1_WRITE(b, mbedtls_asn1_write_raw_buffer(&p, output, sig + element_len, + element_len)); + if ((sig[element_len] & 0x80) != 0) { + CHK_ASN1_WRITE(b, mbedtls_asn1_write_tag(&p, output, 0)); + s_len++; + } + + CHK_ASN1_WRITE(b, mbedtls_asn1_write_len(&p, output, s_len)); + CHK_ASN1_WRITE(b, mbedtls_asn1_write_tag(&p, output, MBEDTLS_ASN1_INTEGER)); + + // Write R value raw data, then length, and integer tag + CHK_ASN1_WRITE(b, + mbedtls_asn1_write_raw_buffer(&p, output, sig, element_len)); + if ((sig[0] & 0x80) != 0) { + CHK_ASN1_WRITE(b, mbedtls_asn1_write_tag(&p, output, 0)); + r_len++; + } + CHK_ASN1_WRITE(b, mbedtls_asn1_write_len(&p, output, r_len)); + CHK_ASN1_WRITE(b, mbedtls_asn1_write_tag(&p, output, MBEDTLS_ASN1_INTEGER)); + + // Write length of data so far, then final sequence tag. "Constructed" flags + // needed for X509 format + CHK_ASN1_WRITE(b, mbedtls_asn1_write_len(&p, output, b)); + CHK_ASN1_WRITE( + b, mbedtls_asn1_write_tag( + &p, output, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); + + // Since we've been writing backwards in the buffer, we might have written + // less than we initially thought. Realign everything to the beginning of the + // buffer. + TEE_MemMove(output, p, b); + *output_length = b; + + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult DeriveEccKey(const uint8_t* seed, size_t seed_length, + uint32_t curve_id, rfc5915_eckey* output) { + if (seed == NULL || seed_length == 0 || output == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + // grp will contain ECC generator point G + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + + // privkey will be the derived seed used to calculate the public key + mbedtls_mpi privkey; + mbedtls_mpi_init(&privkey); + + // pubkey will be the (X,Y) point calculated by multiplying privkey*G + mbedtls_ecp_point pubkey; + mbedtls_ecp_point_init(&pubkey); + + mbedtls_entropy_context entropy; + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init(&ctr_drbg); + + // Derive 64 bytes worth of key material. + uint8_t derived[64]; +#if OPK_OPTEE_CONFIG_DEVICEKEY_NON_NIST_KDF == 1 + // Legacy method. Non-NIST. Should only be used on old devices looking to + // update to OPK v19. + mbedtls_sha256(seed, seed_length, derived, 0); + mbedtls_sha256(seed, seed_length, derived + 32, 0); +#else + // Using NIST SP 800 56Cr2 "One-step Key Derivation", where H=sha256 and + // FixedInfo=curve_id + { + uint32_t counter = 0; + size_t input_length = sizeof(counter) + seed_length + sizeof(curve_id); + uint8_t* input = TEE_Malloc(input_length, TEE_MALLOC_FILL_ZERO); + if (input == NULL) { + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } + + counter++; + uint8_t* addr = input; + uint32_t counter_be = oemcrypto_htobe32(counter); + TEE_MemMove(addr, &counter_be, sizeof(counter_be)); + addr = addr + sizeof(counter); + TEE_MemMove(addr, seed, seed_length); + addr = addr + seed_length; + TEE_MemMove(addr, &curve_id, sizeof(curve_id)); + mbedtls_sha256(input, input_length, derived, 0); + + counter++; + counter_be = oemcrypto_htobe32(counter); + addr = input; + TEE_MemMove(addr, &counter_be, sizeof(counter_be)); + mbedtls_sha256(input, input_length, derived + 32, 0); + TEE_Free(input); + } +#endif + + OEMCryptoResult res; + TEE_MemFill(output, 0, sizeof(*output)); + + // Copy derived result into mbedtls mpi struct, treat it as the private key + mbedtls_ecp_group_id id = MbedTlsCurveId(curve_id); + size_t curve_len_bits = CurveNumBits(id); + size_t curve_len = (curve_len_bits + 7) / 8; + int mbedtls_res = mbedtls_mpi_read_binary(&privkey, derived, curve_len); + if (mbedtls_res < 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // Use a static generator point G for the provided curve + // mbedtls_ecp_group_load loads a known set of fields for a given curve + mbedtls_res = mbedtls_ecp_group_load(&grp, id); + if (mbedtls_res < 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // Initialize the Random Number Generator + const char* pers = "ecp_mul"; + mbedtls_res = mbedtls_ctr_drbg_seed(&ctr_drbg, EntropyFunc, &entropy, + (const unsigned char*)pers, strlen(pers)); + if (mbedtls_res < 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // Multiply private val by G + mbedtls_res = mbedtls_ecp_mul(&grp, &pubkey, &privkey, &grp.G, + mbedtls_ctr_drbg_random, &ctr_drbg); + if (mbedtls_res < 0) { + res = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // Copy results into output struct + output->ecc_curve_type = curve_id; + output->ecc_curve_bits = curve_len_bits; + output->max_signature_size = ECCSignatureSize(curve_len_bits); + + res = extract_mbedtls_mpi_param(&privkey, &output->private_val, + &output->private_val_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&pubkey.MBEDTLS_PRIVATE(X), &output->public_x, + &output->public_x_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + res = extract_mbedtls_mpi_param(&pubkey.MBEDTLS_PRIVATE(Y), &output->public_y, + &output->public_y_len); + if (res != OEMCrypto_SUCCESS) { + goto cleanup; + } + + zero_pad_and_realloc(&output->private_val, &output->private_val_len, + curve_len); + zero_pad_and_realloc(&output->public_x, &output->public_x_len, curve_len); + zero_pad_and_realloc(&output->public_y, &output->public_y_len, curve_len); + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&pubkey); + mbedtls_mpi_free(&privkey); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + TEE_MemFill(derived, 0, sizeof(derived)); + + if (res != OEMCrypto_SUCCESS) { + Free_rfc5915_eckey(output); + } + + return res; +} + +static OEMCryptoResult Helper_EncodeECCKey( + const rfc5915_eckey* key, uint8_t* output, size_t* output_length, + int (*mbedtls_write_fn)(const mbedtls_pk_context* ctx, unsigned char* buf, + size_t size)) { + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + int mbedtls_res = + mbedtls_pk_setup(&pk_ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); + if (mbedtls_res != 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_ecp_keypair_init(mbedtls_pk_ec(pk_ctx)); + + mbedtls_res = + mbedtls_ecp_group_load(&(mbedtls_pk_ec(pk_ctx)->MBEDTLS_PRIVATE(grp)), + MbedTlsCurveId(key->ecc_curve_type)); + if (mbedtls_res < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // Priv key + mbedtls_res = + mbedtls_mpi_read_binary(&(mbedtls_pk_ec(pk_ctx)->MBEDTLS_PRIVATE(d)), + key->private_val, key->private_val_len); + if (mbedtls_res < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // Public x, y, z. Set Z to const 1. + mbedtls_res = mbedtls_mpi_read_binary( + &(mbedtls_pk_ec(pk_ctx)->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), + key->public_x, key->public_x_len); + if (mbedtls_res < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_res = mbedtls_mpi_read_binary( + &(mbedtls_pk_ec(pk_ctx)->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), + key->public_y, key->public_y_len); + if (mbedtls_res < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + mbedtls_res = mbedtls_mpi_lset( + &(mbedtls_pk_ec(pk_ctx)->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z)), 1); + if (mbedtls_res < 0) { + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // write EC data in DER encoding to output + size_t original_output_length = *output_length; + int bytes_written = mbedtls_write_fn(&pk_ctx, output, *output_length); + if (bytes_written <= 0) { + mbedtls_pk_free(&pk_ctx); + EMSG("mbedtls write function returned %x", bytes_written); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + *output_length = bytes_written; + + // mbedtls ASN1 write functions write backwards from the end of the buffer. + // Re-align memory to the beginning of the buffer. + TEE_MemMove(output, output + original_output_length - *output_length, + *output_length); + + mbedtls_pk_free(&pk_ctx); + return OEMCrypto_SUCCESS; +} + +// Encodes ECC public key as X509 SubjectPublicKeyInfo +OEMCryptoResult EncodeECCPublicKey(rfc5915_eckey* key, uint8_t* output, + size_t* output_length) { + if (key == NULL || key->private_val == NULL || key->public_x == NULL || + key->public_y == NULL || key->private_val_len == 0 || + key->public_x_len == 0 || key->public_y_len == 0 || output == NULL || + output_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + return Helper_EncodeECCKey(key, output, output_length, + mbedtls_pk_write_pubkey_der); +} + +OEMCryptoResult EncodeECCPrivateKey(rfc5915_eckey* key, uint8_t* output, + size_t* output_length) { + if (key == NULL || key->private_val == NULL || key->public_x == NULL || + key->public_y == NULL || key->private_val_len == 0 || + key->public_x_len == 0 || key->public_y_len == 0 || output == NULL || + output_length == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + return Helper_EncodeECCKey(key, output, output_length, + mbedtls_pk_write_key_der); +} diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.c index 7af8c68..1c72efe 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.c +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.c @@ -24,6 +24,12 @@ b += ret; \ } while (0) +int EntropyFunc(void* data, unsigned char* output, size_t size) { + ((void)data); + TEE_GenerateRandom(output, size); + return 0; +} + /* * Takes an mbedtls_mpi pointer |src|, an empty buffer pointer |dest|, and * a 0 value |dest_len|. diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.h b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.h index 0f7339f..a780350 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.h +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/der_parse.h @@ -35,6 +35,10 @@ typedef struct pkcs1_rsa { size_t coefficient_len; } pkcs1_rsa; +// An alternative to mbedtls_entropy_func due to some instability issues. +// https://github.com/OP-TEE/optee_os/issues/2856 +int EntropyFunc(void* data, unsigned char* output, size_t size); + /* * Parses |input| data, which is a DER-encoded PKCS8 RSA private key. Extracts * the RSA private key components such as modulus, exponents, primes, @@ -125,7 +129,6 @@ OEMCryptoResult EncodeECDSASignature(const uint8_t* sig, size_t sig_length, OEMCryptoResult DeriveEccKey(const uint8_t* seed, size_t seed_length, uint32_t curve_id, rfc5915_eckey* output); - /* * Encodes the EC key data as a SubjectPublicKeyData struct. The input data must * have the public X,Y keys and private key set, as well as the curve type. diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/prov30_factory_util_mbedtls_v3.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/prov30_factory_util_mbedtls_v3.c new file mode 100644 index 0000000..e181125 --- /dev/null +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/util/prov30_factory_util_mbedtls_v3.c @@ -0,0 +1,1551 @@ +/* + * 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 + +#include "asn1.h" +#include "ctr_drbg.h" +#include "der_parse.h" +#include "entropy.h" +#include "error.h" +#include "oemcrypto_check_macros.h" +#include "oid.h" +#include "pk.h" +#include "pkcs7.h" +#include "platform.h" +#include "x509.h" +#include "x509_crl.h" +#include "x509_crt.h" + +/****************************************************************************** + The following functions are copied from MBEDTLS library 3.4.0 + https://github.com/Mbed-TLS/mbedtls/tree/v3.4.0 + + Known issues in version v3.4.0: + 1. pkcs7_get_certificates(): + This function does not support parsing multiple certificates in a + certificate chain and will return an error. As a workaround, a locally + modified copy of this function is provided, which only parses the first + certificate and does not return an error if the parsing is successful. + See details at: + https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L216 + 2. pkcs7_get_digest_algorithm_set() and pkcs7_get_signed_data(): + These functions assume that the DigestAlgorithmIdentifiers set in the signed + data of the certificate is always non-empty. However, this set can be empty + in some cases. Locally modified versions of these functions skip the + DigestAlgorithmIdentifiers set if it is empty. + + For all local changes made, search for "TODO(OPK, b/349676714)" in this file. + Functions with a leading comment "Copied from mbedtls-*" and not marked as + "modified" are taken from the MBEDTLS library without any changes. +*******************************************************************************/ + +// Copied from mbedtls-3.4.0 +static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info* signer) { + mbedtls_x509_name* name_cur; + mbedtls_x509_name* name_prv; + + if (signer == NULL) { + return; + } + + name_cur = signer->MBEDTLS_PRIVATE(issuer).next; + while (name_cur != NULL) { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_free(name_prv); + } + signer->MBEDTLS_PRIVATE(issuer).next = NULL; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_signature(unsigned char** p, unsigned char* end, + mbedtls_pkcs7_buf* signature) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING); + if (ret != 0) { + return ret; + } + + signature->tag = MBEDTLS_ASN1_OCTET_STRING; + signature->len = len; + signature->p = *p; + + *p = *p + len; + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_digest_algorithm(unsigned char** p, unsigned char* end, + mbedtls_x509_buf* alg) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); + } + + return ret; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_version(unsigned char** p, unsigned char* end, int* ver) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_asn1_get_int(p, end, ver); + if (ret != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret); + } + + /* If version != 1, return invalid version */ + if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) { + ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION; + } + + return ret; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_content_info_type(unsigned char** p, unsigned char* end, + unsigned char** seq_end, + mbedtls_pkcs7_buf* pkcs7) { + size_t len = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char* start = *p; + + ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (ret != 0) { + *p = start; + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } + *seq_end = *p + len; + ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID); + if (ret != 0) { + *p = start; + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } + + pkcs7->tag = MBEDTLS_ASN1_OID; + pkcs7->len = len; + pkcs7->p = *p; + *p += len; + + return ret; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_signer_info(unsigned char** p, unsigned char* end, + mbedtls_pkcs7_signer_info* signer, + mbedtls_x509_buf* alg) { + unsigned char *end_signer, *end_issuer_and_sn; + int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + asn1_ret = mbedtls_asn1_get_tag( + p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (asn1_ret != 0) { + goto out; + } + + end_signer = *p + len; + + ret = pkcs7_get_version(p, end_signer, &signer->MBEDTLS_PRIVATE(version)); + if (ret != 0) { + goto out; + } + + asn1_ret = mbedtls_asn1_get_tag( + p, end_signer, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (asn1_ret != 0) { + goto out; + } + + end_issuer_and_sn = *p + len; + /* Parsing IssuerAndSerialNumber */ + signer->MBEDTLS_PRIVATE(issuer_raw).p = *p; + + asn1_ret = + mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (asn1_ret != 0) { + goto out; + } + + ret = mbedtls_x509_get_name(p, *p + len, &signer->MBEDTLS_PRIVATE(issuer)); + if (ret != 0) { + goto out; + } + + signer->MBEDTLS_PRIVATE(issuer_raw).len = + *p - signer->MBEDTLS_PRIVATE(issuer_raw).p; + + ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, + &signer->MBEDTLS_PRIVATE(serial)); + if (ret != 0) { + goto out; + } + + /* ensure no extra or missing bytes */ + if (*p != end_issuer_and_sn) { + ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; + goto out; + } + + ret = pkcs7_get_digest_algorithm(p, end_signer, + &signer->MBEDTLS_PRIVATE(alg_identifier)); + if (ret != 0) { + goto out; + } + + /* Check that the digest algorithm used matches the one provided earlier */ + if (signer->MBEDTLS_PRIVATE(alg_identifier).tag != alg->tag || + signer->MBEDTLS_PRIVATE(alg_identifier).len != alg->len || + TEE_MemCompare(signer->MBEDTLS_PRIVATE(alg_identifier).p, alg->p, + alg->len) != 0) { + ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; + goto out; + } + + /* Assume authenticatedAttributes is nonexistent */ + ret = pkcs7_get_digest_algorithm( + p, end_signer, &signer->MBEDTLS_PRIVATE(sig_alg_identifier)); + if (ret != 0) { + goto out; + } + + ret = pkcs7_get_signature(p, end_signer, &signer->MBEDTLS_PRIVATE(sig)); + if (ret != 0) { + goto out; + } + + /* Do not permit any unauthenticated attributes */ + if (*p != end_signer) { + ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; + } + +out: + if (asn1_ret != 0 || ret != 0) { + pkcs7_free_signer_info(signer); + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, asn1_ret); + } + + return ret; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_signers_info_set(unsigned char** p, unsigned char* end, + mbedtls_pkcs7_signer_info* signers_set, + mbedtls_x509_buf* digest_alg) { + unsigned char* end_set; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int count = 0; + size_t len = 0; + + ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret); + } + + /* Detect zero signers */ + if (len == 0) { + return 0; + } + + end_set = *p + len; + + ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg); + if (ret != 0) { + return ret; + } + count++; + + mbedtls_pkcs7_signer_info* prev = signers_set; + while (*p != end_set) { + mbedtls_pkcs7_signer_info* signer = + mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info)); + if (!signer) { + ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED; + goto cleanup; + } + + ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg); + if (ret != 0) { + mbedtls_free(signer); + goto cleanup; + } + prev->MBEDTLS_PRIVATE(next) = signer; + prev = signer; + count++; + } + + return count; + +cleanup: + pkcs7_free_signer_info(signers_set); + mbedtls_pkcs7_signer_info* signer = signers_set->MBEDTLS_PRIVATE(next); + while (signer != NULL) { + prev = signer; + signer = signer->MBEDTLS_PRIVATE(next); + pkcs7_free_signer_info(prev); + mbedtls_free(prev); + } + signers_set->MBEDTLS_PRIVATE(next) = NULL; + return ret; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_uid(unsigned char** p, const unsigned char* end, + mbedtls_x509_buf* uid, int n) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (*p == end) { + return 0; + } + + uid->tag = **p; + + if ((ret = mbedtls_asn1_get_tag(p, end, &uid->len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | n)) != 0) { + if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + return 0; + } + + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + } + + uid->p = *p; + *p += uid->len; + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_basic_constraints(unsigned char** p, + const unsigned char* end, int* ca_istrue, + int* max_pathlen) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + /* + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ + *ca_istrue = 0; /* DEFAULT FALSE */ + *max_pathlen = 0; /* endless */ + + if ((ret = mbedtls_asn1_get_tag( + p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*p == end) { + return 0; + } + + if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) { + if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + ret = mbedtls_asn1_get_int(p, end, ca_istrue); + } + + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*ca_istrue != 0) { + *ca_istrue = 1; + } + } + + if (*p == end) { + return 0; + } + + if ((ret = mbedtls_asn1_get_int(p, end, max_pathlen)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer + * overflow, which is an undefined behavior. */ + if (*max_pathlen == INT_MAX) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_LENGTH); + } + + (*max_pathlen)++; + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_ext_key_usage(unsigned char** p, const unsigned char* end, + mbedtls_x509_sequence* ext_key_usage) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_asn1_get_sequence_of(p, end, ext_key_usage, + MBEDTLS_ASN1_OID)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + /* Sequence length must be >= 1 */ + if (ext_key_usage->buf.p == NULL) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_INVALID_LENGTH); + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_dates(unsigned char** p, const unsigned char* end, + mbedtls_x509_time* from, mbedtls_x509_time* to) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag( + p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret); + } + + end = *p + len; + + if ((ret = mbedtls_x509_get_time(p, end, from)) != 0) { + return ret; + } + + if ((ret = mbedtls_x509_get_time(p, end, to)) != 0) { + return ret; + } + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_certificate_policies( + unsigned char** p, const unsigned char* end, + mbedtls_x509_sequence* certificate_policies) { + int ret, parse_ret = 0; + size_t len; + mbedtls_asn1_buf* buf; + mbedtls_asn1_sequence* cur = certificate_policies; + + /* Get main sequence tag */ + ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + if (*p + len != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + /* + * Cannot be an empty sequence. + */ + if (len == 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + while (*p < end) { + mbedtls_x509_buf policy_oid; + const unsigned char* policy_end; + + /* + * Get the policy sequence + */ + if ((ret = mbedtls_asn1_get_tag( + p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + policy_end = *p + len; + + if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len, MBEDTLS_ASN1_OID)) != + 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + policy_oid.tag = MBEDTLS_ASN1_OID; + policy_oid.len = len; + policy_oid.p = *p; + + /* + * Only AnyPolicy is currently supported when enforcing policy. + */ + if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_POLICY, &policy_oid) != 0) { + /* + * Set the parsing return code but continue parsing, in case this + * extension is critical. + */ + parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; + } + + /* Allocate and assign next pointer */ + if (cur->buf.p != NULL) { + if (cur->next != NULL) { + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + } + + cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); + + if (cur->next == NULL) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_ALLOC_FAILED); + } + + cur = cur->next; + } + + buf = &(cur->buf); + buf->tag = policy_oid.tag; + buf->p = policy_oid.p; + buf->len = policy_oid.len; + + *p += len; + + /* + * If there is an optional qualifier, then *p < policy_end + * Check the Qualifier len to verify it doesn't exceed policy_end. + */ + if (*p < policy_end) { + if ((ret = mbedtls_asn1_get_tag( + p, policy_end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + /* + * Skip the optional policy qualifiers. + */ + *p += len; + } + + if (*p != policy_end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return parse_ret; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_version(unsigned char** p, const unsigned char* end, + int* ver) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 0)) != 0) { + if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + *ver = 0; + return 0; + } + + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + } + + end = *p + len; + + if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret); + } + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_get_crt_ext(unsigned char** p, const unsigned char* end, + mbedtls_x509_crt* crt, mbedtls_x509_crt_ext_cb_t cb, + void* p_ctx) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet; + + if (*p == end) { + return 0; + } + + if ((ret = mbedtls_x509_get_ext(p, end, &crt->v3_ext, 3)) != 0) { + return ret; + } + + end = crt->v3_ext.p + crt->v3_ext.len; + while (*p < end) { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + mbedtls_x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + int ext_type = 0; + + if ((ret = mbedtls_asn1_get_tag( + p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + end_ext_data = *p + len; + + /* Get extension ID */ + if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len, + MBEDTLS_ASN1_OID)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + extn_oid.tag = MBEDTLS_ASN1_OID; + extn_oid.p = *p; + *p += extn_oid.len; + + /* Get optional critical */ + if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 && + (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + /* Data should be octet string type */ + if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len, + MBEDTLS_ASN1_OCTET_STRING)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); + } + + start_ext_octet = *p; + end_ext_octet = *p + len; + + if (end_ext_octet != end_ext_data) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + /* + * Detect supported extensions + */ + ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type); + + if (ret != 0) { + /* Give the callback (if any) a chance to handle the extension */ + if (cb != NULL) { + ret = cb(p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet); + if (ret != 0 && is_critical) { + return ret; + } + *p = end_ext_octet; + continue; + } + + /* No parser found, skip extension */ + *p = end_ext_octet; + + if (is_critical) { + /* Data is marked as critical: fail */ + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); + } + continue; + } + + /* Forbid repeated extensions */ + if ((crt->MBEDTLS_PRIVATE(ext_types) & ext_type) != 0) { + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + } + + crt->MBEDTLS_PRIVATE(ext_types) |= ext_type; + + switch (ext_type) { + case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: + /* Parse basic constraints */ + if ((ret = x509_get_basic_constraints( + p, end_ext_octet, &crt->MBEDTLS_PRIVATE(ca_istrue), + &crt->MBEDTLS_PRIVATE(max_pathlen))) != 0) { + return ret; + } + break; + + case MBEDTLS_X509_EXT_KEY_USAGE: + /* Parse key usage */ + if ((ret = mbedtls_x509_get_key_usage( + p, end_ext_octet, &crt->MBEDTLS_PRIVATE(key_usage))) != 0) { + return ret; + } + break; + + case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: + /* Parse extended key usage */ + if ((ret = x509_get_ext_key_usage(p, end_ext_octet, + &crt->ext_key_usage)) != 0) { + return ret; + } + break; + + case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: + /* Parse subject alt name */ + if ((ret = mbedtls_x509_get_subject_alt_name( + p, end_ext_octet, &crt->subject_alt_names)) != 0) { + return ret; + } + break; + + case MBEDTLS_X509_EXT_NS_CERT_TYPE: + /* Parse netscape certificate type */ + if ((ret = mbedtls_x509_get_ns_cert_type( + p, end_ext_octet, &crt->MBEDTLS_PRIVATE(ns_cert_type))) != 0) { + return ret; + } + break; + + case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES: + /* Parse certificate policies type */ + if ((ret = x509_get_certificate_policies( + p, end_ext_octet, &crt->certificate_policies)) != 0) { + /* Give the callback (if any) a chance to handle the extension + * if it contains unsupported policies */ + if (ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL && + cb(p_ctx, crt, &extn_oid, is_critical, start_ext_octet, + end_ext_octet) == 0) { + break; + } + + if (is_critical) { + return ret; + } else + /* + * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we + * cannot interpret or enforce the policy. However, it is up to + * the user to choose how to enforce the policies, + * unless the extension is critical. + */ + if (ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) { + return ret; + } + } + break; + + default: + /* + * If this is a non-critical extension, which the oid layer + * supports, but there isn't an x509 parser for it, + * skip the extension. + */ + if (is_critical) { + return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; + } else { + *p = end_ext_octet; + } + } + } + + if (*p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int x509_crt_parse_der_core(mbedtls_x509_crt* crt, + const unsigned char* buf, size_t buflen, + int make_copy, mbedtls_x509_crt_ext_cb_t cb, + void* p_ctx) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + unsigned char *p, *end, *crt_end; + mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; + + TEE_MemFill(&sig_params1, 0, sizeof(mbedtls_x509_buf)); + TEE_MemFill(&sig_params2, 0, sizeof(mbedtls_x509_buf)); + TEE_MemFill(&sig_oid2, 0, sizeof(mbedtls_x509_buf)); + + /* + * Check for valid input + */ + if (crt == NULL || buf == NULL) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + /* Use the original buffer until we figure out actual length. */ + p = (unsigned char*)buf; + len = buflen; + end = p + len; + + /* + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + */ + if (mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != + 0) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERR_X509_INVALID_FORMAT; + } + + end = crt_end = p + len; + crt->raw.len = crt_end - buf; + + if (make_copy != 0) { + /* Create and populate a new buffer for the raw field. */ + crt->raw.p = p = mbedtls_calloc(1, crt->raw.len); + if (crt->raw.p == NULL) { + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + TEE_MemMove(crt->raw.p, buf, crt->raw.len); + crt->MBEDTLS_PRIVATE(own_buffer) = 1; + + p += crt->raw.len - len; + end = crt_end = p + len; + } else { + crt->raw.p = (unsigned char*)buf; + crt->MBEDTLS_PRIVATE(own_buffer) = 0; + } + + /* + * TBSCertificate ::= SEQUENCE { + */ + crt->tbs.p = p; + + if ((ret = mbedtls_asn1_get_tag( + &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + } + + end = p + len; + crt->tbs.len = end - crt->tbs.p; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * + * CertificateSerialNumber ::= INTEGER + * + * signature AlgorithmIdentifier + */ + if ((ret = x509_get_version(&p, end, &crt->version)) != 0 || + (ret = mbedtls_x509_get_serial(&p, end, &crt->serial)) != 0 || + (ret = mbedtls_x509_get_alg(&p, end, &crt->sig_oid, &sig_params1)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + if (crt->version < 0 || crt->version > 2) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERR_X509_UNKNOWN_VERSION; + } + + crt->version++; + + if ((ret = mbedtls_x509_get_sig_alg( + &crt->sig_oid, &sig_params1, &crt->MBEDTLS_PRIVATE(sig_md), + &crt->MBEDTLS_PRIVATE(sig_pk), &crt->MBEDTLS_PRIVATE(sig_opts))) != + 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + /* + * issuer Name + */ + crt->issuer_raw.p = p; + + if ((ret = mbedtls_asn1_get_tag( + &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + } + + if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + crt->issuer_raw.len = p - crt->issuer_raw.p; + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + * + */ + if ((ret = x509_get_dates(&p, end, &crt->valid_from, &crt->valid_to)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + /* + * subject Name + */ + crt->subject_raw.p = p; + + if ((ret = mbedtls_asn1_get_tag( + &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != + 0) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + } + + if (len && (ret = mbedtls_x509_get_name(&p, p + len, &crt->subject)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + crt->subject_raw.len = p - crt->subject_raw.p; + + /* + * SubjectPublicKeyInfo + */ + crt->pk_raw.p = p; + if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &crt->pk)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + crt->pk_raw.len = p - crt->pk_raw.p; + + /* + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version shall be v3 + */ + if (crt->version == 2 || crt->version == 3) { + ret = x509_get_uid(&p, end, &crt->issuer_id, 1); + if (ret != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + } + + if (crt->version == 2 || crt->version == 3) { + ret = x509_get_uid(&p, end, &crt->subject_id, 2); + if (ret != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + } + + if (crt->version == 3) { + ret = x509_get_crt_ext(&p, end, crt, cb, p_ctx); + if (ret != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + } + + if (p != end) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + end = crt_end; + + /* + * } + * -- end of TBSCertificate + * + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + if (crt->sig_oid.len != sig_oid2.len || + TEE_MemCompare(crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len) != 0 || + sig_params1.tag != sig_params2.tag || + sig_params1.len != sig_params2.len || + (sig_params1.len != 0 && + TEE_MemCompare(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERR_X509_SIG_MISMATCH; + } + + if ((ret = mbedtls_x509_get_sig(&p, end, &crt->MBEDTLS_PRIVATE(sig))) != 0) { + mbedtls_x509_crt_free(crt); + return ret; + } + + if (p != end) { + mbedtls_x509_crt_free(crt); + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int mbedtls_x509_crt_parse_der_internal(mbedtls_x509_crt* chain, + const unsigned char* buf, + size_t buflen, int make_copy, + mbedtls_x509_crt_ext_cb_t cb, + void* p_ctx) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_x509_crt *crt = chain, *prev = NULL; + + /* + * Check for valid input + */ + if (crt == NULL || buf == NULL) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + while (crt->version != 0 && crt->next != NULL) { + prev = crt; + crt = crt->next; + } + + /* + * Add new certificate on the end of the chain if needed. + */ + if (crt->version != 0 && crt->next == NULL) { + crt->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); + + if (crt->next == NULL) { + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + prev = crt; + mbedtls_x509_crt_init(crt->next); + crt = crt->next; + } + + ret = x509_crt_parse_der_core(crt, buf, buflen, make_copy, cb, p_ctx); + if (ret != 0) { + if (prev) { + prev->next = NULL; + } + + if (crt != chain) { + mbedtls_free(crt); + } + + return ret; + } + + return 0; +} + +// Copied from mbedtls-3.4.0 +static int pkcs7_get_next_content_len(unsigned char** p, unsigned char* end, + size_t* len) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_asn1_get_tag( + p, end, len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); + if (ret != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } else if ((size_t)(end - *p) != *len) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return ret; +} + +// Copied from mbedtls-3.4.0, modified +static int pkcs7_get_certificates(unsigned char** p, unsigned char* end, + mbedtls_x509_crt* certs) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len1 = 0; + size_t len2 = 0; + unsigned char *end_set, *end_cert, *start; + + ret = mbedtls_asn1_get_tag( + p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); + if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + return 0; + } + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); + } + start = *p; + end_set = *p + len1; + + // CertificateChoices SEQUENCE + ret = mbedtls_asn1_get_tag(p, end_set, &len2, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret); + } + + end_cert = *p + len2; + + /* + * This is to verify that there is only one signer certificate. It seems it is + * not easy to differentiate between the chain vs different signer's + * certificate. So, we support only the root certificate and the single + * signer. The behaviour would be improved with addition of multiple signer + * support. + */ + + // TODO(OPK, b/349676714): To add the support of parsing the entire cert + // chain. Currently it parses the first cert from the chain if there are + // multiple. + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L216 + if (end_cert != end_set) { + // Workaround for parsing the first cert in the chain of multiple certs. + // Do not return an error. Skip to the end_set once the first cert is + // parsed. + // return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; + if (mbedtls_x509_crt_parse_der_internal(certs, start, end_cert - start, 1, + NULL, NULL) < 0) { + return MBEDTLS_ERR_PKCS7_INVALID_CERT; + } + *p = end_set; + } else { + // From the original mbedtls which assumes only one cert in the chain. + if (mbedtls_x509_crt_parse_der(certs, start, len1) < 0) { + return MBEDTLS_ERR_PKCS7_INVALID_CERT; + } + *p = end_cert; + } + + /* + * Since in this version we strictly support single certificate, and reaching + * here implies we have parsed successfully, we return 1. + */ + return 1; +} + +// Copied from mbedtls-3.4.0, modified +static int pkcs7_get_digest_algorithm_set(unsigned char** p, unsigned char* end, + mbedtls_x509_buf* alg) { + size_t len = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); + } + + // TODO(OPK, b/349676714): mbedtls doesn't allow empty digest algorithm set + // although it is a valid case. Return OK when it is empty for now. + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L155 + if (len == 0) { + return 0; + } + + end = *p + len; + + ret = mbedtls_asn1_get_alg_null(p, end, alg); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); + } + + /** For now, it assumes there is only one digest algorithm specified **/ + if (*p != end) { + return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; + } + + return 0; +} + +// Copied from mbedtls-3.4.0, modified +static int pkcs7_get_signed_data(unsigned char* buf, size_t buflen, + mbedtls_pkcs7_signed_data* signed_data) { + unsigned char* p = buf; + unsigned char* end = buf + buflen; + unsigned char* end_content_info = NULL; + size_t len = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); + } + + if (p + len != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + /* Get version of signed data */ + ret = pkcs7_get_version(&p, end, &signed_data->MBEDTLS_PRIVATE(version)); + + if (ret != 0) { + return ret; + } + + /* Get digest algorithm */ + ret = pkcs7_get_digest_algorithm_set( + &p, end, &signed_data->MBEDTLS_PRIVATE(digest_alg_identifiers)); + if (ret != 0) { + return ret; + } + + // TODO(OPK, b/349676714): pkcs7_get_digest_algorithm_set() doesn't handle + // empty digest_alg_identifiers. Below check will fail if the parsed + // digest_alg_identifiers is empty. + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L494 + /* + mbedtls_md_type_t md_alg; + ret = mbedtls_oid_get_md_alg( + &signed_data->MBEDTLS_PRIVATE(digest_alg_identifiers), &md_alg); + if (ret != 0) { + return MBEDTLS_ERR_PKCS7_INVALID_ALG; + } + */ + + mbedtls_pkcs7_buf content_type; + TEE_MemFill(&content_type, 0, sizeof(content_type)); + ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type); + if (ret != 0) { + return ret; + } + if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) { + return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO; + } + + if (p != end_content_info) { + /* Determine if valid content is present */ + ret = mbedtls_asn1_get_tag( + &p, end_content_info, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } + p += len; + if (p != end_content_info) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } + /* Valid content is present - this is not supported */ + // TODO(OPK, b/349676714): To add support for this. Ignore the extra content + // for now. + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L526 + // return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; + } + + /* Look for certificates, there may or may not be any */ + mbedtls_x509_crt_init(&signed_data->MBEDTLS_PRIVATE(certs)); + ret = pkcs7_get_certificates(&p, end, &signed_data->MBEDTLS_PRIVATE(certs)); + if (ret < 0) { + return ret; + } + + signed_data->MBEDTLS_PRIVATE(no_of_certs) = ret; + + /* + * Currently CRLs are not supported. If CRL exist, the parsing will fail + * at next step of getting signers info and return error as invalid + * signer info. + */ + + signed_data->MBEDTLS_PRIVATE(no_of_crls) = 0; + + /* Get signers info */ + ret = pkcs7_get_signers_info_set( + &p, end, &signed_data->MBEDTLS_PRIVATE(signers), + &signed_data->MBEDTLS_PRIVATE(digest_alg_identifiers)); + if (ret < 0) { + return ret; + } + + signed_data->MBEDTLS_PRIVATE(no_of_signers) = ret; + + /* Don't permit trailing data */ + if (p != end) { + return MBEDTLS_ERR_PKCS7_INVALID_FORMAT; + } + + return 0; +} + +// A copy of mbedtls_pkcs7_parse_der() from mbedtls-3.4.0 +// It calls the modified pkcs7_get_signed_data() +static int mbedtls_pkcs7_parse_der_ref(mbedtls_pkcs7* pkcs7, + const unsigned char* buf, + const size_t buflen) { + unsigned char* p; + unsigned char* end; + size_t len = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (pkcs7 == NULL) { + return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + } + + /* make an internal copy of the buffer for parsing */ + pkcs7->MBEDTLS_PRIVATE(raw).p = p = mbedtls_calloc(1, buflen); + if (pkcs7->MBEDTLS_PRIVATE(raw).p == NULL) { + ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED; + goto out; + } + TEE_MemMove(p, buf, buflen); + pkcs7->MBEDTLS_PRIVATE(raw).len = buflen; + end = p + buflen; + + ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (ret != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); + goto out; + } + + if ((size_t)(end - p) != len) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + goto out; + } + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { + if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + goto out; + } + p = pkcs7->MBEDTLS_PRIVATE(raw).p; + len = buflen; + goto try_data; + } + + if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) { + /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported + * feature */ + if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len) || + !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len) || + !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len) || + !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, + len) || + !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) { + /* OID is valid according to the spec, but unsupported */ + ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; + } else { + /* OID is invalid according to the spec */ + ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + } + goto out; + } + + p += len; + + ret = pkcs7_get_next_content_len(&p, end, &len); + if (ret != 0) { + goto out; + } + + /* ensure no extra/missing data */ + if (p + len != end) { + ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + goto out; + } + +try_data: + ret = pkcs7_get_signed_data(p, len, &pkcs7->MBEDTLS_PRIVATE(signed_data)); + if (ret != 0) { + goto out; + } + + ret = MBEDTLS_PKCS7_SIGNED_DATA; + +out: + if (ret < 0) { + mbedtls_pkcs7_free(pkcs7); + } + + return ret; +} + +/****************************************************************************** + End of the MBEDTLS library +*******************************************************************************/ + +/* +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 | ++-----------------------+ +| (DER-encoded PKCS#8) | ++-----------------------+ +*/ +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) { + RETURN_INVALID_CONTEXT_IF_NULL(certs_and_key); + RETURN_INVALID_CONTEXT_IF_ZERO(certs_and_key_length); + RETURN_INVALID_CONTEXT_IF_NULL(cert_chain_out); + RETURN_INVALID_CONTEXT_IF_NULL(cert_chain_out_length); + RETURN_INVALID_CONTEXT_IF_NULL(key_out); + RETURN_INVALID_CONTEXT_IF_NULL(key_out_length); + // 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 + TEE_MemMove(cert_chain_out, certs_and_key + sizeof(uint32_t), + cert_chain_length); + *cert_chain_out_length = (size_t)cert_chain_length; + // Copy private key + TEE_MemMove(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 certificate chain parsing + OEMCryptoResult result = OEMCrypto_SUCCESS; + mbedtls_pkcs7 pkcs7; + mbedtls_pkcs7_init(&pkcs7); + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + mbedtls_entropy_context entropy; + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init(&ctr_drbg); + + // Seed the random number generator + const char* pers = "pk_parse_and_check"; + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, EntropyFunc, &entropy, + (const unsigned char*)pers, strlen(pers)); + if (ret != 0) { + result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // Parse the PKCS#7 structure + ret = mbedtls_pkcs7_parse_der_ref(&pkcs7, cert_chain, cert_chain_length); + if (ret < 0) { + result = OEMCrypto_ERROR_UNKNOWN_FAILURE; + goto cleanup; + } + + // 2. Verify the certificate chain + // The PKCS#7 structure can contain multiple certificates. Assuming the cert + // chain contains an intermediate cert followed by a leaf cert. + mbedtls_x509_crt* intermediate_cert = + &pkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); + if (intermediate_cert == NULL) { + result = OEMCrypto_ERROR_INVALID_CONTEXT; + goto cleanup; + } + // TODO: Only the first cert in the chain is parsed for now due to the + // limitations of the mbedtls library: + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L216 + /* + mbedtls_x509_crt* leaf_cert = intermediate_cert->next; + if (leaf_cert == NULL) { + result = OEMCrypto_ERROR_INVALID_CONTEXT; + goto cleanup; + } + + // Verify leaf certificate against intermediate + ret = mbedtls_x509_crt_verify(leaf_cert, intermediate_cert, NULL, NULL, NULL, + NULL, NULL); + if (ret != 0) { + result = OEMCrypto_ERROR_INVALID_CONTEXT; + goto cleanup; + } + */ + + // 3. Parse the private key + ret = mbedtls_pk_parse_key(&pk, key, key_length, NULL, 0, + mbedtls_ctr_drbg_random, &ctr_drbg); + if (ret != 0) { + result = OEMCrypto_ERROR_INVALID_KEY; + goto cleanup; + } + + // TODO: Only the first cert in the chain is parsed for now due to the + // limitations of the mbedtls library: + // https://github.com/Mbed-TLS/mbedtls/blob/v3.4.0/library/pkcs7.c#L216 + /* + // 4. Verify private key matches public key in leaf certificate + + ret = mbedtls_pk_check_pair(&leaf_cert->pk, &pk, mbedtls_ctr_drbg_random, + &ctr_drbg); + if (ret != 0) { + result = OEMCrypto_ERROR_INVALID_KEY; + } + */ +cleanup: + mbedtls_pkcs7_free(&pkcs7); + mbedtls_pk_free(&pk); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return result; +} diff --git a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_crypto_asymmetric.c b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_crypto_asymmetric.c index 2355855..940fa6b 100644 --- a/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_crypto_asymmetric.c +++ b/oemcrypto/opk/ports/optee/ta/common/wtpi_impl/wtpi_crypto_asymmetric.c @@ -274,9 +274,15 @@ OEMCryptoResult WTPI_RSASign(WTPI_AsymmetricKey_Handle key, TEE_FreeOperation(sha1_op); TEE_OperationHandle sign_op_handle = TEE_HANDLE_NULL; +#ifdef USE_OPTEE_4 + res = TEE_AllocateOperation(&sign_op_handle, + TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, + TEE_MODE_SIGN, key_info.objectSize); +#else res = TEE_AllocateOperation(&sign_op_handle, TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_MODE_SIGN, key_info.keySize); +#endif if (res != TEE_SUCCESS) { EMSG("TEE_AllocateOperation() failed with result 0x%x", res); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -381,9 +387,15 @@ OEMCryptoResult WTPI_RSADecrypt(WTPI_AsymmetricKey_Handle key, } TEE_OperationHandle decrypt_op_handle = TEE_HANDLE_NULL; +#ifdef USE_OPTEE_4 + res = TEE_AllocateOperation(&decrypt_op_handle, + TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1, + TEE_MODE_DECRYPT, key_info.objectSize); +#else res = TEE_AllocateOperation(&decrypt_op_handle, TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1, TEE_MODE_DECRYPT, key_info.keySize); +#endif if (res != TEE_SUCCESS) { EMSG("TEE_AllocateOperation() failed with result 0x%x", res); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -494,8 +506,13 @@ OEMCryptoResult Helper_ECCSign(WTPI_AsymmetricKey_Handle key, // Sign digest TEE_OperationHandle sign_op = TEE_HANDLE_NULL; +#ifdef USE_OPTEE_4 + res = TEE_AllocateOperation(&sign_op, sign_algo, TEE_MODE_SIGN, + key_info.objectSize); +#else res = TEE_AllocateOperation(&sign_op, sign_algo, TEE_MODE_SIGN, key_info.keySize); +#endif if (res != TEE_SUCCESS) { EMSG("TEE_AllocateOperation() failed with result 0x%x", res); return OEMCrypto_ERROR_UNKNOWN_FAILURE; 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 fcd1a91..a932beb 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 @@ -13,12 +13,18 @@ #include "cose_util.h" #include "odk_endian.h" +#include "oemcrypto_check_macros.h" #include "oemcrypto_key_types.h" +#include "opk_config.h" +#ifdef USE_PROVISIONING_30 +# include "prov30_factory_util.h" +#endif #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_device_key_interface.h" #include "wtpi_device_renewal_interface_layer1.h" #include "wtpi_logging_interface.h" #include "wtpi_provisioning_4_interface.h" @@ -228,14 +234,40 @@ static OEMCryptoResult GetProv4DeviceID(uint8_t* device_id, return result; } +#ifdef USE_PROVISIONING_30 +static OEMCryptoResult GetProv3DeviceID(uint8_t* device_id, + size_t device_id_length) { + ABORT_IF_NULL(device_id); + 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; +} +#endif + 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 (WTPI_GetProvisioningMethod() != OEMCrypto_Keybox) { +#ifdef USE_PROVISIONING_30 + if (provisioning_method == OEMCrypto_OEMCertificate) { + return GetProv3DeviceID(device_id, device_id_length); + } +#endif + if (provisioning_method != OEMCrypto_Keybox) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } @@ -250,7 +282,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; @@ -306,28 +339,154 @@ OEMCryptoResult WTPI_K1_CreateKeyHandleFromKeybox( } } -OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input UNUSED, - size_t input_length UNUSED, - uint8_t* wrapped_cert UNUSED, - size_t* wrapped_cert_length UNUSED) { +OEMCryptoResult WTPI_StripKeyboxAndReinstall(void) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } -OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert( - const uint8_t* input UNUSED, size_t input_length UNUSED) { +#ifdef USE_PROVISIONING_30 +// Load Provisioning 3.0 OEM private key to output buffer +static OEMCryptoResult LoadOEMPrivateKey(uint8_t* output, + size_t* output_length) { + ABORT_IF_NULL(output); + ABORT_IF_NULL(output_length); + ABORT_IF(*output_length < MAX_PROV30_OEM_KEY_SIZE, "Invalid output length"); + return WTPI_LoadOEMPrivateKey30(output, output_length); +} +#endif + +OEMCryptoResult WTPI_WrapOEMCert(const uint8_t* input, size_t input_length, + uint8_t* wrapped_cert, + size_t* wrapped_cert_length) { +#ifdef USE_PROVISIONING_30 + 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_OEM_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); +#else + (void)input; + (void)input_length; + (void)wrapped_cert; + (void)wrapped_cert_length; return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } -OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output UNUSED, - size_t* output_length UNUSED) { +OEMCryptoResult WTPI_UnwrapValidateAndInstallOEMCert(const uint8_t* input, + size_t input_length) { +#ifdef USE_PROVISIONING_30 + 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); +#else + (void)input; + (void)input_length; return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif +} + +OEMCryptoResult WTPI_LoadOEMPublicCertificate(uint8_t* output, + size_t* output_length) { +#ifdef USE_PROVISIONING_30 + 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); +#else + (void)output; + (void)output_length; + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_ValidateOEMCertAndKey(void) { +#ifdef USE_PROVISIONING_30 + 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); +#else return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } OEMCryptoResult WTPI_CreateAsymmetricKeyHandleFromOEMKey( - WTPI_AsymmetricKey_Handle* key_handle UNUSED) { + WTPI_AsymmetricKey_Handle* key_handle) { +#ifdef USE_PROVISIONING_30 + 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) { + TEE_MemFill(oem_key, 0, sizeof(oem_key)); + LOGE( + "Failed to create asymmetric key handle for OEM private key with " + "result: %u", + result); + return result; + } + TEE_MemFill(oem_key, 0, sizeof(oem_key)); + return OEMCrypto_SUCCESS; +#else + (void)key_handle; return OEMCrypto_ERROR_NOT_IMPLEMENTED; +#endif } diff --git a/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/include/user_ta_header_defines.h b/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/include/user_ta_header_defines.h index 03a9841..f554be3 100644 --- a/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/include/user_ta_header_defines.h +++ b/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/include/user_ta_header_defines.h @@ -23,7 +23,7 @@ #define TA_FLAGS TA_FLAG_EXEC_DDR /* Provisioned stack size */ -#define TA_STACK_SIZE (16 * 1024) +#define TA_STACK_SIZE (32 * 1024) /* Provisioned heap size for TEE_Malloc() and friends */ #define TA_DATA_SIZE (64 * 1024) diff --git a/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/sub.mk b/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/sub.mk index aacf72b..fad127e 100644 --- a/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/sub.mk +++ b/oemcrypto/opk/ports/optee/ta/oemcrypto_ta/sub.mk @@ -43,9 +43,26 @@ cppflags-y += \ -DOPK_CONFIG_IMPLEMENTER_NAME=$(IMPLEMENTER) \ -DOPK_CONFIG_PROVISIONING_METHOD=$(OPTEE_PROVISIONING_METHOD) \ -Wno-switch-default - #-D_DEBUG +# Check if FACTORY_BUILD_ONLY is defined and has a value +ifneq ($(origin FACTORY_BUILD_ONLY), undefined) +ifneq ($(FACTORY_BUILD_ONLY),) +cppflags-y += -DFACTORY_BUILD_ONLY +endif +endif + +ifneq ($(origin USE_PROVISIONING_30), undefined) +ifneq ($(USE_PROVISIONING_30),) +cppflags-y += -DUSE_PROVISIONING_30 +endif +endif + +ifneq ($(origin USE_OPTEE_4), undefined) +ifneq ($(USE_OPTEE_4),) +cppflags-y += -DUSE_OPTEE_4 +endif +endif + libnames += \ $(wtpi_impl_libs) - diff --git a/oemcrypto/opk/ports/optee/ta/wtpi_test_ta/sub.mk b/oemcrypto/opk/ports/optee/ta/wtpi_test_ta/sub.mk index 30c7979..9ad85cb 100644 --- a/oemcrypto/opk/ports/optee/ta/wtpi_test_ta/sub.mk +++ b/oemcrypto/opk/ports/optee/ta/wtpi_test_ta/sub.mk @@ -50,3 +50,21 @@ cppflags-y += \ -DOPK_CONFIG_PROVISIONING_METHOD=$(OPTEE_PROVISIONING_METHOD) \ -Wno-switch-default \ +# Check if FACTORY_BUILD_ONLY is defined and has a value +ifneq ($(origin FACTORY_BUILD_ONLY), undefined) +ifneq ($(FACTORY_BUILD_ONLY),) +cppflags-y += -DFACTORY_BUILD_ONLY +endif +endif + +ifneq ($(origin USE_PROVISIONING_30), undefined) +ifneq ($(USE_PROVISIONING_30),) +cppflags-y += -DUSE_PROVISIONING_30 +endif +endif + +ifneq ($(origin USE_OPTEE_4), undefined) +ifneq ($(USE_OPTEE_4),) +cppflags-y += -DUSE_OPTEE_4 +endif +endif diff --git a/oemcrypto/opk/ports/trusty/ta/reference/rules.mk b/oemcrypto/opk/ports/trusty/ta/reference/rules.mk index fe434ef..443873d 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/rules.mk +++ b/oemcrypto/opk/ports/trusty/ta/reference/rules.mk @@ -79,7 +79,6 @@ 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/ree/GEN_oemcrypto_api.c b/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c index e8f2e88..97ca495 100644 --- a/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c +++ b/oemcrypto/opk/serialization/ree/GEN_oemcrypto_api.c @@ -807,6 +807,38 @@ cleanup_and_return: return result; } +OEMCRYPTO_API OEMCryptoResult OEMCrypto_SetSessionUsage( + OEMCrypto_SESSION session, uint32_t intent, uint32_t mode) { + 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_SetSessionUsage_Request(session, intent, mode); + 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_SetSessionUsage_Response(&response, &result); + + 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_GetKeyHandle( OEMCrypto_SESSION session, const uint8_t* content_key_id, size_t content_key_id_length, OEMCryptoCipherMode cipher_mode, diff --git a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c index 9eb73a5..a034a70 100644 --- a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c +++ b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.c @@ -816,6 +816,38 @@ void OPK_Unpack_GetOEMKeyToken_Response(ODK_Message* msg, } } +ODK_Message OPK_Pack_SetSessionUsage_Request(OEMCrypto_SESSION session, + uint32_t intent, uint32_t mode) { + uint32_t api_value = 155; /* from _oecc155 */ + 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_Pack_uint32_t(&msg, &session); + OPK_Pack_uint32_t(&msg, &intent); + OPK_Pack_uint32_t(&msg, &mode); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + +void OPK_Unpack_SetSessionUsage_Response(ODK_Message* msg, + OEMCryptoResult* result) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 155) + 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_GetKeyHandle_Request(OEMCrypto_SESSION session, const uint8_t* content_key_id, size_t content_key_id_length, diff --git a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h index 7f72cbb..c871c0b 100644 --- a/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h +++ b/oemcrypto/opk/serialization/ree/GEN_ree_serializer.h @@ -121,6 +121,10 @@ void OPK_Unpack_GetOEMKeyToken_Response(ODK_Message* msg, OEMCryptoResult* result, uint8_t** key_token, size_t** key_token_length); +ODK_Message OPK_Pack_SetSessionUsage_Request(OEMCrypto_SESSION session, + uint32_t intent, uint32_t mode); +void OPK_Unpack_SetSessionUsage_Response(ODK_Message* msg, + OEMCryptoResult* result); ODK_Message OPK_Pack_GetKeyHandle_Request(OEMCrypto_SESSION session, const uint8_t* content_key_id, size_t content_key_id_length, diff --git a/oemcrypto/opk/serialization/tee/GEN_dispatcher.c b/oemcrypto/opk/serialization/tee/GEN_dispatcher.c index 1cdc271..78c9e7f 100644 --- a/oemcrypto/opk/serialization/tee/GEN_dispatcher.c +++ b/oemcrypto/opk/serialization/tee/GEN_dispatcher.c @@ -344,12 +344,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t message_length; OPK_Init_size_t((size_t*)&message_length); size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signature_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); uint8_t* message; OPK_InitPointer((uint8_t**)&message); size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (core_message_size == NULL) goto handle_out_of_memory; OPK_Init_size_t(core_message_size); uint8_t* signature; OPK_InitPointer((uint8_t**)&signature); @@ -373,12 +375,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t message_length; OPK_Init_size_t((size_t*)&message_length); size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signature_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); uint8_t* message; OPK_InitPointer((uint8_t**)&message); size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (core_message_size == NULL) goto handle_out_of_memory; OPK_Init_size_t(core_message_size); uint8_t* signature; OPK_InitPointer((uint8_t**)&signature); @@ -456,6 +460,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t content_key_id_length; OPK_Init_size_t((size_t*)&content_key_id_length); size_t* key_control_block_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (key_control_block_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(key_control_block_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -550,13 +555,20 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, } case 120: /* OEMCrypto_LoadCasECMKeys */ { - if (!Handle_OEMCrypto_LoadCasECMKeys(request, response)) - goto handle_invalid_request; + ODK_MessageStatus status = MESSAGE_STATUS_OK; + if (!Handle_OEMCrypto_LoadCasECMKeys(request, response, &status)) { + if (status == MESSAGE_STATUS_OUT_OF_MEMORY) { + goto handle_out_of_memory; + } else { + goto handle_invalid_request; + } + } break; } case 130: /* OEMCrypto_GetOEMKeyToken */ { size_t* key_token_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (key_token_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(key_token_length); OEMCrypto_SESSION key_session; OPK_Init_uint32_t((uint32_t*)&key_session); @@ -574,11 +586,29 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Pack_GetOEMKeyToken_Response(result, key_token, key_token_length); break; } + case 155: /* OEMCrypto_SetSessionUsage */ + { + OEMCrypto_SESSION session; + OPK_Init_uint32_t((uint32_t*)&session); + uint32_t intent; + OPK_Init_uint32_t((uint32_t*)&intent); + uint32_t mode; + OPK_Init_uint32_t((uint32_t*)&mode); + OPK_Unpack_SetSessionUsage_Request(request, &session, &intent, &mode); + if (!ODK_Message_IsValid(request)) goto handle_invalid_request; + OEMCryptoResult result; + OPK_Init_uint32_t((uint32_t*)&result); + LOGD("SetSessionUsage"); + result = OEMCrypto_SetSessionUsage(session, intent, mode); + *response = OPK_Pack_SetSessionUsage_Response(result); + break; + } case 133: /* OEMCrypto_GetKeyHandle */ { size_t content_key_id_length; OPK_Init_size_t((size_t*)&content_key_id_length); size_t* key_handle_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (key_handle_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(key_handle_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -615,6 +645,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OEMCrypto_CENCEncryptPatternDesc* pattern = (OEMCrypto_CENCEncryptPatternDesc*)OPK_VarAlloc( sizeof(OEMCrypto_CENCEncryptPatternDesc)); + if (pattern == NULL) goto handle_out_of_memory; OPK_Init_OEMCrypto_CENCEncryptPatternDesc( (OEMCrypto_CENCEncryptPatternDesc*)pattern); OPK_Unpack_DecryptCENC_Request(request, &key_handle, &key_handle_length, @@ -638,6 +669,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OEMCrypto_DestBufferDesc* out_buffer_descriptor = (OEMCrypto_DestBufferDesc*)OPK_VarAlloc( sizeof(OEMCrypto_DestBufferDesc)); + if (out_buffer_descriptor == NULL) goto handle_out_of_memory; OPK_Init_OEMCrypto_DestBufferDesc( (OEMCrypto_DestBufferDesc*)out_buffer_descriptor); uint8_t subsample_flags; @@ -720,6 +752,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t buffer_length; OPK_Init_size_t((size_t*)&buffer_length); size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signature_length); uint8_t* key_handle; OPK_InitPointer((uint8_t**)&key_handle); @@ -778,6 +811,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Init_size_t((size_t*)&keybox_or_cert_length); size_t* wrapped_keybox_or_cert_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (wrapped_keybox_or_cert_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(wrapped_keybox_or_cert_length); size_t transport_key_length; OPK_Init_size_t((size_t*)&transport_key_length); @@ -861,6 +895,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 7: /* OEMCrypto_GetDeviceID */ { size_t* device_id_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (device_id_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(device_id_length); uint8_t* device_id; OPK_InitPointer((uint8_t**)&device_id); @@ -878,9 +913,11 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, { size_t* wrapped_private_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (wrapped_private_key_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(wrapped_private_key_length); uint8_t* clear_private_key_bytes = (uint8_t*)OPK_VarAlloc(sizeof(uint8_t)); + if (clear_private_key_bytes == NULL) goto handle_out_of_memory; 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); @@ -903,6 +940,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 4: /* OEMCrypto_GetKeyData */ { size_t* key_data_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (key_data_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(key_data_length); uint8_t* key_data; OPK_InitPointer((uint8_t**)&key_data); @@ -947,6 +985,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 104: /* OEMCrypto_GetOEMPublicCertificate */ { size_t* public_cert_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (public_cert_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(public_cert_length); uint8_t* public_cert; OPK_InitPointer((uint8_t**)&public_cert); @@ -987,6 +1026,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 125: /* OEMCrypto_BuildInformation */ { size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(buffer_length); char* buffer; OPK_InitPointer((uint8_t**)&buffer); @@ -1202,6 +1242,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OPK_Init_size_t((size_t*)&signature_length); size_t* wrapped_private_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (wrapped_private_key_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(wrapped_private_key_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1266,6 +1307,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t message_length; OPK_Init_size_t((size_t*)&message_length); size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signature_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1294,12 +1336,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t message_length; OPK_Init_size_t((size_t*)&message_length); size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signature_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); uint8_t* message; OPK_InitPointer((uint8_t**)&message); size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (core_message_size == NULL) goto handle_out_of_memory; OPK_Init_size_t(core_message_size); uint8_t* signature; OPK_InitPointer((uint8_t**)&signature); @@ -1321,6 +1365,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 61: /* OEMCrypto_CreateUsageTableHeader */ { size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (header_buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(header_buffer_length); uint8_t* header_buffer; OPK_InitPointer((uint8_t**)&header_buffer); @@ -1408,8 +1453,10 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 65: /* OEMCrypto_UpdateUsageEntry */ { size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (header_buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(header_buffer_length); size_t* entry_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (entry_buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(entry_buffer_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1455,6 +1502,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t pst_length; OPK_Init_size_t((size_t*)&pst_length); size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(buffer_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1491,6 +1539,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 67: /* OEMCrypto_ShrinkUsageTableHeader */ { size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (header_buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(header_buffer_length); uint32_t new_entry_count; OPK_Init_uint32_t((uint32_t*)&new_entry_count); @@ -1511,9 +1560,11 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 116: /* OEMCrypto_GetBootCertificateChain */ { size_t* bcc_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (bcc_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(bcc_length); size_t* additional_signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (additional_signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(additional_signature_length); uint8_t* bcc; OPK_InitPointer((uint8_t**)&bcc); @@ -1536,12 +1587,15 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 117: /* OEMCrypto_GenerateCertificateKeyPair */ { size_t* public_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (public_key_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(public_key_length); size_t* public_key_signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (public_key_signature_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(public_key_signature_length); size_t* wrapped_private_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (wrapped_private_key_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(wrapped_private_key_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1574,6 +1628,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 131: /* OEMCrypto_GetDeviceInformation */ { size_t* device_info_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (device_info_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(device_info_length); uint8_t* device_info; OPK_InitPointer((uint8_t**)&device_info); @@ -1595,6 +1650,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, size_t encoded_device_info_length; OPK_Init_size_t((size_t*)&encoded_device_info_length); size_t* signed_csr_payload_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (signed_csr_payload_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(signed_csr_payload_length); uint8_t* challenge; OPK_InitPointer((uint8_t**)&challenge); @@ -1729,6 +1785,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, OEMCrypto_DestBufferDesc* output_descriptor = (OEMCrypto_DestBufferDesc*)OPK_VarAlloc( sizeof(OEMCrypto_DestBufferDesc)); + if (output_descriptor == NULL) goto handle_out_of_memory; OPK_Init_OEMCrypto_DestBufferDesc(output_descriptor); int secure_fd; OPK_Init_int((int*)&secure_fd); @@ -1746,8 +1803,10 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 115: /* OEMCrypto_OPK_SerializationVersion */ { uint32_t* ree_major = (uint32_t*)OPK_VarAlloc(sizeof(uint32_t)); + if (ree_major == NULL) goto handle_out_of_memory; OPK_Init_uint32_t(ree_major); uint32_t* ree_minor = (uint32_t*)OPK_VarAlloc(sizeof(uint32_t)); + if (ree_minor == NULL) goto handle_out_of_memory; OPK_Init_uint32_t(ree_minor); uint32_t* tee_major; OPK_InitPointer((uint8_t**)&tee_major); @@ -1768,6 +1827,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 113: /* OEMCrypto_GenerateOTARequest */ { size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (buffer_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(buffer_length); OEMCrypto_SESSION session; OPK_Init_uint32_t((uint32_t*)&session); @@ -1811,6 +1871,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request, case 143: /* OEMCrypto_GetEmbeddedDrmCertificate */ { size_t* public_cert_length = (size_t*)OPK_VarAlloc(sizeof(size_t)); + if (public_cert_length == NULL) goto handle_out_of_memory; OPK_Init_size_t(public_cert_length); uint8_t* public_cert; OPK_InitPointer((uint8_t**)&public_cert); @@ -1835,4 +1896,10 @@ handle_invalid_request: LOGE("invalid request"); *response = CreateEmptyMessage(); return MESSAGE_STATUS_OK; + +handle_out_of_memory: + LOGE("out of memory"); + ODK_Message_SetStatus(request, MESSAGE_STATUS_OUT_OF_MEMORY); + *response = CreateEmptyMessage(); + return MESSAGE_STATUS_OK; } diff --git a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c index c0a7062..ebbc8f0 100644 --- a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c +++ b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.c @@ -670,6 +670,32 @@ ODK_Message OPK_Pack_GetOEMKeyToken_Response(OEMCryptoResult result, return msg; } +void OPK_Unpack_SetSessionUsage_Request(ODK_Message* msg, + OEMCrypto_SESSION* session, + uint32_t* intent, uint32_t* mode) { + uint32_t api_value = UINT32_MAX; + OPK_Unpack_uint32_t(msg, &api_value); + if (api_value != 155) + ODK_MESSAGE_SETSTATUS(msg, MESSAGE_STATUS_API_VALUE_ERROR); + uint64_t timestamp; + OPK_Unpack_uint64_t(msg, ×tamp); + OPK_Unpack_uint32_t(msg, session); + OPK_Unpack_uint32_t(msg, intent); + OPK_Unpack_uint32_t(msg, mode); + OPK_UnpackEOM(msg); + OPK_SharedBuffer_FinalizeUnpacking(); +} + +ODK_Message OPK_Pack_SetSessionUsage_Response(OEMCryptoResult result) { + uint32_t api_value = 155; /* from _oecc155 */ + ODK_Message msg = TOS_Transport_GetResponse(); + OPK_Pack_uint32_t(&msg, &api_value); + OPK_Pack_uint32_t(&msg, &result); + OPK_PackEOM(&msg); + OPK_SharedBuffer_FinalizePacking(); + return msg; +} + void OPK_Unpack_GetKeyHandle_Request( ODK_Message* msg, OEMCrypto_SESSION* session, uint8_t** content_key_id, size_t* content_key_id_length, OEMCryptoCipherMode* cipher_mode, diff --git a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h index 0e6990d..43e940b 100644 --- a/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h +++ b/oemcrypto/opk/serialization/tee/GEN_tee_serializer.h @@ -119,6 +119,10 @@ void OPK_Unpack_GetOEMKeyToken_Request(ODK_Message* msg, ODK_Message OPK_Pack_GetOEMKeyToken_Response(OEMCryptoResult result, const uint8_t* key_token, const size_t* key_token_length); +void OPK_Unpack_SetSessionUsage_Request(ODK_Message* msg, + OEMCrypto_SESSION* session, + uint32_t* intent, uint32_t* mode); +ODK_Message OPK_Pack_SetSessionUsage_Response(OEMCryptoResult result); void OPK_Unpack_GetKeyHandle_Request( ODK_Message* msg, OEMCrypto_SESSION* session, uint8_t** content_key_id, size_t* content_key_id_length, OEMCryptoCipherMode* cipher_mode, diff --git a/oemcrypto/opk/serialization/tee/special_case_request_handlers.c b/oemcrypto/opk/serialization/tee/special_case_request_handlers.c index ebbfd05..97339a7 100644 --- a/oemcrypto/opk/serialization/tee/special_case_request_handlers.c +++ b/oemcrypto/opk/serialization/tee/special_case_request_handlers.c @@ -18,7 +18,8 @@ void OPK_Init_OEMCrypto_EntitledContentKeyObject( OEMCrypto_EntitledContentKeyObject* obj); bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request, - ODK_Message* response) { + ODK_Message* response, + ODK_MessageStatus* status) { size_t message_length; OPK_Init_size_t((size_t*)&message_length); OEMCrypto_SESSION session; @@ -28,11 +29,19 @@ bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request, OEMCrypto_EntitledContentKeyObject* even_key = (OEMCrypto_EntitledContentKeyObject*)OPK_VarAlloc( sizeof(OEMCrypto_EntitledContentKeyObject)); + if (!even_key) { + *status = MESSAGE_STATUS_OUT_OF_MEMORY; + return false; + } OPK_Init_OEMCrypto_EntitledContentKeyObject( (OEMCrypto_EntitledContentKeyObject*)even_key); OEMCrypto_EntitledContentKeyObject* odd_key = (OEMCrypto_EntitledContentKeyObject*)OPK_VarAlloc( sizeof(OEMCrypto_EntitledContentKeyObject)); + if (!odd_key) { + *status = MESSAGE_STATUS_OUT_OF_MEMORY; + return false; + } OPK_Init_OEMCrypto_EntitledContentKeyObject( (OEMCrypto_EntitledContentKeyObject*)odd_key); OPK_Unpack_LoadCasECMKeys_Request(request, &session, &message, @@ -44,5 +53,6 @@ bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request, result = OEMCrypto_LoadCasECMKeys(session, message, message_length, even_key, odd_key); *response = OPK_Pack_LoadCasECMKeys_Response(result); + *status = MESSAGE_STATUS_OK; return true; } diff --git a/oemcrypto/opk/serialization/tee/special_case_request_handlers.h b/oemcrypto/opk/serialization/tee/special_case_request_handlers.h index 4c7273e..e48c49e 100644 --- a/oemcrypto/opk/serialization/tee/special_case_request_handlers.h +++ b/oemcrypto/opk/serialization/tee/special_case_request_handlers.h @@ -16,7 +16,8 @@ extern "C" { #include "odk_message.h" bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request, - ODK_Message* response); + ODK_Message* response, + ODK_MessageStatus* status); #ifdef __cplusplus } // extern "C" diff --git a/oemcrypto/test/GEN_api_lock_file.c b/oemcrypto/test/GEN_api_lock_file.c index e1d5925..009338f 100644 --- a/oemcrypto/test/GEN_api_lock_file.c +++ b/oemcrypto/test/GEN_api_lock_file.c @@ -384,3 +384,7 @@ 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); + +// OEMCrypto_SetSessionUsage defined in v18.7 +OEMCryptoResult _oecc155(OEMCrypto_SESSION session, uint32_t intent, + uint32_t mode); diff --git a/oemcrypto/test/install_prov30_oem_cert_tool.cpp b/oemcrypto/test/install_prov30_oem_cert_tool.cpp index 25eac6d..f4fd408 100644 --- a/oemcrypto/test/install_prov30_oem_cert_tool.cpp +++ b/oemcrypto/test/install_prov30_oem_cert_tool.cpp @@ -26,6 +26,8 @@ format below: +-----------------------+----------------------+--------------------------+ | Private Key | +-----------------------+ +| (DER-encoded PKCS#8) | ++-----------------------+ |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. diff --git a/oemcrypto/test/oec_decrypt_fallback_chain.cpp b/oemcrypto/test/oec_decrypt_fallback_chain.cpp index 6cb7aac..fe303fc 100644 --- a/oemcrypto/test/oec_decrypt_fallback_chain.cpp +++ b/oemcrypto/test/oec_decrypt_fallback_chain.cpp @@ -17,7 +17,6 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { switch (dest_buffer->type) { case OEMCrypto_BufferType_Clear: dest_buffer->buffer.clear.clear_buffer += bytes; - dest_buffer->buffer.clear.clear_buffer_length -= bytes; break; case OEMCrypto_BufferType_Secure: @@ -99,6 +98,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample( const size_t length = subsample.num_bytes_clear + subsample.num_bytes_encrypted; fake_sample.buffers.input_data_length = length; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + length; + } fake_sample.subsamples = &subsample; fake_sample.subsamples_length = 1; @@ -144,6 +148,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( if (subsample.num_bytes_clear > 0) { fake_sample.buffers.input_data_length = subsample.num_bytes_clear; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + subsample.num_bytes_clear; + } fake_subsample.num_bytes_clear = subsample.num_bytes_clear; fake_subsample.num_bytes_encrypted = 0; fake_subsample.block_offset = 0; @@ -167,6 +176,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( if (subsample.num_bytes_encrypted > 0) { fake_sample.buffers.input_data_length = subsample.num_bytes_encrypted; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + subsample.num_bytes_encrypted; + } fake_subsample.num_bytes_clear = 0; fake_subsample.num_bytes_encrypted = subsample.num_bytes_encrypted; fake_subsample.block_offset = subsample.block_offset; diff --git a/oemcrypto/test/oec_device_features.cpp b/oemcrypto/test/oec_device_features.cpp index 49f0d8c..d440159 100644 --- a/oemcrypto/test/oec_device_features.cpp +++ b/oemcrypto/test/oec_device_features.cpp @@ -10,7 +10,9 @@ #include +#include "log.h" #include "oec_test_data.h" +#include "string_conversions.h" #include "test_sleep.h" namespace wvoec { @@ -68,6 +70,12 @@ void DeviceFeatures::Initialize() { provisioning_method == OEMCrypto_BootCertificateChain || provisioning_method == OEMCrypto_DrmReprovisioning; printf("loads_certificate = %s.\n", loads_certificate ? "true" : "false"); + if (rsa_test_key().empty()) { + set_rsa_test_key( + std::vector(kTestRSAPKCS8PrivateKeyInfo2_2048, + kTestRSAPKCS8PrivateKeyInfo2_2048 + + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048))); + } generic_crypto = (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_Generic_Encrypt(buffer, 0, buffer, 0, iv, @@ -129,6 +137,9 @@ void DeviceFeatures::Initialize() { case LOAD_TEST_RSA_KEY: printf("LOAD_TEST_RSA_KEY: Call LoadTestRSAKey before deriving keys.\n"); break; + case PRELOADED_RSA_KEY: + printf("PRELOADED_RSA_KEY: Device has test RSA key baked in.\n"); + break; case TEST_PROVISION_30: printf("TEST_PROVISION_30: Device provisioned with OEM Cert.\n"); break; @@ -175,9 +186,10 @@ void DeviceFeatures::PickDerivedKey() { return; case OEMCrypto_DrmCertificate: case OEMCrypto_DrmReprovisioning: - if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { - derive_key_method = LOAD_TEST_RSA_KEY; - } + derive_key_method = + (OEMCrypto_ERROR_NOT_IMPLEMENTED == OEMCrypto_LoadTestRSAKey()) + ? PRELOADED_RSA_KEY + : LOAD_TEST_RSA_KEY; return; case OEMCrypto_Keybox: if (OEMCrypto_ERROR_NOT_IMPLEMENTED != diff --git a/oemcrypto/test/oec_device_features.h b/oemcrypto/test/oec_device_features.h index ec0a8fc..d1e4d7d 100644 --- a/oemcrypto/test/oec_device_features.h +++ b/oemcrypto/test/oec_device_features.h @@ -38,6 +38,7 @@ class DeviceFeatures { LOAD_TEST_RSA_KEY, // Call LoadTestRSAKey before deriving keys. TEST_PROVISION_30, // Device has OEM Certificate installed. TEST_PROVISION_40, // Device has Boot Certificate Chain installed. + PRELOADED_RSA_KEY, // Device has test RSA key baked in. }; enum DeriveMethod derive_key_method; @@ -70,6 +71,16 @@ class DeviceFeatures { // Get a list of output types that should be tested. const std::vector& GetOutputTypes(); + // If the device has a baked in cert, then this is the public key that should + // be used for testing. + const std::vector& rsa_test_key() const { return rsa_test_key_; }; + void set_rsa_test_key(const std::vector& rsa_test_key) { + rsa_test_key_ = rsa_test_key; + } + void set_rsa_test_key(std::vector&& rsa_test_key) { + rsa_test_key_ = std::move(rsa_test_key); + } + private: // Decide which method should be used to derive session keys, based on // supported featuers. @@ -82,6 +93,7 @@ class DeviceFeatures { // A list of possible output types. std::vector output_types_; bool initialized_ = false; + std::vector rsa_test_key_; }; // There is one global set of features for the version of OEMCrypto being diff --git a/oemcrypto/test/oec_session_util.cpp b/oemcrypto/test/oec_session_util.cpp index e562c3f..4836d11 100644 --- a/oemcrypto/test/oec_session_util.cpp +++ b/oemcrypto/test/oec_session_util.cpp @@ -554,7 +554,7 @@ void ProvisioningRoundTrip::VerifyLoadFailed() { } void Provisioning40RoundTrip::PrepareSession(bool is_oem_key) { - const size_t buffer_size = 5000; // Make sure it is large enough. + const size_t buffer_size = 10240; // Make sure it is large enough. std::vector public_key(buffer_size); size_t public_key_size = buffer_size; std::vector public_key_signature(buffer_size); @@ -616,7 +616,7 @@ OEMCryptoResult Provisioning40RoundTrip::LoadDRMCertResponse() { } void Provisioning40CastRoundTrip::PrepareSession() { - const size_t buffer_size = 5000; // Make sure it is large enough. + const size_t buffer_size = 10240; // Make sure it is large enough. std::vector public_key(buffer_size); size_t public_key_size = buffer_size; std::vector public_key_signature(buffer_size); @@ -1918,10 +1918,9 @@ void Session::LoadOEMCert(bool verify_cert) { void Session::SetTestRsaPublicKey() { public_ec_.reset(); - public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo( - kTestRSAPKCS8PrivateKeyInfo2_2048, - sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); - ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key #2"; + public_rsa_ = + util::RsaPublicKey::LoadPrivateKeyInfo(global_features.rsa_test_key()); + ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key"; } void Session::SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type, diff --git a/oemcrypto/test/oemcrypto_basic_test.cpp b/oemcrypto/test/oemcrypto_basic_test.cpp index 42f638a..eae6766 100644 --- a/oemcrypto/test/oemcrypto_basic_test.cpp +++ b/oemcrypto/test/oemcrypto_basic_test.cpp @@ -2,17 +2,79 @@ // source code may only be used and distributed under the Widevine // License Agreement. // - #include "oemcrypto_basic_test.h" +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "OEMCryptoCENC.h" #include "clock.h" -#include "jsmn.h" #include "log.h" #include "oemcrypto_corpus_generator_helper.h" #include "oemcrypto_resource_test.h" #include "test_sleep.h" +void PrintTo(const jsmntype_t& type, std::ostream* out) { + switch (type) { + case JSMN_UNDEFINED: + *out << "Undefined"; + return; + case JSMN_OBJECT: + *out << "Object"; + return; + case JSMN_ARRAY: + *out << "Array"; + return; + case JSMN_STRING: + *out << "String"; + return; + case JSMN_PRIMITIVE: + *out << "Primitive"; + return; + } + *out << "Unknown(" << static_cast(type) << ')'; +} + namespace wvoec { +namespace { +// Counts the number of ancestor tokens of the provided |root_index| token. +// The result does not count the root itself. +// +// JSMN tokens specify the count of immediate ancessor tokens, but +// not the total. +// - Primitives never have children +// - Strings have 0 if they are a value, and 1 if they are the +// name of an object member +// - Objects have the count of members (each key-value pair is 1, +// regardless of the value's children elements) +// - Arrays have the count of elements (regardless of the values members) +// +int32_t JsmnAncestorCount(const std::vector& tokens, + int32_t root_index) { + if (root_index >= static_cast(tokens.size())) return 0; + int32_t count = 0; + int32_t iter = root_index; + int32_t remainder = 1; + while (remainder > 0 && iter < static_cast(tokens.size())) { + const int32_t child_count = tokens[iter].size; + remainder += child_count; + count += child_count; + iter++; + remainder--; + } + return count; +} +} // namespace + void OEMCryptoClientTest::SetUp() { ::testing::Test::SetUp(); wvutil::TestSleep::SyncFakeClock(); @@ -156,7 +218,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 18.6. Tests last updated 2024-06-04"; + "OEMCrypto unit tests for API 18.7. Tests last updated 2024-09-04"; cout << " " << log_message << "\n"; cout << " " << "These tests are part of Android U." @@ -165,7 +227,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, 6); + EXPECT_EQ(ODK_MINOR_VERSION, 7); EXPECT_EQ(kCurrentAPI, static_cast(ODK_MAJOR_VERSION)); OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); EXPECT_GT(level, OEMCrypto_Level_Unknown); @@ -286,26 +348,143 @@ TEST_F(OEMCryptoClientTest, CheckNullBuildInformationAPI17) { } } +// Verifies that OEMCrypto_BuildInformation() is behaving as expected +// by assigning appropriate values to the build info size. +TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputLengthAPI17) { + constexpr size_t kZero = 0; + constexpr char kNullChar = '\0'; + + // Allocating single byte to avoid potential null dereference. + std::string build_info(1, kNullChar); + size_t build_info_length = 0; + + OEMCryptoResult result = + OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + + ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_GT(build_info_length, kZero) + << "Signaling ERROR_SHORT_BUFFER should have assigned a length"; + + // Force a ERROR_SHORT_BUFFER using a non-zero value. + // Note: It is assumed that vendors will provide more than a single + // character of info. + const size_t second_attempt_length = + (build_info_length >= 2) ? build_info_length / 2 : 1; + build_info.assign(second_attempt_length, kNullChar); + build_info_length = build_info.size(); + + result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER) + << "second_attempt_length = " << second_attempt_length + << ", build_info_length" << build_info_length; + // OEM specified build info length should be larger than the + // original length if returning ERROR_SHORT_BUFFER. + ASSERT_GT(build_info_length, second_attempt_length); + + // Final attempt with a buffer large enough buffer, padding to + // ensure the caller truncates. + constexpr size_t kBufferPadSize = 42; + const size_t expected_length = build_info_length; + const size_t final_attempt_length = expected_length + kBufferPadSize; + build_info.assign(final_attempt_length, kNullChar); + build_info_length = build_info.size(); + + result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + + ASSERT_EQ(result, OEMCrypto_SUCCESS) + << "final_attempt_length = " << final_attempt_length + << ", expected_length = " << expected_length + << ", build_info_length = " << build_info_length; + // Ensure not empty. + ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty"; + // Ensure it was truncated down from the padded length. + ASSERT_LT(build_info_length, final_attempt_length) + << "Should have truncated from oversized buffer: expected_length = " + << expected_length; + // Ensure the real length is within the size originally specified. + // OK if final length is smaller than estimated length. + ASSERT_LE(build_info_length, expected_length); +} + +// Verifies that OEMCrypto_BuildInformation() is behaving as expected +// by checking the resulting contents. +// Does not validate whether output if valid JSON for v18. +TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputContentAPI17) { + constexpr size_t kZero = 0; + constexpr char kNullChar = '\0'; + + // Allocating single byte to avoid potential null dereference. + std::string build_info(1, kNullChar); + size_t build_info_length = 0; + OEMCryptoResult result = + OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_GT(build_info_length, kZero) + << "Signaling ERROR_SHORT_BUFFER should have assigned a length"; + + // Expect successful acquisition of build information. + const size_t expected_length = build_info_length; + build_info.assign(expected_length, kNullChar); + result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + ASSERT_EQ(result, OEMCrypto_SUCCESS) + << "expected_length = " << expected_length + << ", build_info_length = " << build_info_length; + // Ensure not empty. + ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty"; + // Ensure the real length is within the size originally specified. + ASSERT_LE(build_info_length, expected_length) + << "Cannot specify success if buffer was too small"; + build_info.resize(build_info_length); + + // Ensure there isn't a trailing null byte. + ASSERT_NE(build_info.back(), kNullChar) + << "Build info must not contain trailing null byte"; + + // Ensure all build info characters are printable, or a limited + // set of white space characters (case of JSON build info). + const auto is_valid_build_info_white_space = [](const char& ch) -> bool { + constexpr char kSpace = ' '; + constexpr char kLineFeed = '\n'; + constexpr char kTab = '\t'; + return ch == kLineFeed || ch == kTab || ch == kSpace; + }; + const auto is_valid_build_info_char = [&](const char& ch) -> bool { + return ::isprint(ch) || is_valid_build_info_white_space(ch); + }; + ASSERT_TRUE(std::all_of(build_info.begin(), build_info.end(), + is_valid_build_info_char)) + << "Build info is not printable: " << wvutil::b2a_hex(build_info); + + // Ensure build info isn't just white space. + ASSERT_FALSE(std::all_of(build_info.begin(), build_info.end(), + is_valid_build_info_white_space)) + << "Build info is just white space: " << wvutil::b2a_hex(build_info); +} + TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { - std::string build_info; - OEMCryptoResult sts = OEMCrypto_BuildInformation(&build_info[0], nullptr); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); - size_t buf_length = 0; + constexpr char kNullChar = '\0'; + constexpr size_t kZero = 0; + + // Step 1: Get Build Info + size_t buffer_length = 0; // OEMCrypto must allow |buffer| to be null so long as |buffer_length| // is provided and initially set to zero. - sts = OEMCrypto_BuildInformation(nullptr, &buf_length); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - build_info.resize(buf_length); - const size_t max_final_size = buf_length; - sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_LE(buf_length, max_final_size); - build_info.resize(buf_length); + OEMCryptoResult result = OEMCrypto_BuildInformation(nullptr, &buffer_length); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, result); + ASSERT_GT(buffer_length, kZero); + std::string build_info(buffer_length, kNullChar); + const size_t max_final_size = buffer_length; + result = OEMCrypto_BuildInformation(&build_info[0], &buffer_length); + ASSERT_EQ(OEMCrypto_SUCCESS, result); + ASSERT_LE(buffer_length, max_final_size); + build_info.resize(buffer_length); + + // Step 2: Parse as JSON jsmn_parser p; jsmn_init(&p); std::vector tokens; - int32_t num_tokens = + const int32_t num_tokens = jsmn_parse(&p, build_info.c_str(), build_info.size(), nullptr, 0); EXPECT_GT(num_tokens, 0) << "Failed to parse BuildInformation as JSON, parse returned " @@ -313,45 +492,186 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { tokens.resize(num_tokens); jsmn_init(&p); - int32_t jsmn_result = jsmn_parse(&p, build_info.c_str(), build_info.size(), - tokens.data(), num_tokens); + const int32_t jsmn_result = jsmn_parse( + &p, build_info.c_str(), build_info.size(), tokens.data(), num_tokens); EXPECT_GE(jsmn_result, 0) << "Failed to parse BuildInformation as JSON, parse returned " << jsmn_result << "for following build info: " << build_info; - std::map expected; - expected["soc_vendor"] = JSMN_STRING; - expected["soc_model"] = JSMN_STRING; - expected["ta_ver"] = JSMN_STRING; - expected["uses_opk"] = JSMN_PRIMITIVE; - expected["tee_os"] = JSMN_STRING; - expected["tee_os_ver"] = JSMN_STRING; + // Step 3a: Ensure info is a single JSON object. + const jsmntok_t& object_token = tokens[0]; + ASSERT_EQ(object_token.type, JSMN_OBJECT) + << "Build info is not a JSON object: " << build_info; - // for values in token - // build string from start,end - // check for existence in map - // check if value matches expectation - // remove from map - for (int i = 0; i < jsmn_result; i++) { - jsmntok_t token = tokens[i]; - std::string key = build_info.substr(token.start, token.end - token.start); - if (expected.find(key) != expected.end()) { - EXPECT_EQ(expected.find(key)->second, tokens[i + 1].type) - << "Type is incorrect for key " << key; - expected.erase(key); + // Step 3b: Verify schema of defined fields. + + // Required fields must be present in the build information, + // and be of the correct type. + const std::map kRequiredFields = { + // SOC manufacturer name + {"soc_vendor", JSMN_STRING}, + // SOC model name + {"soc_model", JSMN_STRING}, + // TA version in string format eg "1.12.3+tag", "2.0" + {"ta_ver", JSMN_STRING}, + // [bool] Whether TA was built with Widevine's OPK + {"uses_opk", JSMN_PRIMITIVE}, + // Trusted OS intended to run the TA, eg "Trusty", "QSEE", "OP-TEE" + {"tee_os", JSMN_STRING}, + // Version of Trusted OS intended to run the TA + {"tee_os_ver", JSMN_STRING}, + // [bool] Whether this is a debug build of the TA + // Not forcing behavior until implementations fix + // them self + // {"is_debug", JSMN_PRIMITIVE}, + }; + + const std::string kSpecialCaseReeKey = "ree"; + + // Optional fields may be present in the build information; + // if they are, then the must be the correct type. + const std::map kOptionalFields = { + // Name of company or entity that provides OEMCrypto. + {"implementor", JSMN_STRING}, + // Git commit hash of the code repository. + {"git_commit", JSMN_STRING}, + // ISO 8601 formatted timestamp of the time the TA was compiled + {"build_timestamp", JSMN_STRING}, + // Whether this was built with FACTORY_MODE_ONLY defined + {"is_factory_mode", JSMN_PRIMITIVE}, + // ... provide information about liboemcrypto.so + // Special case, see kOptionalReeFields for details. + {kSpecialCaseReeKey, JSMN_OBJECT}, + // Technically required, but several implementations + // do not implement this fields. + {"is_debug", JSMN_PRIMITIVE}, + }; + + // A set of the required fields found when examining the + // build information, use to verify all fields are present. + std::set found_required_fields; + // Stores the tokens of the "ree" field, if set, used to + // validate its content. + std::vector ree_tokens; + bool has_ree_info = false; + + // Start: first object key token + // Condition: key-value pair (2 tokens) + // Iter: next key-value pair (2 tokens) + for (int32_t i = 1; (i + 1) < jsmn_result; i += 2) { + // JSMN objects consist of pairs of key-value pairs (keys are always + // JSMN_STRING). + const jsmntok_t& key_token = tokens[i]; + ASSERT_EQ(key_token.type, JSMN_STRING) + << "Bad object key: i = " << i << ", build_info = " << build_info; + const jsmntok_t& value_token = tokens[i + 1]; + + const std::string key = + build_info.substr(key_token.start, key_token.end - key_token.start); + if (kRequiredFields.find(key) != kRequiredFields.end()) { + ASSERT_EQ(value_token.type, kRequiredFields.at(key)) + << "Unexpected required field type: field = " << key + << ", build_info = " << build_info; + found_required_fields.insert(key); + } else if (kOptionalFields.find(key) != kOptionalFields.end()) { + ASSERT_EQ(value_token.type, kOptionalFields.at(key)) + << "Unexpected optional field type: field = " << key + << ", build_info = " << build_info; + } // Do not validate vendor fields. + + if (key == kSpecialCaseReeKey) { + // Store the tokens of the "ree" field for additional validation. + const int32_t first_ree_field_index = i + 2; + const int32_t ree_token_count = JsmnAncestorCount(tokens, i + 1); + const auto first_ree_field_iter = tokens.begin() + first_ree_field_index; + ree_tokens.assign(first_ree_field_iter, + first_ree_field_iter + ree_token_count); + has_ree_info = true; } + + // Skip potential nested tokens. + i += JsmnAncestorCount(tokens, i + 1); } - // if map is not empty, return false - if (expected.size() > 0) { - std::string missing; - for (auto e : expected) { - missing.append(e.first); - missing.append(" "); + // Step 3c: Ensure all required fields were found. + if (found_required_fields.size() != kRequiredFields.size()) { + // Generate a list of all the missing fields. + std::string missing_fields; + for (const auto& required_field : kRequiredFields) { + if (found_required_fields.find(required_field.first) != + found_required_fields.end()) + continue; + if (!missing_fields.empty()) { + missing_fields.append(", "); + } + missing_fields.push_back('"'); + missing_fields.append(required_field.first); + missing_fields.push_back('"'); } - FAIL() << "JSON does not contain all required keys. Missing keys: [" - << missing << "] in string " << build_info; + + FAIL() << "Build info JSON object does not contain all required keys; " + << "missing_fields = [" << missing_fields + << "], build_info = " << build_info; + return; } + + // If no "ree" field tokens, then end here. + if (!has_ree_info) return; + // Step 4a: Verify "ree" object scheme. + ASSERT_FALSE(ree_tokens.empty()) + << "REE field was specified, but contents were empty: build_info = " + << build_info; + + // The optional field "ree", if present, must follow the required + // format. + const std::map kReeRequiredFields = { + // liboemcrypto.so version in string format eg "2.15.0+tag" + {"liboemcrypto_ver", JSMN_STRING}, + // git hash of code that compiled liboemcrypto.so + {"git_commit", JSMN_STRING}, + // ISO 8601 timestamp for when liboemcrypto.so was built + {"build_timestamp", JSMN_STRING}}; + + found_required_fields.clear(); + for (int32_t i = 0; (i + 1) < static_cast(ree_tokens.size()); + i += 2) { + const jsmntok_t& key_token = ree_tokens[i]; + ASSERT_EQ(key_token.type, JSMN_STRING) + << "Bad REE object key: i = " << i << ", build_info = " << build_info; + const jsmntok_t& value_token = ree_tokens[i + 1]; + + const std::string key = + build_info.substr(key_token.start, key_token.end - key_token.start); + if (kReeRequiredFields.find(key) != kReeRequiredFields.end()) { + ASSERT_EQ(value_token.type, kReeRequiredFields.at(key)) + << "Unexpected optional REE field type: ree_field = " << key + << ", build_info = " << build_info; + found_required_fields.insert(key); + } // Do not validate vendor fields. + + // Skip potential nested tokens. + i += JsmnAncestorCount(ree_tokens, i + 1); + } + + // Step 4b: Ensure all required fields of the "ree" object were found. + if (found_required_fields.size() == kReeRequiredFields.size()) return; + // Generate a list of all the missing REE fields. + std::string missing_ree_fields; + for (const auto& required_field : kReeRequiredFields) { + if (found_required_fields.find(required_field.first) != + found_required_fields.end()) + continue; + if (!missing_ree_fields.empty()) { + missing_ree_fields.append(", "); + } + missing_ree_fields.push_back('"'); + missing_ree_fields.append(required_field.first); + missing_ree_fields.push_back('"'); + } + + FAIL() << "REE info JSON object does not contain all required keys; " + << "missing_ree_fields = [" << missing_ree_fields + << "], build_info = " << build_info; } TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) { diff --git a/oemcrypto/test/oemcrypto_decrypt_test.cpp b/oemcrypto/test/oemcrypto_decrypt_test.cpp index a61c893..63e598a 100644 --- a/oemcrypto/test/oemcrypto_decrypt_test.cpp +++ b/oemcrypto/test/oemcrypto_decrypt_test.cpp @@ -121,38 +121,6 @@ TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) { EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); } -// 'cbc1' mode is no longer supported in v16 -TEST_P(OEMCryptoLicenseTest, RejectCbc1API16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - vector key_handle; - OEMCryptoResult sts; - sts = GetKeyHandleIntoVector(session_.session_id(), - session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, - OEMCrypto_CipherMode_CBCS, key_handle); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Create a zero pattern to indicate this is 'cbc1' - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), - &sample_description, 1, &pattern); - EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); -} - TEST_P(OEMCryptoLicenseTest, RejectCbcsWithBlockOffset) { ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.cpp b/oemcrypto/test/oemcrypto_session_tests_helper.cpp index 2a3d525..175bb51 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.cpp +++ b/oemcrypto/test/oemcrypto_session_tests_helper.cpp @@ -70,6 +70,9 @@ void SessionUtil::EnsureTestROT() { case DeviceFeatures::TEST_PROVISION_30: // Can use oem certificate to install test rsa key. break; + case DeviceFeatures::PRELOADED_RSA_KEY: + // There is already a key. + break; case wvoec::DeviceFeatures::TEST_PROVISION_40: // OEM certificate is retrieved from the server. break; diff --git a/oemcrypto/test/oemcrypto_usage_table_test.cpp b/oemcrypto/test/oemcrypto_usage_table_test.cpp index 40491b4..ba62ad3 100644 --- a/oemcrypto/test/oemcrypto_usage_table_test.cpp +++ b/oemcrypto/test/oemcrypto_usage_table_test.cpp @@ -90,6 +90,9 @@ TEST_F(OEMCryptoSessionTests, Provisioning_IncrementCounterAPI18) { // Test that successive calls to PrepAndSignLicenseRequest only increase // the license count in the ODK message TEST_F(OEMCryptoSessionTests, License_IncrementCounterAPI18) { + if (OEMCrypto_SecurityLevel() == OEMCrypto_Level3) { + GTEST_SKIP() << "L3 does not support license counter."; + } Session s; s.open(); LicenseRoundTrip license_messages(&s); @@ -132,6 +135,9 @@ TEST_F(OEMCryptoSessionTests, MasterGeneration_IncrementCounterAPI18) { GTEST_SKIP() << "Usage table not supported, so master generation number " "does not need to be checked."; } + if (OEMCrypto_SecurityLevel() == OEMCrypto_Level3) { + GTEST_SKIP() << "L3 does not support license counter."; + } Session s1; s1.open(); LicenseRoundTrip license_messages(&s1);