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 */
16
17 #ifndef ANDROID_VOLD_KEYMASTER_H
18 #define ANDROID_VOLD_KEYMASTER_H
19
20 #include <memory>
21 #include <string>
22 #include <utility>
23
24 #include <keymaster/authorization_set.h>
25
26 namespace android {
27 namespace vold {
28
29 using namespace keymaster;
30
31 // C++ wrappers to the Keymaster C interface.
32 // This is tailored to the needs of KeyStorage, but could be extended to be
33 // a more general interface.
34
35 // Class that wraps a keymaster1_device_t or keymaster2_device_t and provides methods
36 // they have in common. Also closes the device on destruction.
37 class IKeymasterDevice;
38
39 // Wrapper for a keymaster_operation_handle_t representing an
40 // ongoing Keymaster operation. Aborts the operation
41 // in the destructor if it is unfinished. Methods log failures
42 // to LOG(ERROR).
43 class KeymasterOperation {
44 public:
45 ~KeymasterOperation();
46 // Is this instance valid? This is false if creation fails, and becomes
47 // false on finish or if an update fails.
48 explicit operator bool() { return mDevice != nullptr; }
49 // Call "update" repeatedly until all of the input is consumed, and
50 // concatenate the output. Return true on success.
51 bool updateCompletely(const std::string& input, std::string* output);
52 // Finish; pass nullptr for the "output" param.
53 bool finish();
54 // Finish and write the output to this string.
55 bool finishWithOutput(std::string* output);
56 // Move constructor
KeymasterOperation(KeymasterOperation && rhs)57 KeymasterOperation(KeymasterOperation&& rhs) {
58 mOpHandle = std::move(rhs.mOpHandle);
59 mDevice = std::move(rhs.mDevice);
60 }
61
62 private:
KeymasterOperation(std::shared_ptr<IKeymasterDevice> d,keymaster_operation_handle_t h)63 KeymasterOperation(std::shared_ptr<IKeymasterDevice> d, keymaster_operation_handle_t h)
64 : mDevice{d}, mOpHandle{h} {}
65 std::shared_ptr<IKeymasterDevice> mDevice;
66 keymaster_operation_handle_t mOpHandle;
67 DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
68 friend class Keymaster;
69 };
70
71 // Wrapper for a Keymaster device for methods that start a KeymasterOperation or are not
72 // part of one.
73 class Keymaster {
74 public:
75 Keymaster();
76 // false if we failed to open the keymaster device.
77 explicit operator bool() { return mDevice != nullptr; }
78 // Generate a key in the keymaster from the given params.
79 bool generateKey(const AuthorizationSet& inParams, std::string* key);
80 // If the keymaster supports it, permanently delete a key.
81 bool deleteKey(const std::string& key);
82 // Begin a new cryptographic operation, collecting output parameters.
83 KeymasterOperation begin(keymaster_purpose_t purpose, const std::string& key,
84 const AuthorizationSet& inParams, AuthorizationSet* outParams);
85 // Begin a new cryptographic operation; don't collect output parameters.
86 KeymasterOperation begin(keymaster_purpose_t purpose, const std::string& key,
87 const AuthorizationSet& inParams);
88
89 private:
90 std::shared_ptr<IKeymasterDevice> mDevice;
91 DISALLOW_COPY_AND_ASSIGN(Keymaster);
92 };
93
94 template <keymaster_tag_t Tag>
addStringParam(AuthorizationSetBuilder && params,TypedTag<KM_BYTES,Tag> tag,const std::string & val)95 inline AuthorizationSetBuilder& addStringParam(AuthorizationSetBuilder&& params,
96 TypedTag<KM_BYTES, Tag> tag,
97 const std::string& val) {
98 return params.Authorization(tag, val.data(), val.size());
99 }
100
101 template <keymaster_tag_t Tag>
addStringParam(AuthorizationSetBuilder * params,TypedTag<KM_BYTES,Tag> tag,const std::string & val)102 inline void addStringParam(AuthorizationSetBuilder* params, TypedTag<KM_BYTES, Tag> tag,
103 const std::string& val) {
104 params->Authorization(tag, val.data(), val.size());
105 }
106
107 } // namespace vold
108 } // namespace android
109
110 #endif
111