Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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 | */ |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 16 | // TODO: Maybe "Keymaster" should be replaced with Keystore2 everywhere? |
Paul Crowley | 0323afd | 2016-03-15 17:04:39 -0700 | [diff] [blame] | 17 | #ifndef ANDROID_VOLD_KEYMASTER_H |
| 18 | #define ANDROID_VOLD_KEYMASTER_H |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 19 | |
Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 20 | #include "KeyBuffer.h" |
| 21 | |
Paul Crowley | 0323afd | 2016-03-15 17:04:39 -0700 | [diff] [blame] | 22 | #include <memory> |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 23 | #include <string> |
Paul Crowley | 0323afd | 2016-03-15 17:04:39 -0700 | [diff] [blame] | 24 | #include <utility> |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 25 | |
Steven Moreland | 25e8b4b | 2017-05-01 12:45:32 -0700 | [diff] [blame] | 26 | #include <android-base/macros.h> |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 27 | #include <keymint_support/authorization_set.h> |
| 28 | #include <keymint_support/keymint_tags.h> |
| 29 | |
| 30 | #include <aidl/android/hardware/security/keymint/ErrorCode.h> |
| 31 | #include <aidl/android/system/keystore2/IKeystoreService.h> |
| 32 | #include <android/binder_manager.h> |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 33 | |
| 34 | namespace android { |
| 35 | namespace vold { |
Shawn Willden | 3535181 | 2018-01-22 09:08:32 -0700 | [diff] [blame] | 36 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 37 | namespace ks2 = ::aidl::android::system::keystore2; |
| 38 | namespace km = ::aidl::android::hardware::security::keymint; |
Shawn Willden | ae8f06f | 2020-01-16 13:21:42 -0700 | [diff] [blame] | 39 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 40 | // C++ wrappers to the Keystore2 AIDL interface. |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 41 | // This is tailored to the needs of KeyStorage, but could be extended to be |
| 42 | // a more general interface. |
| 43 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 44 | // Wrapper for a Keystore2 operation handle representing an |
| 45 | // ongoing Keystore2 operation. Aborts the operation |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 46 | // in the destructor if it is unfinished. Methods log failures |
| 47 | // to LOG(ERROR). |
| 48 | class KeymasterOperation { |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 49 | public: |
Paul Crowley | 0323afd | 2016-03-15 17:04:39 -0700 | [diff] [blame] | 50 | ~KeymasterOperation(); |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 51 | // Is this instance valid? This is false if creation fails, and becomes |
| 52 | // false on finish or if an update fails. |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 53 | explicit operator bool() const { return (bool)ks2Operation; } |
| 54 | km::ErrorCode getErrorCode() const { return errorCode; } |
| 55 | std::optional<std::string> getUpgradedBlob() const { return upgradedBlob; } |
Paul Crowley | 13ffd8e | 2016-01-27 14:30:22 +0000 | [diff] [blame] | 56 | // Call "update" repeatedly until all of the input is consumed, and |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 57 | // concatenate the output. Return true on success. |
Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 58 | template <class TI, class TO> |
| 59 | bool updateCompletely(TI& input, TO* output) { |
| 60 | if (output) output->clear(); |
| 61 | return updateCompletely(input.data(), input.size(), [&](const char* b, size_t n) { |
Shawn Willden | 785365b | 2018-01-20 09:37:36 -0700 | [diff] [blame] | 62 | if (output) std::copy(b, b + n, std::back_inserter(*output)); |
Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 63 | }); |
| 64 | } |
| 65 | |
Paul Crowley | dff8c72 | 2016-05-16 08:14:56 -0700 | [diff] [blame] | 66 | // Finish and write the output to this string, unless pointer is null. |
| 67 | bool finish(std::string* output); |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 68 | // Move constructor |
Shawn Willden | 3535181 | 2018-01-22 09:08:32 -0700 | [diff] [blame] | 69 | KeymasterOperation(KeymasterOperation&& rhs) { *this = std::move(rhs); } |
Paul Crowley | dff8c72 | 2016-05-16 08:14:56 -0700 | [diff] [blame] | 70 | // Construct an object in an error state for error returns |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 71 | KeymasterOperation() { errorCode = km::ErrorCode::UNKNOWN_ERROR; } |
Janis Danisevskis | 015ec30 | 2017-01-31 11:31:08 +0000 | [diff] [blame] | 72 | // Move Assignment |
Shawn Willden | 785365b | 2018-01-20 09:37:36 -0700 | [diff] [blame] | 73 | KeymasterOperation& operator=(KeymasterOperation&& rhs) { |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 74 | ks2Operation = rhs.ks2Operation; |
| 75 | rhs.ks2Operation = nullptr; |
Shawn Willden | 3e02df8 | 2018-02-07 15:06:06 -0700 | [diff] [blame] | 76 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 77 | upgradedBlob = rhs.upgradedBlob; |
| 78 | rhs.upgradedBlob = std::nullopt; |
Shawn Willden | 3e02df8 | 2018-02-07 15:06:06 -0700 | [diff] [blame] | 79 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 80 | errorCode = rhs.errorCode; |
| 81 | rhs.errorCode = km::ErrorCode::UNKNOWN_ERROR; |
Shawn Willden | 3e02df8 | 2018-02-07 15:06:06 -0700 | [diff] [blame] | 82 | |
Janis Danisevskis | 015ec30 | 2017-01-31 11:31:08 +0000 | [diff] [blame] | 83 | return *this; |
| 84 | } |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 85 | |
| 86 | private: |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 87 | KeymasterOperation(std::shared_ptr<ks2::IKeystoreOperation> ks2Op, |
| 88 | std::optional<std::vector<uint8_t>> blob) |
| 89 | : ks2Operation{ks2Op}, errorCode{km::ErrorCode::OK} { |
| 90 | if (blob) |
| 91 | upgradedBlob = std::optional(std::string(blob->begin(), blob->end())); |
| 92 | else |
| 93 | upgradedBlob = std::nullopt; |
| 94 | } |
| 95 | |
| 96 | KeymasterOperation(km::ErrorCode errCode) : errorCode{errCode} {} |
Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 97 | |
| 98 | bool updateCompletely(const char* input, size_t inputLen, |
| 99 | const std::function<void(const char*, size_t)> consumer); |
| 100 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 101 | std::shared_ptr<ks2::IKeystoreOperation> ks2Operation; |
| 102 | std::optional<std::string> upgradedBlob; |
| 103 | km::ErrorCode errorCode; |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 104 | DISALLOW_COPY_AND_ASSIGN(KeymasterOperation); |
| 105 | friend class Keymaster; |
| 106 | }; |
| 107 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 108 | // Wrapper for keystore2 methods that vold uses. |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 109 | class Keymaster { |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 110 | public: |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 111 | Keymaster(); |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 112 | // false if we failed to get a keystore2 security level. |
| 113 | explicit operator bool() { return (bool)securityLevel; } |
| 114 | // Generate a key using keystore2 from the given params. |
Shawn Willden | 3535181 | 2018-01-22 09:08:32 -0700 | [diff] [blame] | 115 | bool generateKey(const km::AuthorizationSet& inParams, std::string* key); |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 116 | // Exports a keystore2 key with STORAGE_KEY tag wrapped with a per-boot ephemeral key |
Barani Muthukumaran | 3dfb094 | 2020-02-03 13:06:45 -0800 | [diff] [blame] | 117 | bool exportKey(const KeyBuffer& kmKey, std::string* key); |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 118 | // If supported, permanently delete a key from the keymint device it belongs to. |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 119 | bool deleteKey(const std::string& key); |
Paul Crowley | dff8c72 | 2016-05-16 08:14:56 -0700 | [diff] [blame] | 120 | // Begin a new cryptographic operation, collecting output parameters if pointer is non-null |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 121 | // If the key was upgraded as a result of a call to this method, the returned KeymasterOperation |
| 122 | // also stores the upgraded key blob. |
| 123 | KeymasterOperation begin(const std::string& key, const km::AuthorizationSet& inParams, |
Shawn Willden | 3535181 | 2018-01-22 09:08:32 -0700 | [diff] [blame] | 124 | km::AuthorizationSet* outParams); |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 125 | |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 126 | // Tell all Keymint devices that early boot has ended and early boot-only keys can no longer |
Shawn Willden | 50397a7 | 2020-04-01 10:02:16 -0600 | [diff] [blame] | 127 | // be created or used. |
| 128 | static void earlyBootEnded(); |
Shawn Willden | 2b1ff5a | 2020-01-16 14:08:36 -0700 | [diff] [blame] | 129 | |
Paul Crowley | 0f74bd4 | 2021-08-06 15:16:10 -0700 | [diff] [blame^] | 130 | // Tell all Keymint devices to delete all rollback-protected keys. |
| 131 | static void deleteAllKeys(); |
| 132 | |
Paul Crowley | df528a7 | 2016-03-09 09:31:37 -0800 | [diff] [blame] | 133 | private: |
Satya Tangirala | e8de4ff | 2021-02-28 22:32:07 -0800 | [diff] [blame] | 134 | std::shared_ptr<ks2::IKeystoreSecurityLevel> securityLevel; |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 135 | DISALLOW_COPY_AND_ASSIGN(Keymaster); |
| 136 | }; |
| 137 | |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 138 | } // namespace vold |
| 139 | } // namespace android |
| 140 | |
Paul Crowley | 1ef2558 | 2016-01-21 20:26:12 +0000 | [diff] [blame] | 141 | #endif |