blob: 3bb5430152dbb0aebd07cbc584025f2b0350209b [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <algorithm>
#include <fstream>
#include <UniquePtr.h>
#include <gtest/gtest.h>
#include <openssl/engine.h>
#include <hardware/keymaster0.h>
#include <keymaster/android_keymaster.h>
#include <keymaster/android_keymaster_messages.h>
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/keymaster_tags.h>
#include <keymaster/soft_keymaster_context.h>
#include "android_keymaster_test_utils.h"
#include "trusty_keymaster_device.h"
#include "openssl_utils.h"
using std::string;
using std::ifstream;
using std::istreambuf_iterator;
static keymaster::AndroidKeymaster *impl_ = nullptr;
extern "C" {
int __android_log_print();
}
int __android_log_print() {
return 0;
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
// Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return result;
}
int trusty_keymaster_connect() {
impl_ = new keymaster::AndroidKeymaster(new keymaster::SoftKeymasterContext(nullptr), 16);
}
void trusty_keymaster_disconnect() {
delete static_cast<keymaster::AndroidKeymaster*>(priv_);
}
template <typename Req, typename Rsp>
static int fake_call(keymaster::AndroidKeymaster* device,
void (keymaster::AndroidKeymaster::*method)(const Req&, Rsp*), void* in_buf,
uint32_t in_size, void* out_buf, uint32_t* out_size) {
Req req;
const uint8_t* in = static_cast<uint8_t*>(in_buf);
req.Deserialize(&in, in + in_size);
Rsp rsp;
(device->*method)(req, &rsp);
*out_size = rsp.SerializedSize();
uint8_t* out = static_cast<uint8_t*>(out_buf);
rsp.Serialize(out, out + *out_size);
return 0;
}
int trusty_keymaster_call(uint32_t cmd, void* in_buf, uint32_t in_size, void* out_buf,
uint32_t* out_size) {
switch (cmd) {
case KM_GENERATE_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::GenerateKey, in_buf, in_size,
out_buf, out_size);
case KM_BEGIN_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::BeginOperation, in_buf, in_size,
out_buf, out_size);
case KM_UPDATE_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::UpdateOperation, in_buf, in_size,
out_buf, out_size);
case KM_FINISH_OPERATION:
return fake_call(impl_, &keymaster::AndroidKeymaster::FinishOperation, in_buf, in_size,
out_buf, out_size);
case KM_IMPORT_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::ImportKey, in_buf, in_size, out_buf,
out_size);
case KM_EXPORT_KEY:
return fake_call(impl_, &keymaster::AndroidKeymaster::ExportKey, in_buf, in_size, out_buf,
out_size);
}
return -EINVAL;
}
namespace keymaster {
namespace test {
class TrustyKeymasterTest : public testing::Test {
protected:
TrustyKeymasterTest() : device(NULL) {}
keymaster_rsa_keygen_params_t build_rsa_params() {
keymaster_rsa_keygen_params_t rsa_params;
rsa_params.public_exponent = 65537;
rsa_params.modulus_size = 2048;
return rsa_params;
}
uint8_t* build_message(size_t length) {
uint8_t* msg = new uint8_t[length];
memset(msg, 'a', length);
return msg;
}
size_t dsa_message_len(const keymaster_dsa_keygen_params_t& params) {
switch (params.key_size) {
case 256:
case 1024:
return 48;
case 2048:
case 4096:
return 72;
default:
// Oops.
return 0;
}
}
TrustyKeymasterDevice device;
};
class Malloc_Delete {
public:
Malloc_Delete(void* p) : p_(p) {}
~Malloc_Delete() { free(p_); }
private:
void* p_;
};
typedef TrustyKeymasterTest KeyGenTest;
TEST_F(KeyGenTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
}
TEST_F(KeyGenTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t ec_params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &ec_params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
}
typedef TrustyKeymasterTest SigningTest;
TEST_F(SigningTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(message_len, siglen);
}
TEST_F(SigningTest, RsaShortMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8 - 1;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, device.sign_data(&sig_params, ptr, size, message.get(),
message_len, &signature, &siglen));
}
TEST_F(SigningTest, RsaLongMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8 + 1;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, device.sign_data(&sig_params, ptr, size, message.get(),
message_len, &signature, &siglen));
}
TEST_F(SigningTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
TEST_F(SigningTest, EcdsaEmptyMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
TEST_F(SigningTest, EcdsaLargeMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
size_t message_len = 1024 * 7;
UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
// contents of message don't matter.
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_GT(siglen, 69U);
EXPECT_LT(siglen, 73U);
}
typedef TrustyKeymasterTest VerificationTest;
TEST_F(VerificationTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message.get(), message_len,
signature, siglen));
}
TEST_F(VerificationTest, RsaBadSignature) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
signature[siglen / 2]++;
EXPECT_EQ(
KM_ERROR_VERIFICATION_FAILED,
device.verify_data(&sig_params, ptr, size, message.get(), message_len, signature, siglen));
}
TEST_F(VerificationTest, RsaBadMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
message[0]++;
EXPECT_EQ(
KM_ERROR_VERIFICATION_FAILED,
device.verify_data(&sig_params, ptr, size, message.get(), message_len, signature, siglen));
}
TEST_F(VerificationTest, RsaShortMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH,
device.verify_data(&sig_params, ptr, size, message.get(), message_len - 1, signature,
siglen));
}
TEST_F(VerificationTest, RsaLongMessage) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len + 1));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH,
device.verify_data(&sig_params, ptr, size, message.get(), message_len + 1, signature,
siglen));
}
TEST_F(VerificationTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message,
array_size(message) - 1, signature, siglen));
}
TEST_F(VerificationTest, EcdsaLargeMessageSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
size_t message_len = 1024 * 7;
UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
// contents of message don't matter.
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, ptr, size, message.get(), message_len,
signature, siglen));
}
static string read_file(const string& file_name) {
ifstream file_stream(file_name, std::ios::binary);
istreambuf_iterator<char> file_begin(file_stream);
istreambuf_iterator<char> file_end;
return string(file_begin, file_end);
}
typedef TrustyKeymasterTest ImportKeyTest;
TEST_F(ImportKeyTest, RsaSuccess) {
string pk8_key = read_file("../../../../system/keymaster/rsa_privkey_pk8.der");
ASSERT_EQ(633U, pk8_key.size());
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(KM_ERROR_OK, device.import_keypair(reinterpret_cast<const uint8_t*>(pk8_key.data()),
pk8_key.size(), &key, &size));
Malloc_Delete key_deleter(key);
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_size = 1024 /* key size */ / 8;
UniquePtr<uint8_t[]> message(new uint8_t[message_size]);
memset(message.get(), 'a', message_size);
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message.get(), message_size,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message.get(), message_size,
signature, siglen));
}
TEST_F(ImportKeyTest, EcdsaSuccess) {
string pk8_key = read_file("../../../../system/keymaster/ec_privkey_pk8.der");
ASSERT_EQ(138U, pk8_key.size());
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(KM_ERROR_OK, device.import_keypair(reinterpret_cast<const uint8_t*>(pk8_key.data()),
pk8_key.size(), &key, &size));
Malloc_Delete key_deleter(key);
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message,
array_size(message) - 1, signature, siglen));
}
struct EVP_PKEY_CTX_Delete {
void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
};
static void VerifySignature(const uint8_t* key, size_t key_len, const uint8_t* signature,
size_t signature_len, const uint8_t* message, size_t message_len) {
UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(d2i_PUBKEY(NULL, &key, key_len));
ASSERT_TRUE(pkey.get() != NULL);
UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(EVP_PKEY_CTX_new(pkey.get(), NULL));
ASSERT_TRUE(ctx.get() != NULL);
ASSERT_EQ(1, EVP_PKEY_verify_init(ctx.get()));
if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)
ASSERT_EQ(1, EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING));
EXPECT_EQ(1, EVP_PKEY_verify(ctx.get(), signature, signature_len, message, message_len));
}
typedef TrustyKeymasterTest ExportKeyTest;
TEST_F(ExportKeyTest, RsaSuccess) {
keymaster_rsa_keygen_params_t params = build_rsa_params();
uint8_t* ptr = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_RSA, &params, &ptr, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(ptr);
uint8_t* exported;
size_t exported_size;
EXPECT_EQ(KM_ERROR_OK, device.get_keypair_public(ptr, size, &exported, &exported_size));
Malloc_Delete exported_deleter(exported);
// Sign a message so we can verify it with the exported pubkey.
keymaster_rsa_sign_params_t sig_params = {DIGEST_NONE, PADDING_NONE};
size_t message_len = params.modulus_size / 8;
UniquePtr<uint8_t[]> message(build_message(message_len));
uint8_t* signature;
size_t siglen;
EXPECT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, ptr, size, message.get(), message_len,
&signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(message_len, siglen);
const uint8_t* tmp = exported;
VerifySignature(exported, exported_size, signature, siglen, message.get(), message_len);
}
typedef TrustyKeymasterTest ExportKeyTest;
TEST_F(ExportKeyTest, EcdsaSuccess) {
keymaster_ec_keygen_params_t params = {256};
uint8_t* key = NULL;
size_t size;
ASSERT_EQ(0, device.generate_keypair(TYPE_EC, &params, &key, &size));
EXPECT_GT(size, 0U);
Malloc_Delete key_deleter(key);
uint8_t* exported;
size_t exported_size;
EXPECT_EQ(KM_ERROR_OK, device.get_keypair_public(key, size, &exported, &exported_size));
Malloc_Delete exported_deleter(exported);
// Sign a message so we can verify it with the exported pubkey.
keymaster_ec_sign_params_t sig_params = {DIGEST_NONE};
uint8_t message[] = "12345678901234567890123456789012";
uint8_t* signature;
size_t siglen;
ASSERT_EQ(KM_ERROR_OK, device.sign_data(&sig_params, key, size, message,
array_size(message) - 1, &signature, &siglen));
Malloc_Delete sig_deleter(signature);
EXPECT_EQ(KM_ERROR_OK, device.verify_data(&sig_params, key, size, message,
array_size(message) - 1, signature, siglen));
VerifySignature(exported, exported_size, signature, siglen, message, array_size(message) - 1);
}
} // namespace test
} // namespace keymaster