1 /*
2 **
3 ** Copyright 2017, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #ifndef LEGACY_SUPPORT_KEYMASTER1_LEGACY_SUPPORT_H_
19 #define LEGACY_SUPPORT_KEYMASTER1_LEGACY_SUPPORT_H_
20 
21 #include <map>
22 #include <vector>
23 
24 #include <hardware/keymaster_defs.h>
25 #include <hardware/keymaster1.h>
26 
27 #include <keymaster/android_keymaster_utils.h>
28 #include <keymaster/authorization_set.h>
29 #include <keymaster/key_factory.h>
30 #include <keymaster/UniquePtr.h>
31 
32 #include "ec_keymaster1_key.h"
33 #include "keymaster_passthrough_engine.h"
34 #include "keymaster_passthrough_key.h"
35 #include "keymaster1_engine.h"
36 #include "rsa_keymaster1_key.h"
37 
38 namespace keymaster {
39 
40 class Keymaster1LegacySupport {
41 public:
42     typedef std::pair<keymaster_algorithm_t, keymaster_purpose_t> AlgPurposePair;
43     typedef std::map<AlgPurposePair, std::vector<keymaster_digest_t>> DigestMap;
44 
45     // NOLINTNEXTLINE(google-explicit-constructor)
46     Keymaster1LegacySupport(const keymaster1_device_t* dev);
47 
48     bool RequiresSoftwareDigesting(const AuthorizationSet& key_description) const;
49     bool RequiresSoftwareDigesting(const keymaster_digest_t digest,
50                                    const AuthProxy& key_description) const;
51 
52 private:
53     DigestMap device_digests_;
54     bool supports_all_;
55 
56 };
57 
58 class SoftwareKeyBlobMaker;
59 
60 template<typename KM1_SOFTDIGEST_FACTORY>
61 class Keymaster1ArbitrationFactory : public KeyFactory {
62 public:
63     template<typename... SOFT_FACTORY_CONSRUCTOR_ARGS>
Keymaster1ArbitrationFactory(const KeymasterPassthroughEngine * ptengine,keymaster_algorithm_t algorithm,const keymaster1_device_t * dev,SOFT_FACTORY_CONSRUCTOR_ARGS &&...args)64     Keymaster1ArbitrationFactory(const KeymasterPassthroughEngine* ptengine,
65                                  keymaster_algorithm_t algorithm,
66                                  const keymaster1_device_t* dev,
67                                  SOFT_FACTORY_CONSRUCTOR_ARGS&&... args)
68             : software_digest_factory_(forward<SOFT_FACTORY_CONSRUCTOR_ARGS>(args)...),
69               passthrough_factory_(ptengine, algorithm),
70               legacy_support_(dev){}
GenerateKey(const AuthorizationSet & key_description,KeymasterKeyBlob * key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced)71     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
72                                   KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
73                                   AuthorizationSet* sw_enforced) const {
74         if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
75             return software_digest_factory_.GenerateKey(key_description, key_blob, hw_enforced,
76                                                  sw_enforced);
77         } else {
78             return passthrough_factory_.GenerateKey(key_description, key_blob, hw_enforced,
79                                                     sw_enforced);
80         }
81     }
82 
ImportKey(const AuthorizationSet & key_description,keymaster_key_format_t input_key_material_format,const KeymasterKeyBlob & input_key_material,KeymasterKeyBlob * output_key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced)83     keymaster_error_t ImportKey(const AuthorizationSet& key_description,
84                                 keymaster_key_format_t input_key_material_format,
85                                 const KeymasterKeyBlob& input_key_material,
86                                 KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
87                                 AuthorizationSet* sw_enforced) const {
88         if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
89             return software_digest_factory_.ImportKey(key_description, input_key_material_format,
90                                                       input_key_material, output_key_blob,
91                                                       hw_enforced, sw_enforced);
92         } else {
93             return passthrough_factory_.ImportKey(key_description, input_key_material_format,
94                                                   input_key_material, output_key_blob,
95                                                   hw_enforced, sw_enforced);
96         }
97     }
98 
LoadKey(KeymasterKeyBlob && key_material,const AuthorizationSet & additional_params,AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,UniquePtr<Key> * key)99     keymaster_error_t LoadKey(KeymasterKeyBlob&& key_material,
100                               const AuthorizationSet& additional_params,
101                               AuthorizationSet&& hw_enforced,
102                               AuthorizationSet&& sw_enforced,
103                               UniquePtr<Key>* key) const override {
104         keymaster_digest_t digest;
105         if (!additional_params.GetTagValue(TAG_DIGEST, &digest)) {
106             digest = KM_DIGEST_NONE;
107         }
108 
109         if (legacy_support_.RequiresSoftwareDigesting(digest,
110                                                       AuthProxy(hw_enforced, sw_enforced))) {
111             return software_digest_factory_.LoadKey(move(key_material), additional_params,
112                                                     move(hw_enforced), move(sw_enforced), key);
113         } else {
114             return passthrough_factory_.LoadKey(move(key_material), additional_params,
115                                                 move(hw_enforced), move(sw_enforced), key);
116         }
117     }
118 
GetOperationFactory(keymaster_purpose_t)119     OperationFactory* GetOperationFactory(keymaster_purpose_t /*purpose*/) const override {
120         // The passthrough operation factory must not be queried. To get the operation factory for
121         // a Key call key.key_factory()->GetOperationFactory()
122         assert(false);
123         return nullptr;
124     }
125 
126     // Informational methods.
SupportedImportFormats(size_t * format_count)127     const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const  override {
128         *format_count = 0;
129         return nullptr;
130     }
SupportedExportFormats(size_t * format_count)131     const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const override {
132         *format_count = 0;
133         return nullptr;
134     }
135 
136 private:
137     KM1_SOFTDIGEST_FACTORY software_digest_factory_;
138     KeymasterPassthroughKeyFactory passthrough_factory_;
139     Keymaster1LegacySupport legacy_support_;
140 };
141 
142 template<>
143 keymaster_error_t
144 Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::GenerateKey(
145         const AuthorizationSet& key_description,
146         KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
147         AuthorizationSet* sw_enforced) const;
148 
149 
150 template<>
151 keymaster_error_t
152 Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::LoadKey(KeymasterKeyBlob&& key_material,
153         const AuthorizationSet& additional_params,
154         AuthorizationSet&& hw_enforced,
155         AuthorizationSet&& sw_enforced,
156         UniquePtr<Key>* key) const;
157 
158 template<>
159 keymaster_error_t
160 Keymaster1ArbitrationFactory<RsaKeymaster1KeyFactory>::LoadKey(KeymasterKeyBlob&& key_material,
161         const AuthorizationSet& additional_params,
162         AuthorizationSet&& hw_enforced,
163         AuthorizationSet&& sw_enforced,
164         UniquePtr<Key>* key) const;
165 
166 } // namespace keymaster
167 
168 #endif  // LEGACY_SUPPORT_KEYMASTER1_LEGACY_SUPPORT_H_
169