1 /*
2 * Copyright 2020, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include "km_compat.h"
20 #include <keymint_support/keymint_tags.h>
21
22 #include <aidl/android/hardware/security/keymint/Algorithm.h>
23 #include <aidl/android/hardware/security/keymint/BlockMode.h>
24 #include <aidl/android/hardware/security/keymint/Digest.h>
25 #include <aidl/android/hardware/security/keymint/PaddingMode.h>
26 #include <android/binder_manager.h>
27
28 #include <openssl/evp.h>
29 #include <openssl/x509.h>
30
31 #define DEFINE_OPENSSL_OBJECT_POINTER(name) using name##_Ptr = bssl::UniquePtr<name>
32
33 DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY);
34 DEFINE_OPENSSL_OBJECT_POINTER(X509);
35
36 using ::aidl::android::hardware::security::keymint::Algorithm;
37 using ::aidl::android::hardware::security::keymint::BlockMode;
38 using ::aidl::android::hardware::security::keymint::Certificate;
39 using ::aidl::android::hardware::security::keymint::Digest;
40 using ::aidl::android::hardware::security::keymint::PaddingMode;
41 using ::aidl::android::hardware::security::keymint::SecurityLevel;
42 using ::aidl::android::hardware::security::keymint::Tag;
43 using ::aidl::android::security::compat::IKeystoreCompatService;
44
45 namespace KMV1 = ::aidl::android::hardware::security::keymint;
46
47 extern "C" int32_t addKeyMintDeviceService();
48
getDevice()49 static std::variant<std::shared_ptr<IKeyMintDevice>, ScopedAStatus> getDevice() {
50 addKeyMintDeviceService();
51 std::shared_ptr<IKeyMintDevice> device;
52 auto service = IKeystoreCompatService::fromBinder(
53 ndk::SpAIBinder(AServiceManager_getService("android.security.compat")));
54 if (!service) {
55 return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
56 }
57 service->getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT, &device);
58 if (!device) {
59 return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
60 }
61 return device;
62 }
63
64 static std::variant<std::vector<Certificate>, ScopedAStatus>
getCertificate(std::shared_ptr<IKeyMintDevice> device,const std::vector<KeyParameter> & keyParams)65 getCertificate(std::shared_ptr<IKeyMintDevice> device, const std::vector<KeyParameter>& keyParams) {
66 KeyCreationResult creationResult;
67 auto status = device->generateKey(keyParams, std::nullopt /* attest_key */, &creationResult);
68 if (!status.isOk()) {
69 return status;
70 }
71 return creationResult.certificateChain;
72 }
73
ensureCertChainSize(const std::variant<std::vector<Certificate>,ScopedAStatus> & result,uint32_t size)74 static void ensureCertChainSize(const std::variant<std::vector<Certificate>, ScopedAStatus>& result,
75 uint32_t size) {
76 ASSERT_TRUE(std::holds_alternative<std::vector<Certificate>>(result));
77 auto certChain = std::get<std::vector<Certificate>>(result);
78 ASSERT_EQ(certChain.size(), size);
79 }
80
verify(const Certificate & certificate)81 static void verify(const Certificate& certificate) {
82 const uint8_t* p = certificate.encodedCertificate.data();
83 X509_Ptr decoded_cert(d2i_X509(nullptr, &p, (long)certificate.encodedCertificate.size()));
84 EVP_PKEY_Ptr decoded_pkey(X509_get_pubkey(decoded_cert.get()));
85 ASSERT_TRUE(X509_verify(decoded_cert.get(), decoded_pkey.get()));
86 }
87
getRSAKeyParams(const std::vector<KeyParameter> & extraParams)88 static std::vector<KeyParameter> getRSAKeyParams(const std::vector<KeyParameter>& extraParams) {
89 auto keyParams = std::vector<KeyParameter>({
90 KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::RSA),
91 KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 2048),
92 KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, 65537),
93 KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_BEFORE, 0),
94 KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_AFTER, 253402300799000),
95 });
96 keyParams.insert(keyParams.end(), extraParams.begin(), extraParams.end());
97 return keyParams;
98 }
99
TEST(CertificateTest,TestRSAKeygen)100 TEST(CertificateTest, TestRSAKeygen) {
101 auto keyParams = getRSAKeyParams({
102 KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
103 KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
104 KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED),
105 KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
106 });
107 auto device = getDevice();
108 if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
109 auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
110 ensureCertChainSize(result, 1);
111 }
112 }
113
TEST(CertificateTest,TestAES)114 TEST(CertificateTest, TestAES) {
115 auto keyParams = {
116 KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::AES),
117 KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 128),
118 KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, BlockMode::CBC),
119 KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::NONE),
120 KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::ENCRYPT),
121 };
122 auto device = getDevice();
123 if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
124 auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
125 ensureCertChainSize(result, 0);
126 }
127 }
128
TEST(CertificateTest,TestAttestation)129 TEST(CertificateTest, TestAttestation) {
130 auto keyParams = getRSAKeyParams({
131 KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
132 KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_CHALLENGE, 42),
133 KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_APPLICATION_ID, 42),
134 });
135 auto device = getDevice();
136 if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
137 auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
138 ensureCertChainSize(result, 3);
139 verify(std::get<std::vector<Certificate>>(result).back());
140 }
141 }
142
TEST(CertificateTest,TestRSAKeygenNoEncryptNoAuthRequired)143 TEST(CertificateTest, TestRSAKeygenNoEncryptNoAuthRequired) {
144 auto keyParams = getRSAKeyParams({
145 KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
146 KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
147 KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
148 KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
149 });
150 auto device = getDevice();
151 if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
152 auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
153 ensureCertChainSize(result, 1);
154 verify(std::get<std::vector<Certificate>>(result)[0]);
155 }
156 }
157
TEST(CertificateTest,TestRSAKeygenNoEncryptAuthRequired)158 TEST(CertificateTest, TestRSAKeygenNoEncryptAuthRequired) {
159 auto keyParams = getRSAKeyParams({
160 KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
161 KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
162 KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
163 });
164 auto device = getDevice();
165 if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
166 auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
167 ensureCertChainSize(result, 1);
168 }
169 }
170