cryptohome: TpmEccAuthBlock checks inputs
Check in TpmEccAuthBlock's Create() and Derive() operations whether
the auth inputs have all necessary fields, instead of crashing when
they're missing.
BUG=b:219612327
TEST=cros_workon_make --board=$BOARD --test cryptohome
Change-Id: I99db5864936a29eefd9f14c896324e57f7a39337
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3624299
Tested-by: Maksim Ivanov <emaxx@chromium.org>
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Betul Soysal <betuls@google.com>
Reviewed-by: Greg Kerr <kerrnel@chromium.org>
diff --git a/cryptohome/auth_blocks/auth_block_unittest.cc b/cryptohome/auth_blocks/auth_block_unittest.cc
index cbb0a2d..8c3b6c9 100644
--- a/cryptohome/auth_blocks/auth_block_unittest.cc
+++ b/cryptohome/auth_blocks/auth_block_unittest.cc
@@ -1495,6 +1495,40 @@
->local_crypto_error());
}
+// Test the Create operation fails when there's no user_input provided.
+TEST(TpmEccAuthBlockTest, CreateFailNoUserInput) {
+ // Prepare.
+ std::string obfuscated_username = "OBFUSCATED_USERNAME";
+ NiceMock<MockTpm> tpm;
+ NiceMock<MockCryptohomeKeysManager> cryptohome_keys_manager;
+ TpmEccAuthBlock auth_block(&tpm, &cryptohome_keys_manager);
+ AuthInput auth_input = {.obfuscated_username = obfuscated_username};
+
+ // Test.
+ AuthBlockState auth_state;
+ KeyBlobs vkk_data;
+ EXPECT_EQ(auth_block.Create(auth_input, &auth_state, &vkk_data)
+ ->local_crypto_error(),
+ CryptoError::CE_OTHER_CRYPTO);
+}
+
+// Test the Create operation fails when there's no obfuscated_username provided.
+TEST(TpmEccAuthBlockTest, CreateFailNoObfuscated) {
+ // Prepare.
+ brillo::SecureBlob user_input(20, 'C');
+ NiceMock<MockTpm> tpm;
+ NiceMock<MockCryptohomeKeysManager> cryptohome_keys_manager;
+ TpmBoundToPcrAuthBlock auth_block(&tpm, &cryptohome_keys_manager);
+ AuthInput auth_input = {.user_input = user_input};
+
+ // Test.
+ AuthBlockState auth_state;
+ KeyBlobs vkk_data;
+ EXPECT_EQ(auth_block.Create(auth_input, &auth_state, &vkk_data)
+ ->local_crypto_error(),
+ CryptoError::CE_OTHER_CRYPTO);
+}
+
// Test SealToPcr in TpmEccAuthBlock::Create failed as expected.
TEST(TpmEccAuthBlockTest, CreateSealToPcrFailTest) {
// Set up inputs to the test.
@@ -1679,6 +1713,22 @@
EXPECT_EQ(key_out_data.vkk_iv.value(), key_out_data.chaps_iv.value());
}
+// Test TpmEccAuthBlock::Derive failure when there's no auth_input provided.
+TEST(TpmEccAuthBlockTest, DeriveFailNoAuthInput) {
+ TpmEccAuthBlockState auth_block_state = GetDefaultEccAuthBlockState();
+ AuthBlockState auth_state{.state = std::move(auth_block_state)};
+
+ NiceMock<MockTpm> tpm;
+ NiceMock<MockCryptohomeKeysManager> cryptohome_keys_manager;
+ TpmEccAuthBlock auth_block(&tpm, &cryptohome_keys_manager);
+
+ KeyBlobs key_out_data;
+ AuthInput auth_input;
+ EXPECT_EQ(auth_block.Derive(auth_input, auth_state, &key_out_data)
+ ->local_crypto_error(),
+ CryptoError::CE_OTHER_CRYPTO);
+}
+
// Test GetEccAuthValue in TpmEccAuthBlock::Derive failed as expected.
TEST(TpmEccAuthBlockTest, DeriveGetEccAuthFailTest) {
TpmEccAuthBlockState auth_block_state = GetDefaultEccAuthBlockState();
diff --git a/cryptohome/auth_blocks/tpm_ecc_auth_block.cc b/cryptohome/auth_blocks/tpm_ecc_auth_block.cc
index 9901ac3..2cac66a 100644
--- a/cryptohome/auth_blocks/tpm_ecc_auth_block.cc
+++ b/cryptohome/auth_blocks/tpm_ecc_auth_block.cc
@@ -342,6 +342,21 @@
CryptoStatus TpmEccAuthBlock::Create(const AuthInput& auth_input,
AuthBlockState* auth_block_state,
KeyBlobs* key_blobs) {
+ if (!auth_input.user_input.has_value()) {
+ LOG(ERROR) << "Missing user_input";
+ return MakeStatus<CryptohomeCryptoError>(
+ CRYPTOHOME_ERR_LOC(kLocTpmEccAuthBlockNoUserInputInCreate),
+ ErrorActionSet({ErrorAction::kDevCheckUnexpectedState}),
+ CryptoError::CE_OTHER_CRYPTO);
+ }
+ if (!auth_input.obfuscated_username.has_value()) {
+ LOG(ERROR) << "Missing obfuscated_username";
+ return MakeStatus<CryptohomeCryptoError>(
+ CRYPTOHOME_ERR_LOC(kLocTpmEccAuthBlockNoUsernameInCreate),
+ ErrorActionSet({ErrorAction::kDevCheckUnexpectedState}),
+ CryptoError::CE_OTHER_CRYPTO);
+ }
+
return TryCreate(auth_input, auth_block_state, key_blobs,
kTryCreateMaxRetryCount);
}
@@ -349,6 +364,14 @@
CryptoStatus TpmEccAuthBlock::Derive(const AuthInput& auth_input,
const AuthBlockState& state,
KeyBlobs* key_out_data) {
+ if (!auth_input.user_input.has_value()) {
+ LOG(ERROR) << "Missing user_input";
+ return MakeStatus<CryptohomeCryptoError>(
+ CRYPTOHOME_ERR_LOC(kLocTpmEccAuthBlockNoUserInputInDerive),
+ ErrorActionSet({ErrorAction::kDevCheckUnexpectedState}),
+ CryptoError::CE_OTHER_CRYPTO);
+ }
+
const TpmEccAuthBlockState* auth_state;
if (!(auth_state = std::get_if<TpmEccAuthBlockState>(&state.state))) {
DLOG(FATAL) << "Invalid AuthBlockState";
diff --git a/cryptohome/error/locations.h b/cryptohome/error/locations.h
index 661a42c..6c78d5c 100644
--- a/cryptohome/error/locations.h
+++ b/cryptohome/error/locations.h
@@ -541,6 +541,12 @@
kLocAuthFactorCreateKeyBlobsFailedInCreate = 357,
/* ./auth_factor/auth_factor.cc */
kLocAuthFactorDeriveFailedInAuth = 358,
+ /* ./auth_blocks/tpm_ecc_auth_block.cc */
+ kLocTpmEccAuthBlockNoUserInputInCreate = 359,
+ /* ./auth_blocks/tpm_ecc_auth_block.cc */
+ kLocTpmEccAuthBlockNoUsernameInCreate = 360,
+ /* ./auth_blocks/tpm_ecc_auth_block.cc */
+ kLocTpmEccAuthBlockNoUserInputInDerive = 361,
// End of generated content.
};
// The enum value should not exceed 65535, otherwise we need to adjust the way