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