diff --git a/libwvdrmengine/oemcrypto/test/ota_keybox_test.cpp b/libwvdrmengine/oemcrypto/test/ota_keybox_test.cpp index 225680b4..ec8377e8 100644 --- a/libwvdrmengine/oemcrypto/test/ota_keybox_test.cpp +++ b/libwvdrmengine/oemcrypto/test/ota_keybox_test.cpp @@ -135,6 +135,11 @@ static const uint8_t TestKeyPKCS8[] = { 0x13, 0xf3, 0xa7, 0xdb, 0xdb, 0x5d, 0x89, 0x2d, 0xd7, 0x02, 0x96, 0xaf, 0xeb, 0x72, 0x8d, 0xd5, 0x56, 0x3b, 0x3a}; +constexpr size_t kInitialOtaKeyboxRequestSize = 8 * 1024; // 8 kB. +// TODO(fredgc): Make sure that partners can use a test cert when +// |use_test_key| parameter of OEMCrypto_GenerateOTARequest() is true. +constexpr uint32_t kUseTestKey = 1; + // TODO(fredgc): duplicate code. Move to common util package. // Return a printable string from data. If all the characters are printable, // then just use the string. Otherwise, convert to hex. @@ -192,9 +197,7 @@ TEST_F(OTAKeyboxProvisioningTest, BasicTest) { } cout << " " << "OTA Keybox functions supported. Device needs provisioning." << endl; - // TODO(fredgc): Make sure that partners can use a test cert when use_test_key - // is true. - constexpr uint32_t use_test_key = 1; + size_t request_length = 0; std::vector request; @@ -203,12 +206,12 @@ TEST_F(OTAKeyboxProvisioningTest, BasicTest) { ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_GenerateOTARequest(session_id, nullptr, &request_length, - use_test_key)); + kUseTestKey)); ASSERT_NE(request_length, 0u); request.resize(request_length); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GenerateOTARequest(session_id, request.data(), - &request_length, use_test_key)); + &request_length, kUseTestKey)); ASSERT_GT(request_length, kMinimumRequestLength); request.resize(request_length); // First 16 bytes should match the label for Option 1 or 2. @@ -292,9 +295,56 @@ TEST_F(OTAKeyboxProvisioningTest, BasicTest) { // Finally, send the response back to the device. EXPECT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ProcessOTAKeybox(session_id, response.data(), - response.size(), use_test_key)); + response.size(), kUseTestKey)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CloseSession(session_id)); // After installation, the keybox should be valid. EXPECT_EQ(OEMCrypto_IsKeyboxValid(), OEMCrypto_SUCCESS); } + +TEST_F(OTAKeyboxProvisioningTest, StressTest) { + static constexpr size_t kStressRequestCount = 1000; + const OEMCrypto_ProvisioningMethod method = OEMCrypto_GetProvisioningMethod(); + if (method != OEMCrypto_Keybox) { + std::cout << "Skipping for non keybox-based devices: method = " + << ProvisioningMethodName(method) << std::endl; + GTEST_SKIP() << "Device is not keybox based: method = " + << ProvisioningMethodName(method); + return; + } + OEMCrypto_SESSION session_id; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_OpenSession(&session_id)) + << "Failed to open OTA keybox session"; + // First request is to ensure operation is supported. + std::vector request(kInitialOtaKeyboxRequestSize); + size_t request_size = request.size(); + OEMCryptoResult result = OEMCrypto_GenerateOTARequest( + session_id, request.data(), &request_size, kUseTestKey); + if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) { + // Not a failure, just skip the test. + OEMCrypto_CloseSession(session_id); + std::cout << "Skipping for device which do not support " + << "OTA keybox provisioning" << std::endl; + GTEST_SKIP() << "OTA Keybox not supported"; + return; + } + + for (size_t i = 0; i < kStressRequestCount; i++) { + request.resize(kInitialOtaKeyboxRequestSize); + request_size = request.size(); + result = OEMCrypto_GenerateOTARequest(session_id, request.data(), + &request_size, kUseTestKey); + if (result == OEMCrypto_ERROR_SHORT_BUFFER) { + request.resize(request_size); + result = OEMCrypto_GenerateOTARequest(session_id, request.data(), + &request_size, kUseTestKey); + } + if (result != OEMCrypto_SUCCESS) { + OEMCrypto_CloseSession(session_id); + std::cout << "Failed on attempt " << (i + 1) << std::endl; + FAIL() << "Failed to generate request: i = " << i; + return; + } + } + OEMCrypto_CloseSession(session_id); +} } // namespace wvoec