diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index c2be6496..e8248cba 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -239,6 +239,12 @@ class CryptoEngine { size_t GetNumberOfOpenSessions() { return sessions_.size(); } + size_t GetMaxNumberOfSessions() { + // An arbitrary limit for mock implementation. + static const size_t kMaxSupportedOEMCryptoSessions = 64; + return kMaxSupportedOEMCryptoSessions; + } + void set_current_session_(SessionContext* current) { current_session_ = current; } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 39e4eba0..3dc97cce 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -80,6 +80,11 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) { LOGI("-- OEMCryptoResult OEMCrypto_OpenSession" "(OEMCrypto_SESSION *session)\n"); } + if (crypto_engine->GetNumberOfOpenSessions() >= + crypto_engine->GetMaxNumberOfSessions()) { + LOGE("[OEMCrypto_OpenSession(): failed due to too many sessions]"); + return OEMCrypto_ERROR_TOO_MANY_SESSIONS; + } SessionId sid = crypto_engine->CreateSession(); *session = (OEMCrypto_SESSION)sid; if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { @@ -1040,8 +1045,7 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* maximum) { LOGI("-- OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(%p)\n", maximum); } if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const size_t kMaxSupportedOEMCryptoSessions = 64; - *maximum = kMaxSupportedOEMCryptoSessions; + *maximum = crypto_engine->GetMaxNumberOfSessions(); return OEMCrypto_SUCCESS; } diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 3a6e7128..eecd6036 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -1746,12 +1746,26 @@ TEST_F(OEMCryptoClientTest, MaxSessionsOpenClose) { ASSERT_EQ(0, sessions_count); size_t max_sessions; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetMaxNumberOfSessions(&max_sessions)); - ASSERT_GT(max_sessions, 0); + // We expect OEMCrypto implementations support at least 8 sessions. + const size_t kMinimumSupportedMaxNumberOfSessions = 8u; + ASSERT_GE(max_sessions, kMinimumSupportedMaxNumberOfSessions); vector sessions; - for (int i = 0; i < max_sessions; i++) { + // Limit the number of sessions for testing. + const size_t kMaxNumberOfSessionsForTesting = 0x100u; + for (int i = 0; i < kMaxNumberOfSessionsForTesting; i++) { OEMCrypto_SESSION session_id; - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_OpenSession(&session_id)); + OEMCryptoResult sts = OEMCrypto_OpenSession(&session_id); + // GetMaxNumberOfSessions might be an estimate. We allow OEMCrypto to report + // a max that is less than what is actually supported. Assume the number + // returned is |max|. OpenSessions shall not fail if number of active + // sessions is less than |max|; OpenSessions should fail with + // OEMCrypto_ERROR_TOO_MANY_SESSIONS if too many sessions are open. + if (sts != OEMCrypto_SUCCESS) { + ASSERT_EQ(OEMCrypto_ERROR_TOO_MANY_SESSIONS, sts); + ASSERT_GE(i, max_sessions); + break; + } ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); ASSERT_EQ(i + 1, sessions_count); @@ -1763,6 +1777,13 @@ TEST_F(OEMCryptoClientTest, MaxSessionsOpenClose) { OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); ASSERT_EQ(sessions.size() - i - 1, sessions_count); } + if (sessions.size() == kMaxNumberOfSessionsForTesting) { + printf( + " MaxSessionsOpenClose: reaches " + "kMaxNumberOfSessionsForTesting(%zu). GetMaxNumberOfSessions = %zu. " + "ERROR_TOO_MANY_SESSIONS not tested.", + kMaxNumberOfSessionsForTesting, max_sessions); + } } TEST_F(OEMCryptoClientTest, GenerateNonce) {