Do digesting, and sometimes padding, in SW when HW doesnt.
The keymaster1 specification only requires HW modules to implement
SHA256 out of the list of keymaster1 digest modes. That would force
many keys to be software only, and would break legacy scenarios. This
change uses SoftKeymasterDevice to front keymaster modules that don't
implement the full suite of digests, quietly inserting KM_DIGEST_NONE
and KM_PAD_NONE into key generation/import requests when necessary, then
performing the digesting, and sometimes padding, in software, then
delegating crypto operations to the hardware.
This is only done for RSA and EC keys. Software digesting isn't
possible for HMAC or AES-GCM keys.
Note that this is not the complete fix for the bug. Some changes in
keystore are also required, coming in another CL.
Bug: 22529223
Change-Id: I740572eb11341fb0659085309da01d5cbcd3854d
diff --git a/android_keymaster_test.cpp b/android_keymaster_test.cpp
index af829e6..f0ae2f1 100644
--- a/android_keymaster_test.cpp
+++ b/android_keymaster_test.cpp
@@ -18,6 +18,9 @@
#include <string>
#include <vector>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
#include <hardware/keymaster0.h>
#include <keymaster/key_factory.h>
#include <keymaster/soft_keymaster_context.h>
@@ -51,6 +54,11 @@
return vector<T>(array, array + len);
}
+/**
+ * KeymasterEnforcement class for use in testing. It's permissive in the sense that it doesn't
+ * check cryptoperiods, but restrictive in the sense that the clock never advances (so rate-limited
+ * keys will only work once).
+ */
class TestKeymasterEnforcement : public KeymasterEnforcement {
public:
TestKeymasterEnforcement() : KeymasterEnforcement(3, 3) {}
@@ -65,10 +73,13 @@
virtual bool ValidateTokenSignature(const hw_auth_token_t& /* token */) const { return true; }
};
+/**
+ * Variant of SoftKeymasterContext that provides a TestKeymasterEnforcement.
+ */
class TestKeymasterContext : public SoftKeymasterContext {
public:
- TestKeymasterContext(keymaster0_device_t* keymaster0 = nullptr)
- : SoftKeymasterContext(keymaster0) {}
+ TestKeymasterContext() {}
+ TestKeymasterContext(const string& root_of_trust) : SoftKeymasterContext(root_of_trust) {}
KeymasterEnforcement* enforcement_policy() override { return &test_policy_; }
@@ -76,6 +87,9 @@
TestKeymasterEnforcement test_policy_;
};
+/**
+ * Test instance creator that builds a pure software keymaster1 implementations.
+ */
class SoftKeymasterTestInstanceCreator : public Keymaster1TestInstanceCreator {
public:
keymaster1_device_t* CreateDevice() const override {
@@ -84,10 +98,14 @@
return device->keymaster_device();
}
- bool algorithm_in_hardware(keymaster_algorithm_t) const override { return false; }
+ bool algorithm_in_km0_hardware(keymaster_algorithm_t) const override { return false; }
int keymaster0_calls() const override { return 0; }
};
+/**
+ * Test instance creator that builds keymaster1 instances which wrap a faked hardware keymaster0
+ * instance, with or without EC support.
+ */
class Keymaster0AdapterTestInstanceCreator : public Keymaster1TestInstanceCreator {
public:
Keymaster0AdapterTestInstanceCreator(bool support_ec) : support_ec_(support_ec) {}
@@ -110,12 +128,12 @@
counting_keymaster0_device_ = new Keymaster0CountingWrapper(keymaster0_device);
- SoftKeymasterDevice* keymaster =
- new SoftKeymasterDevice(new TestKeymasterContext(counting_keymaster0_device_));
+ SoftKeymasterDevice* keymaster = new SoftKeymasterDevice(new TestKeymasterContext);
+ keymaster->SetHardwareDevice(counting_keymaster0_device_);
return keymaster->keymaster_device();
}
- bool algorithm_in_hardware(keymaster_algorithm_t algorithm) const override {
+ bool algorithm_in_km0_hardware(keymaster_algorithm_t algorithm) const override {
switch (algorithm) {
case KM_ALGORITHM_RSA:
return true;
@@ -132,10 +150,35 @@
bool support_ec_;
};
+/**
+ * Test instance creator that builds a SoftKeymasterDevice which wraps a fake hardware keymaster1
+ * instance, with minimal digest support.
+ */
+class Sha256OnlyKeymaster1TestInstanceCreator : public Keymaster1TestInstanceCreator {
+ keymaster1_device_t* CreateDevice() const {
+ std::cerr << "Creating keymaster1-backed device that supports only SHA256";
+
+ // fake_device doesn't leak because device (below) takes ownership of it.
+ keymaster1_device_t* fake_device = make_device_sha256_only(
+ (new SoftKeymasterDevice(new TestKeymasterContext("PseudoHW")))->keymaster_device());
+
+ // device doesn't leak; it's cleaned up by device->keymaster_device()->common.close().
+ SoftKeymasterDevice* device = new SoftKeymasterDevice(new TestKeymasterContext);
+ device->SetHardwareDevice(fake_device);
+
+ return device->keymaster_device();
+ }
+
+ bool algorithm_in_km0_hardware(keymaster_algorithm_t) const override { return false; }
+ int keymaster0_calls() const override { return 0; }
+ int minimal_digest_set() const override { return true; }
+};
+
static auto test_params = testing::Values(
InstanceCreatorPtr(new SoftKeymasterTestInstanceCreator),
InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(true /* support_ec */)),
- InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(false /* support_ec */)));
+ InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(false /* support_ec */)),
+ InstanceCreatorPtr(new Sha256OnlyKeymaster1TestInstanceCreator));
typedef Keymaster1Test CheckSupported;
INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, CheckSupported, test_params);
@@ -218,17 +261,38 @@
keymaster_digest_t* digests;
ASSERT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
KM_PURPOSE_SIGN, &digests, &len));
- EXPECT_TRUE(
- ResponseContains({KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
- KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512},
- digests, len));
+ if (GetParam()->minimal_digest_set()) {
+ EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA_2_256}, digests, len));
+ } else {
+ EXPECT_TRUE(
+ ResponseContains({KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+ KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512},
+ digests, len));
+ }
+ free(digests);
+
+ ASSERT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
+ KM_PURPOSE_ENCRYPT, &digests, &len));
+ if (GetParam()->minimal_digest_set()) {
+ EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA_2_256}, digests, len));
+ } else {
+ EXPECT_TRUE(
+ ResponseContains({KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+ KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512},
+ digests, len));
+ }
free(digests);
ASSERT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_EC,
KM_PURPOSE_SIGN, &digests, &len));
- EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
- KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512},
- digests, len));
+ if (GetParam()->minimal_digest_set()) {
+ EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA_2_256}, digests, len));
+ } else {
+ EXPECT_TRUE(
+ ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+ KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512},
+ digests, len));
+ }
free(digests);
EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
@@ -237,9 +301,13 @@
ASSERT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_HMAC,
KM_PURPOSE_SIGN, &digests, &len));
- EXPECT_TRUE(ResponseContains({KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384,
- KM_DIGEST_SHA_2_512, KM_DIGEST_SHA1},
- digests, len));
+ if (GetParam()->minimal_digest_set()) {
+ EXPECT_TRUE(ResponseContains({KM_DIGEST_SHA_2_256}, digests, len));
+ } else {
+ EXPECT_TRUE(ResponseContains({KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384,
+ KM_DIGEST_SHA_2_512, KM_DIGEST_SHA1},
+ digests, len));
+ }
free(digests);
EXPECT_EQ(0, GetParam()->keymaster0_calls());
@@ -341,7 +409,7 @@
// Check specified tags are all present, and in the right set.
AuthorizationSet crypto_params;
AuthorizationSet non_crypto_params;
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA)) {
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA)) {
EXPECT_NE(0U, hw_enforced().size());
EXPECT_NE(0U, sw_enforced().size());
crypto_params.push_back(hw_enforced());
@@ -359,7 +427,7 @@
EXPECT_TRUE(contains(crypto_params, TAG_RSA_PUBLIC_EXPONENT, 3));
EXPECT_FALSE(contains(non_crypto_params, TAG_RSA_PUBLIC_EXPONENT, 3));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(1, GetParam()->keymaster0_calls());
}
@@ -381,7 +449,7 @@
// Check specified tags are all present, and in the right set.
AuthorizationSet crypto_params;
AuthorizationSet non_crypto_params;
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC)) {
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC)) {
EXPECT_NE(0U, hw_enforced().size());
EXPECT_NE(0U, sw_enforced().size());
crypto_params.push_back(hw_enforced());
@@ -397,7 +465,7 @@
EXPECT_TRUE(contains(crypto_params, TAG_KEY_SIZE, 224));
EXPECT_FALSE(contains(non_crypto_params, TAG_KEY_SIZE, 224));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(1, GetParam()->keymaster0_calls());
}
@@ -412,7 +480,7 @@
}
TEST_P(NewKeyGeneration, EcdsaInvalidSize) {
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
ASSERT_EQ(
KM_ERROR_UNKNOWN_ERROR,
GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(KM_DIGEST_NONE)));
@@ -421,7 +489,7 @@
KM_ERROR_UNSUPPORTED_KEY_SIZE,
GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(KM_DIGEST_NONE)));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(1, GetParam()->keymaster0_calls());
}
@@ -433,7 +501,7 @@
<< "Failed to generate size: " << size;
}
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -510,7 +578,7 @@
ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
EXPECT_EQ(original, sw_enforced());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(1, GetParam()->keymaster0_calls());
}
@@ -526,7 +594,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -540,7 +608,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -556,6 +624,9 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
TEST_P(SigningOperationsTest, RsaPkcs1Sha256Success) {
@@ -567,7 +638,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -580,7 +651,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -601,7 +672,7 @@
string signature;
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&signature));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -636,7 +707,7 @@
size_t input_consumed;
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &result, &input_consumed));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -653,7 +724,7 @@
// Another abort should fail
EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -666,7 +737,7 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -681,7 +752,7 @@
begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PSS);
ASSERT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_SIGN, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -693,7 +764,7 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -706,7 +777,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -720,7 +791,7 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -731,7 +802,7 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -742,7 +813,18 @@
string signature;
SignMessage(message, &signature, KM_DIGEST_SHA_2_256);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+ EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaSha384Success) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(
+ KM_DIGEST_SHA_2_384)));
+ string message(1024, 'a');
+ string signature;
+ SignMessage(message, &signature, KM_DIGEST_SHA_2_384);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -756,9 +838,9 @@
ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
string result;
size_t input_consumed;
- EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &result, &input_consumed));
+ EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -785,7 +867,7 @@
}
}
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(digests.size() * key_sizes.size() * 3,
static_cast<size_t>(GetParam()->keymaster0_calls()));
}
@@ -801,6 +883,10 @@
}
TEST_P(SigningOperationsTest, HmacSha1Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate other digests for HMAC.
+ return;
+
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA1)
@@ -814,6 +900,10 @@
}
TEST_P(SigningOperationsTest, HmacSha224Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate other digests for HMAC.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_224)
@@ -827,6 +917,10 @@
}
TEST_P(SigningOperationsTest, HmacSha256Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate other digests for HMAC.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_256)
@@ -840,6 +934,10 @@
}
TEST_P(SigningOperationsTest, HmacSha384Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate other digests for HMAC.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_384)
@@ -854,6 +952,10 @@
}
TEST_P(SigningOperationsTest, HmacSha512Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate other digests for HMAC.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_512)
@@ -870,12 +972,12 @@
// TODO(swillden): unified API should generate an error on key generation.
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
- .Digest(KM_DIGEST_SHA_2_512)
- .Authorization(TAG_MIN_MAC_LENGTH, 512)));
+ .Digest(KM_DIGEST_SHA_2_256)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)));
string message = "12345678901234567890123456789012";
string signature;
- MacMessage(message, &signature, 512);
- ASSERT_EQ(64U, signature.size());
+ MacMessage(message, &signature, 160);
+ ASSERT_EQ(20U, signature.size());
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -911,10 +1013,12 @@
string key = make_string(key_data);
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -945,10 +1049,13 @@
0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -979,10 +1086,13 @@
0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1017,10 +1127,13 @@
0x12, 0x0c, 0x4f, 0x2d, 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1046,10 +1159,12 @@
0x1d, 0x41, 0x79, 0xbc, 0x89, 0x1d, 0x87, 0xa6,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1081,10 +1196,12 @@
0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1118,10 +1235,12 @@
0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58,
};
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
- CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ if (!GetParam()->minimal_digest_set()) {
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+ CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+ }
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1169,7 +1288,7 @@
SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE, KM_PAD_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1184,10 +1303,46 @@
SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
VerifyMessage(message, signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
+TEST_P(VerificationOperationsTest, RsaPssSha224Success) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(512, 3)
+ .Digest(KM_DIGEST_SHA_2_224)
+ .Padding(KM_PAD_RSA_PSS)));
+ // Use large message, which won't work without digesting.
+ string message(1024, 'a');
+ string signature;
+ SignMessage(message, &signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PSS);
+ VerifyMessage(message, signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PSS);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+ // Verify with OpenSSL.
+ string pubkey;
+ EXPECT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &pubkey));
+
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(pubkey.data());
+ unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+ d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size()));
+ ASSERT_TRUE(pkey.get());
+
+ EVP_MD_CTX digest_ctx;
+ EVP_MD_CTX_init(&digest_ctx);
+ EVP_PKEY_CTX* pkey_ctx;
+ EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, EVP_sha224(), nullptr /* engine */,
+ pkey.get()));
+ EXPECT_EQ(1, EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+ EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size()));
+ EXPECT_EQ(1,
+ EVP_DigestVerifyFinal(&digest_ctx, reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size()));
+ EVP_MD_CTX_cleanup(&digest_ctx);
+}
+
TEST_P(VerificationOperationsTest, RsaPssSha256CorruptSignature) {
GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(512, 3)
@@ -1209,7 +1364,7 @@
EXPECT_EQ(message.size(), input_consumed);
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1235,7 +1390,7 @@
EXPECT_EQ(message.size(), input_consumed);
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1249,10 +1404,45 @@
SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
VerifyMessage(message, signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
+TEST_P(VerificationOperationsTest, RsaPks1Sha224Success) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(512, 3)
+ .Digest(KM_DIGEST_SHA_2_224)
+ .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+ // Use large message, which won't work without digesting.
+ string message(1024, 'a');
+ string signature;
+ SignMessage(message, &signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PKCS1_1_5_SIGN);
+ VerifyMessage(message, signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PKCS1_1_5_SIGN);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+ // Verify with OpenSSL.
+ string pubkey;
+ EXPECT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &pubkey));
+
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(pubkey.data());
+ unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+ d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size()));
+ ASSERT_TRUE(pkey.get());
+
+ EVP_MD_CTX digest_ctx;
+ EVP_MD_CTX_init(&digest_ctx);
+ EVP_PKEY_CTX* pkey_ctx;
+ EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, EVP_sha224(), nullptr /* engine */,
+ pkey.get()));
+ EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size()));
+ EXPECT_EQ(1,
+ EVP_DigestVerifyFinal(&digest_ctx, reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size()));
+ EVP_MD_CTX_cleanup(&digest_ctx);
+}
+
TEST_P(VerificationOperationsTest, RsaPkcs1Sha256CorruptSignature) {
GenerateKey(AuthorizationSetBuilder()
.RsaSigningKey(512, 3)
@@ -1274,7 +1464,7 @@
EXPECT_EQ(message.size(), input_consumed);
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1300,28 +1490,23 @@
EXPECT_EQ(message.size(), input_consumed);
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
TEST_P(VerificationOperationsTest, RsaAllDigestAndPadCombinations) {
- // Get all supported digests and padding modes.
- size_t digests_len;
- keymaster_digest_t* digests;
- ASSERT_EQ(KM_ERROR_OK,
- device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &digests,
- &digests_len));
+ vector<keymaster_digest_t> digests = {
+ KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+ KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+ };
- size_t padding_modes_len;
- keymaster_padding_t* padding_modes;
- ASSERT_EQ(KM_ERROR_OK,
- device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN,
- &padding_modes, &padding_modes_len));
+ vector<keymaster_padding_t> padding_modes{
+ KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN, KM_PAD_RSA_PSS,
+ };
- // Try them.
int trial_count = 0;
- for (keymaster_padding_t padding_mode : make_vector(padding_modes, padding_modes_len)) {
- for (keymaster_digest_t digest : make_vector(digests, digests_len)) {
+ for (keymaster_padding_t padding_mode : padding_modes) {
+ for (keymaster_digest_t digest : digests) {
if (digest != KM_DIGEST_NONE && padding_mode == KM_PAD_NONE)
// Digesting requires padding
continue;
@@ -1397,10 +1582,7 @@
}
}
- free(padding_modes);
- free(digests);
-
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(trial_count * 4, GetParam()->keymaster0_calls());
}
@@ -1412,7 +1594,7 @@
SignMessage(message, &signature, KM_DIGEST_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1424,27 +1606,10 @@
SignMessage(message, &signature, KM_DIGEST_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
-TEST_P(VerificationOperationsTest, EcdsaTooLong) {
- ASSERT_EQ(KM_ERROR_OK,
- GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(KM_DIGEST_NONE)));
- string message = "1234567890123456789012345678901234";
- string signature;
-
- AuthorizationSet begin_params(client_params());
- begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
- EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
- string output;
- size_t input_consumed;
- EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &output, &input_consumed));
-
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
- EXPECT_EQ(2, GetParam()->keymaster0_calls());
-}
-
TEST_P(VerificationOperationsTest, EcdsaSlightlyTooLong) {
ASSERT_EQ(KM_ERROR_OK,
GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(521).Digest(KM_DIGEST_NONE)));
@@ -1458,7 +1623,7 @@
message[65] ^= 7;
VerifyMessage(message, signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(5, GetParam()->keymaster0_calls());
}
@@ -1472,7 +1637,7 @@
SignMessage(message, &signature, KM_DIGEST_SHA_2_256);
VerifyMessage(message, signature, KM_DIGEST_SHA_2_256);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
// Just for giggles, try verifying with the wrong digest.
@@ -1487,7 +1652,63 @@
EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
}
+TEST_P(VerificationOperationsTest, EcdsaSha224Success) {
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(
+ KM_DIGEST_SHA_2_224)));
+
+ string message = "12345678901234567890123456789012";
+ string signature;
+ SignMessage(message, &signature, KM_DIGEST_SHA_2_224);
+ VerifyMessage(message, signature, KM_DIGEST_SHA_2_224);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+ EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+ // Just for giggles, try verifying with the wrong digest.
+ AuthorizationSet begin_params(client_params());
+ begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+ EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+ string result;
+ size_t input_consumed;
+ EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+ EXPECT_EQ(message.size(), input_consumed);
+ EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+}
+
+TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndKeySizes) {
+ keymaster_digest_t digests[] = {
+ KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
+ KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+ };
+ size_t key_sizes[] = {224, 256, 384, 521};
+
+ string message = "1234567890";
+ string signature;
+
+ for (auto key_size : key_sizes) {
+ AuthorizationSetBuilder builder;
+ builder.EcdsaSigningKey(key_size);
+ for (auto digest : digests)
+ builder.Digest(digest);
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(builder));
+
+ for (auto digest : digests) {
+ SignMessage(message, &signature, digest);
+ VerifyMessage(message, signature, digest);
+ }
+ }
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+ EXPECT_EQ(static_cast<int>(array_length(key_sizes) * (1 + 3 * array_length(digests))),
+ GetParam()->keymaster0_calls());
+}
+
TEST_P(VerificationOperationsTest, HmacSha1Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate missing digests for HMAC.
+ return;
+
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA1)
@@ -1501,6 +1722,10 @@
}
TEST_P(VerificationOperationsTest, HmacSha224Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate missing digests for HMAC.
+ return;
+
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_224)
@@ -1553,6 +1778,10 @@
}
TEST_P(VerificationOperationsTest, HmacSha384Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate missing digests for HMAC.
+ return;
+
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_384)
@@ -1566,6 +1795,10 @@
}
TEST_P(VerificationOperationsTest, HmacSha512Success) {
+ if (GetParam()->minimal_digest_set())
+ // Can't emulate missing digests for HMAC.
+ return;
+
GenerateKey(AuthorizationSetBuilder()
.HmacKey(128)
.Digest(KM_DIGEST_SHA_2_512)
@@ -1592,7 +1825,7 @@
// TODO(swillden): Verify that the exported key is actually usable to verify signatures.
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -1605,7 +1838,7 @@
// TODO(swillden): Verify that the exported key is actually usable to verify signatures.
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -1617,7 +1850,7 @@
string export_data;
ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -1630,7 +1863,7 @@
string export_data;
ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -1666,18 +1899,18 @@
KM_KEY_FORMAT_PKCS8, pk8_key));
// Check values derived from the key.
- EXPECT_TRUE(contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
- : sw_enforced(),
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+ : sw_enforced(),
TAG_ALGORITHM, KM_ALGORITHM_RSA));
- EXPECT_TRUE(contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
- : sw_enforced(),
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+ : sw_enforced(),
TAG_KEY_SIZE, 1024));
- EXPECT_TRUE(contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
- : sw_enforced(),
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+ : sw_enforced(),
TAG_RSA_PUBLIC_EXPONENT, 65537U));
// And values provided by AndroidKeymaster
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
else
EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
@@ -1688,35 +1921,7 @@
SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE, KM_PAD_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
- EXPECT_EQ(4, GetParam()->keymaster0_calls());
-}
-
-TEST_P(ImportKeyTest, OldApiRsaSuccess) {
- string pk8_key = read_file("rsa_privkey_pk8.der");
- ASSERT_EQ(633U, pk8_key.size());
-
- // NOTE: This will break when the keymaster0 APIs are removed from keymaster1. But at that
- // point softkeymaster will no longer support keymaster0 APIs anyway.
- uint8_t* key_blob;
- size_t key_blob_length;
- ASSERT_EQ(0,
- device()->import_keypair(device(), reinterpret_cast<const uint8_t*>(pk8_key.data()),
- pk8_key.size(), &key_blob, &key_blob_length));
- set_key_blob(key_blob, key_blob_length);
-
- string message(1024 / 8, 'a');
- AuthorizationSet begin_params; // Don't use client data.
- begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
- begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
- AuthorizationSet update_params;
- AuthorizationSet output_params;
- string signature =
- ProcessMessage(KM_PURPOSE_SIGN, message, begin_params, update_params, &output_params);
- ProcessMessage(KM_PURPOSE_VERIFY, message, signature, begin_params, update_params,
- &output_params);
-
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1755,15 +1960,15 @@
KM_KEY_FORMAT_PKCS8, pk8_key));
// Check values derived from the key.
- EXPECT_TRUE(
- contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC) ? hw_enforced() : sw_enforced(),
- TAG_ALGORITHM, KM_ALGORITHM_EC));
- EXPECT_TRUE(
- contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC) ? hw_enforced() : sw_enforced(),
- TAG_KEY_SIZE, 256));
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+ : sw_enforced(),
+ TAG_ALGORITHM, KM_ALGORITHM_EC));
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+ : sw_enforced(),
+ TAG_KEY_SIZE, 256));
// And values provided by AndroidKeymaster
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
else
EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
@@ -1774,7 +1979,7 @@
SignMessage(message, &signature, KM_DIGEST_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1787,15 +1992,15 @@
KM_KEY_FORMAT_PKCS8, pk8_key));
// Check values derived from the key.
- EXPECT_TRUE(
- contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC) ? hw_enforced() : sw_enforced(),
- TAG_ALGORITHM, KM_ALGORITHM_EC));
- EXPECT_TRUE(
- contains(GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC) ? hw_enforced() : sw_enforced(),
- TAG_KEY_SIZE, 256));
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+ : sw_enforced(),
+ TAG_ALGORITHM, KM_ALGORITHM_EC));
+ EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+ : sw_enforced(),
+ TAG_KEY_SIZE, 256));
// And values provided by AndroidKeymaster
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
else
EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
@@ -1806,7 +2011,7 @@
SignMessage(message, &signature, KM_DIGEST_NONE);
VerifyMessage(message, signature, KM_DIGEST_NONE);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1856,7 +2061,7 @@
string message = "Hello World!";
string signature;
MacMessage(message, &signature, 256);
- VerifyMessage(message, signature, KM_DIGEST_SHA_2_256);
+ VerifyMac(message, signature);
EXPECT_EQ(0, GetParam()->keymaster0_calls());
}
@@ -1878,7 +2083,7 @@
// Unpadded RSA is deterministic
EXPECT_EQ(ciphertext1, ciphertext2);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -1896,7 +2101,7 @@
EXPECT_EQ(expected_plaintext, plaintext);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1914,7 +2119,7 @@
size_t input_consumed;
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &result, &input_consumed));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -1957,7 +2162,7 @@
EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -1978,7 +2183,28 @@
// OAEP randomizes padding so every result should be different.
EXPECT_NE(ciphertext1, ciphertext2);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepSha224Success) {
+ size_t key_size = 768;
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(key_size, 3)
+ .Padding(KM_PAD_RSA_OAEP)
+ .Digest(KM_DIGEST_SHA_2_224)));
+
+ string message = "Hello";
+ string ciphertext1 = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+ EXPECT_EQ(key_size / 8, ciphertext1.size());
+
+ string ciphertext2 = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+ EXPECT_EQ(key_size / 8, ciphertext2.size());
+
+ // OAEP randomizes padding so every result should be different.
+ EXPECT_NE(ciphertext1, ciphertext2);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -1995,7 +2221,24 @@
string plaintext = DecryptMessage(ciphertext, KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
EXPECT_EQ(message, plaintext);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepSha224RoundTrip) {
+ size_t key_size = 768;
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(key_size, 3)
+ .Padding(KM_PAD_RSA_OAEP)
+ .Digest(KM_DIGEST_SHA_2_224)));
+ string message = "Hello World!";
+ string ciphertext = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+ EXPECT_EQ(key_size / 8, ciphertext.size());
+
+ string plaintext = DecryptMessage(ciphertext, KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+ EXPECT_EQ(message, plaintext);
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -2011,11 +2254,15 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
TEST_P(EncryptionOperationsTest, RsaOaepUnauthorizedDigest) {
+ if (GetParam()->minimal_digest_set())
+ // We don't have two supported digests, so we can't try authorizing one and using another.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.RsaEncryptionKey(512, 3)
.Padding(KM_PAD_RSA_OAEP)
@@ -2029,11 +2276,16 @@
begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA1);
EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
+ if (GetParam()->minimal_digest_set())
+ // We don't have two supported digests, so we can't try encrypting with one and decrypting
+ // with another.
+ return;
+
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
.RsaEncryptionKey(768, 3)
.Padding(KM_PAD_RSA_OAEP)
@@ -2052,7 +2304,7 @@
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
EXPECT_EQ(0U, result.size());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -2073,7 +2325,7 @@
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
EXPECT_EQ(0U, result.size());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -2100,7 +2352,7 @@
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
EXPECT_EQ(0U, result.size());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -2108,16 +2360,16 @@
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
string message = "Hello World!";
- string ciphertext1 = EncryptMessage(string(message), KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+ string ciphertext1 = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(512U / 8, ciphertext1.size());
- string ciphertext2 = EncryptMessage(string(message), KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+ string ciphertext2 = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(512U / 8, ciphertext2.size());
// PKCS1 v1.5 randomizes padding so every result should be different.
EXPECT_NE(ciphertext1, ciphertext2);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -2125,16 +2377,55 @@
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
string message = "Hello World!";
- string ciphertext = EncryptMessage(string(message), KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+ string ciphertext = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(512U / 8, ciphertext.size());
string plaintext = DecryptMessage(ciphertext, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(message, plaintext);
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
+TEST_P(EncryptionOperationsTest, RsaRoundTripAllCombinations) {
+ size_t key_size = 2048;
+ ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(key_size, 3)
+ .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT)
+ .Padding(KM_PAD_RSA_OAEP)
+ .Digest(KM_DIGEST_NONE)
+ .Digest(KM_DIGEST_MD5)
+ .Digest(KM_DIGEST_SHA1)
+ .Digest(KM_DIGEST_SHA_2_224)
+ .Digest(KM_DIGEST_SHA_2_256)
+ .Digest(KM_DIGEST_SHA_2_384)
+ .Digest(KM_DIGEST_SHA_2_512)));
+
+ string message = "Hello World!";
+
+ keymaster_padding_t padding_modes[] = {KM_PAD_RSA_OAEP, KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
+ keymaster_digest_t digests[] = {
+ KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+ KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+ };
+
+ for (auto padding : padding_modes)
+ for (auto digest : digests) {
+ if (padding == KM_PAD_RSA_OAEP && digest == KM_DIGEST_NONE)
+ // OAEP requires a digest.
+ continue;
+
+ string ciphertext = EncryptMessage(message, digest, padding);
+ EXPECT_EQ(key_size / 8, ciphertext.size());
+
+ string plaintext = DecryptMessage(ciphertext, digest, padding);
+ EXPECT_EQ(message, plaintext);
+ }
+
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+ EXPECT_EQ(40, GetParam()->keymaster0_calls());
+}
+
TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) {
ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
@@ -2149,24 +2440,7 @@
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
EXPECT_EQ(0U, result.size());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
- EXPECT_EQ(2, GetParam()->keymaster0_calls());
-}
-
-TEST_P(EncryptionOperationsTest, RsaPkcs1InvalidDigest) {
- ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
- .RsaEncryptionKey(512, 3)
- .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT)
- .Digest(KM_DIGEST_NONE)));
- string message = "Hello World!";
- string result;
-
- AuthorizationSet begin_params(client_params());
- begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
- begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE); // Any digest is invalid
- EXPECT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
-
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -2189,7 +2463,7 @@
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
EXPECT_EQ(0U, result.size());
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(4, GetParam()->keymaster0_calls());
}
@@ -2201,7 +2475,7 @@
begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
EXPECT_EQ(2, GetParam()->keymaster0_calls());
}
@@ -2211,7 +2485,7 @@
ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_ENCRYPT));
ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_DECRYPT));
- if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_EC))
+ if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
EXPECT_EQ(3, GetParam()->keymaster0_calls());
}
@@ -3339,5 +3613,32 @@
EXPECT_EQ(1, GetParam()->keymaster0_calls());
}
+TEST(SoftKeymasterWrapperTest, CheckKeymaster1Device) {
+ // Make a good fake device, and wrap it.
+ SoftKeymasterDevice* good_fake(new SoftKeymasterDevice(new TestKeymasterContext));
+
+ // Wrap it and check it.
+ SoftKeymasterDevice* good_fake_wrapper(new SoftKeymasterDevice(new TestKeymasterContext));
+ good_fake_wrapper->SetHardwareDevice(good_fake->keymaster_device());
+ EXPECT_TRUE(good_fake_wrapper->Keymaster1DeviceIsGood());
+
+ // Close and clean up wrapper and wrapped
+ good_fake_wrapper->keymaster_device()->common.close(good_fake_wrapper->hw_device());
+
+ // Make a "bad" (doesn't support all digests) device;
+ keymaster1_device_t* sha256_only_fake = make_device_sha256_only(
+ (new SoftKeymasterDevice(new TestKeymasterContext("256")))->keymaster_device());
+
+ // Wrap it and check it.
+ SoftKeymasterDevice* sha256_only_fake_wrapper(
+ (new SoftKeymasterDevice(new TestKeymasterContext)));
+ sha256_only_fake_wrapper->SetHardwareDevice(sha256_only_fake);
+ EXPECT_FALSE(sha256_only_fake_wrapper->Keymaster1DeviceIsGood());
+
+ // Close and clean up wrapper and wrapped
+ sha256_only_fake_wrapper->keymaster_device()->common.close(
+ sha256_only_fake_wrapper->hw_device());
+}
+
} // namespace test
} // namespace keymaster