summaryrefslogtreecommitdiff
path: root/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
blob: 7d3bc30b7b6fa92ce35d8ce173a3259dae687e70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/*
 * Copyright (C) 2020 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.
 */

#pragma once

#include <functional>
#include <string_view>

#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <android-base/properties.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <gtest/gtest.h>
#include <openssl/x509.h>

#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>

#include <keymint_support/attestation_record.h>
#include <keymint_support/authorization_set.h>
#include <keymint_support/openssl_utils.h>

namespace aidl::android::hardware::security::keymint {

::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set);

inline bool operator==(const keymint::AuthorizationSet& a, const keymint::AuthorizationSet& b) {
    return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
}

namespace test {

using ::android::sp;
using Status = ::ndk::ScopedAStatus;
using ::std::optional;
using ::std::shared_ptr;
using ::std::string;
using ::std::vector;

constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;

class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
  public:
    struct KeyData {
        vector<uint8_t> blob;
        vector<KeyCharacteristics> characteristics;
    };

    static bool arm_deleteAllKeys;
    static bool dump_Attestations;

    void SetUp() override;
    void TearDown() override {
        if (key_blob_.size()) {
            CheckedDeleteKey();
        }
        AbortIfNeeded();
    }

    void InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint);
    IKeyMintDevice& keyMint() { return *keymint_; }
    int32_t AidlVersion();
    uint32_t os_version() { return os_version_; }
    uint32_t os_patch_level() { return os_patch_level_; }
    uint32_t vendor_patch_level() { return vendor_patch_level_; }
    uint32_t boot_patch_level(const vector<KeyCharacteristics>& key_characteristics);
    uint32_t boot_patch_level();
    bool isDeviceIdAttestationRequired();

    bool Curve25519Supported();

    ErrorCode GetReturnErrorCode(const Status& result);

    ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
                          vector<KeyCharacteristics>* key_characteristics) {
        return GenerateKey(key_desc, std::nullopt /* attest_key */, key_blob, key_characteristics,
                           &cert_chain_);
    }
    ErrorCode GenerateKey(const AuthorizationSet& key_desc,
                          const optional<AttestationKey>& attest_key, vector<uint8_t>* key_blob,
                          vector<KeyCharacteristics>* key_characteristics,
                          vector<Certificate>* cert_chain);
    ErrorCode GenerateKey(const AuthorizationSet& key_desc,
                          const optional<AttestationKey>& attest_key = std::nullopt);

    // Generate key for implementations which do not support factory attestation.
    ErrorCode GenerateKeyWithSelfSignedAttestKey(const AuthorizationSet& attest_key_desc,
                                                 const AuthorizationSet& key_desc,
                                                 vector<uint8_t>* key_blob,
                                                 vector<KeyCharacteristics>* key_characteristics,
                                                 vector<Certificate>* cert_chain);

    ErrorCode GenerateKeyWithSelfSignedAttestKey(const AuthorizationSet& attest_key_desc,
                                                 const AuthorizationSet& key_desc,
                                                 vector<uint8_t>* key_blob,
                                                 vector<KeyCharacteristics>* key_characteristics) {
        return GenerateKeyWithSelfSignedAttestKey(attest_key_desc, key_desc, key_blob,
                                                  key_characteristics, &cert_chain_);
    }

    ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                        const string& key_material, vector<uint8_t>* key_blob,
                        vector<KeyCharacteristics>* key_characteristics);
    ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
                        const string& key_material);

    ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key,
                               const AuthorizationSet& wrapping_key_desc, string masking_key,
                               const AuthorizationSet& unwrapping_params, int64_t password_sid,
                               int64_t biometric_sid);
    ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key,
                               const AuthorizationSet& wrapping_key_desc, string masking_key,
                               const AuthorizationSet& unwrapping_params) {
        return ImportWrappedKey(wrapped_key, wrapping_key, wrapping_key_desc, masking_key,
                                unwrapping_params, 0 /* password_sid */, 0 /* biometric_sid */);
    }

    ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob, const vector<uint8_t>& app_id,
                                 const vector<uint8_t>& app_data,
                                 vector<KeyCharacteristics>* key_characteristics);
    ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob,
                                 vector<KeyCharacteristics>* key_characteristics);

    void CheckCharacteristics(const vector<uint8_t>& key_blob,
                              const vector<KeyCharacteristics>& generate_characteristics);
    void CheckAppIdCharacteristics(const vector<uint8_t>& key_blob, std::string_view app_id_string,
                                   std::string_view app_data_string,
                                   const vector<KeyCharacteristics>& generate_characteristics);

    ErrorCode DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
    ErrorCode DeleteKey(bool keep_key_blob = false);

    ErrorCode DeleteAllKeys();

    ErrorCode DestroyAttestationIds();

    void CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
    void CheckedDeleteKey();

    ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
                    const AuthorizationSet& in_params, AuthorizationSet* out_params,
                    std::shared_ptr<IKeyMintOperation>& op);
    ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
                    const AuthorizationSet& in_params, AuthorizationSet* out_params);
    ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
                    AuthorizationSet* out_params);
    ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);

    ErrorCode UpdateAad(const string& input);
    ErrorCode Update(const string& input, string* output);

    ErrorCode Finish(const string& message, const string& signature, string* output);
    ErrorCode Finish(const string& message, string* output) {
        return Finish(message, {} /* signature */, output);
    }
    ErrorCode Finish(string* output) { return Finish({} /* message */, output); }

    ErrorCode Abort();
    ErrorCode Abort(const shared_ptr<IKeyMintOperation>& op);
    void AbortIfNeeded();

    string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
                          const string& message, const AuthorizationSet& in_params,
                          AuthorizationSet* out_params);
    std::tuple<ErrorCode, std::string /* processedMessage */> ProcessMessage(
            const vector<uint8_t>& key_blob, KeyPurpose operation, const std::string& message,
            const AuthorizationSet& in_params);
    string SignMessage(const vector<uint8_t>& key_blob, const string& message,
                       const AuthorizationSet& params);
    string SignMessage(const string& message, const AuthorizationSet& params);

    string MacMessage(const string& message, Digest digest, size_t mac_length);

    void CheckAesIncrementalEncryptOperation(BlockMode block_mode, int message_size);

    void CheckHmacTestVector(const string& key, const string& message, Digest digest,
                             const string& expected_mac);

    void CheckAesCtrTestVector(const string& key, const string& nonce, const string& message,
                               const string& expected_ciphertext);

    void CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode,
                                  PaddingMode padding_mode, const string& key, const string& iv,
                                  const string& input, const string& expected_output);

    void VerifyMessage(const vector<uint8_t>& key_blob, const string& message,
                       const string& signature, const AuthorizationSet& params);
    void VerifyMessage(const string& message, const string& signature,
                       const AuthorizationSet& params);
    void LocalVerifyMessage(const string& message, const string& signature,
                            const AuthorizationSet& params);

    string LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params);
    string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
                          const AuthorizationSet& in_params, AuthorizationSet* out_params);
    string EncryptMessage(const string& message, const AuthorizationSet& params,
                          AuthorizationSet* out_params);
    string EncryptMessage(const string& message, const AuthorizationSet& params);
    string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding);
    string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
                          vector<uint8_t>* iv_out);
    string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
                          const vector<uint8_t>& iv_in);
    string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
                          uint8_t mac_length_bits, const vector<uint8_t>& iv_in);
    string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
                          uint8_t mac_length_bits);

    string DecryptMessage(const vector<uint8_t>& key_blob, const string& ciphertext,
                          const AuthorizationSet& params);
    string DecryptMessage(const string& ciphertext, const AuthorizationSet& params);
    string DecryptMessage(const string& ciphertext, BlockMode block_mode, PaddingMode padding_mode,
                          const vector<uint8_t>& iv);

    std::pair<ErrorCode, vector<uint8_t>> UpgradeKey(const vector<uint8_t>& key_blob);

    template <typename TagType>
    std::tuple<KeyData /* aesKey */, KeyData /* hmacKey */, KeyData /* rsaKey */,
               KeyData /* ecdsaKey */>
    CreateTestKeys(
            TagType tagToTest, ErrorCode expectedReturn,
            std::function<void(AuthorizationSetBuilder*)> tagModifier =
                    [](AuthorizationSetBuilder*) {}) {
        /* AES */
        KeyData aesKeyData;
        AuthorizationSetBuilder aesBuilder = AuthorizationSetBuilder()
                                                     .AesEncryptionKey(128)
                                                     .Authorization(tagToTest)
                                                     .BlockMode(BlockMode::ECB)
                                                     .Padding(PaddingMode::NONE)
                                                     .Authorization(TAG_NO_AUTH_REQUIRED);
        tagModifier(&aesBuilder);
        ErrorCode errorCode =
                GenerateKey(aesBuilder, &aesKeyData.blob, &aesKeyData.characteristics);
        EXPECT_EQ(expectedReturn, errorCode);

        /* HMAC */
        KeyData hmacKeyData;
        AuthorizationSetBuilder hmacBuilder = AuthorizationSetBuilder()
                                                      .HmacKey(128)
                                                      .Authorization(tagToTest)
                                                      .Digest(Digest::SHA_2_256)
                                                      .Authorization(TAG_MIN_MAC_LENGTH, 128)
                                                      .Authorization(TAG_NO_AUTH_REQUIRED);
        tagModifier(&hmacBuilder);
        errorCode = GenerateKey(hmacBuilder, &hmacKeyData.blob, &hmacKeyData.characteristics);
        EXPECT_EQ(expectedReturn, errorCode);

        /* RSA */
        KeyData rsaKeyData;
        AuthorizationSetBuilder rsaBuilder = AuthorizationSetBuilder()
                                                     .RsaSigningKey(2048, 65537)
                                                     .Authorization(tagToTest)
                                                     .Digest(Digest::NONE)
                                                     .Padding(PaddingMode::NONE)
                                                     .Authorization(TAG_NO_AUTH_REQUIRED)
                                                     .SetDefaultValidity();
        tagModifier(&rsaBuilder);
        errorCode = GenerateKey(rsaBuilder, &rsaKeyData.blob, &rsaKeyData.characteristics);
        if (!(SecLevel() == SecurityLevel::STRONGBOX &&
              ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED == errorCode)) {
            EXPECT_EQ(expectedReturn, errorCode);
        }

        /* ECDSA */
        KeyData ecdsaKeyData;
        AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder()
                                                       .EcdsaSigningKey(EcCurve::P_256)
                                                       .Authorization(tagToTest)
                                                       .Digest(Digest::SHA_2_256)
                                                       .Authorization(TAG_NO_AUTH_REQUIRED)
                                                       .SetDefaultValidity();
        tagModifier(&ecdsaBuilder);
        errorCode = GenerateKey(ecdsaBuilder, &ecdsaKeyData.blob, &ecdsaKeyData.characteristics);
        if (!(SecLevel() == SecurityLevel::STRONGBOX &&
              ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED == errorCode)) {
            EXPECT_EQ(expectedReturn, errorCode);
        }
        return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData};
    }
    bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
    SecurityLevel SecLevel() const { return securityLevel_; }

    vector<uint32_t> ValidKeySizes(Algorithm algorithm);
    vector<uint32_t> InvalidKeySizes(Algorithm algorithm);

    vector<BlockMode> ValidBlockModes(Algorithm algorithm);
    vector<PaddingMode> ValidPaddingModes(Algorithm algorithm, BlockMode blockMode);
    vector<PaddingMode> InvalidPaddingModes(Algorithm algorithm, BlockMode blockMode);

    vector<EcCurve> ValidCurves();
    vector<EcCurve> InvalidCurves();

    vector<Digest> ValidDigests(bool withNone, bool withMD5);
    vector<uint64_t> ValidExponents();

    static vector<string> build_params() {
        auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
        return params;
    }

    std::shared_ptr<IKeyMintOperation> op_;
    vector<Certificate> cert_chain_;
    vector<uint8_t> key_blob_;
    vector<KeyCharacteristics> key_characteristics_;

    const vector<KeyParameter>& SecLevelAuthorizations(
            const vector<KeyCharacteristics>& key_characteristics);
    inline const vector<KeyParameter>& SecLevelAuthorizations() {
        return SecLevelAuthorizations(key_characteristics_);
    }
    const vector<KeyParameter>& SecLevelAuthorizations(
            const vector<KeyCharacteristics>& key_characteristics, SecurityLevel securityLevel);

    ErrorCode UseAesKey(const vector<uint8_t>& aesKeyBlob);
    ErrorCode UseHmacKey(const vector<uint8_t>& hmacKeyBlob);
    ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
    ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);

  protected:
    std::shared_ptr<IKeyMintDevice> keymint_;
    uint32_t os_version_;
    uint32_t os_patch_level_;
    uint32_t vendor_patch_level_;
    bool timestamp_token_required_;

    SecurityLevel securityLevel_;
    string name_;
    string author_;
    long challenge_;
};

// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
                       const char* prop) {
    std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
    if (!prop_value.empty()) {
        tags->Authorization(ttag, prop_value.data(), prop_value.size());
    }
}

// Return the VSR API level for this device.
int get_vsr_api_level();

// Indicate whether the test is running on a GSI image.
bool is_gsi_image();

vector<uint8_t> build_serial_blob(const uint64_t serial_int);
void verify_subject(const X509* cert, const string& subject, bool self_signed);
void verify_serial(X509* cert, const uint64_t expected_serial);
void verify_subject_and_serial(const Certificate& certificate,  //
                               const uint64_t expected_serial,  //
                               const string& subject, bool self_signed);
void verify_root_of_trust(const vector<uint8_t>& verified_boot_key,  //
                          bool device_locked,                        //
                          VerifiedBoot verified_boot_state,          //
                          const vector<uint8_t>& verified_boot_hash);
bool verify_attestation_record(int aidl_version,                       //
                               const string& challenge,                //
                               const string& app_id,                   //
                               AuthorizationSet expected_sw_enforced,  //
                               AuthorizationSet expected_hw_enforced,  //
                               SecurityLevel security_level,
                               const vector<uint8_t>& attestation_cert,
                               vector<uint8_t>* unique_id = nullptr);

string bin2hex(const vector<uint8_t>& data);
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
vector<uint8_t> make_name_from_str(const string& name);
void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
                        vector<uint8_t>* payload_value);
void p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
bool check_feature(const std::string& name);

AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
                                                   bool strict_issuer_check = true);

#define INSTANTIATE_KEYMINT_AIDL_TEST(name)                                          \
    INSTANTIATE_TEST_SUITE_P(PerInstance, name,                                      \
                             testing::ValuesIn(KeyMintAidlTestBase::build_params()), \
                             ::android::PrintInstanceNameToString);                  \
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);

}  // namespace test

}  // namespace aidl::android::hardware::security::keymint