• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
19 
20 #include <map>
21 #include <utility>
22 #include <vector>
23 
24 #include <hardware/keymaster1.h>
25 #include <hardware/keymaster_defs.h>
26 
27 #include <keymaster/UniquePtr.h>
28 #include <keymaster/android_keymaster_utils.h>
29 #include <keymaster/authorization_set.h>
30 #include <keymaster/key_factory.h>
31 
32 #include "ec_keymaster1_key.h"
33 #include "keymaster1_engine.h"
34 #include "keymaster_passthrough_engine.h"
35 #include "keymaster_passthrough_key.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 class SoftwareKeyBlobMaker;
58 
59 template <typename KM1_SOFTDIGEST_FACTORY> class Keymaster1ArbitrationFactory : public KeyFactory {
60   public:
61     template <typename... SOFT_FACTORY_CONSRUCTOR_ARGS>
Keymaster1ArbitrationFactory(const KeymasterPassthroughEngine * ptengine,keymaster_algorithm_t algorithm,const keymaster1_device_t * dev,SOFT_FACTORY_CONSRUCTOR_ARGS &&...args)62     Keymaster1ArbitrationFactory(const KeymasterPassthroughEngine* ptengine,
63                                  keymaster_algorithm_t algorithm, const keymaster1_device_t* dev,
64                                  SOFT_FACTORY_CONSRUCTOR_ARGS&&... args)
65         : software_digest_factory_(std::forward<SOFT_FACTORY_CONSRUCTOR_ARGS>(args)...),
66           passthrough_factory_(ptengine, algorithm), legacy_support_(dev) {}
GenerateKey(const AuthorizationSet & key_description,UniquePtr<Key> attest_key,const KeymasterBlob & issuer_subject,KeymasterKeyBlob * key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,CertificateChain * cert_chain)67     keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
68                                   UniquePtr<Key> attest_key,  //
69                                   const KeymasterBlob& issuer_subject,
70                                   KeymasterKeyBlob* key_blob,     //
71                                   AuthorizationSet* hw_enforced,  //
72                                   AuthorizationSet* sw_enforced,
73                                   CertificateChain* cert_chain) const {
74         if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
75             return software_digest_factory_.GenerateKey(key_description, std::move(attest_key),
76                                                         issuer_subject, key_blob, hw_enforced,
77                                                         sw_enforced, cert_chain);
78         } else {
79             return passthrough_factory_.GenerateKey(key_description, std::move(attest_key),
80                                                     issuer_subject, key_blob, hw_enforced,
81                                                     sw_enforced, cert_chain);
82         }
83     }
84 
ImportKey(const AuthorizationSet & key_description,keymaster_key_format_t input_key_material_format,const KeymasterKeyBlob & input_key_material,UniquePtr<Key> attest_key,const KeymasterBlob & issuer_subject,KeymasterKeyBlob * output_key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,CertificateChain * cert_chain)85     keymaster_error_t ImportKey(const AuthorizationSet& key_description,
86                                 keymaster_key_format_t input_key_material_format,
87                                 const KeymasterKeyBlob& input_key_material,
88                                 UniquePtr<Key> attest_key,  //
89                                 const KeymasterBlob& issuer_subject,
90                                 KeymasterKeyBlob* output_key_blob,  //
91                                 AuthorizationSet* hw_enforced,      //
92                                 AuthorizationSet* sw_enforced, CertificateChain* cert_chain) const {
93         if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
94             return software_digest_factory_.ImportKey(
95                 key_description, input_key_material_format, input_key_material,
96                 std::move(attest_key), issuer_subject, output_key_blob, hw_enforced, sw_enforced,
97                 cert_chain);
98         } else {
99             return passthrough_factory_.ImportKey(
100                 key_description, input_key_material_format, input_key_material,
101                 std::move(attest_key), issuer_subject, output_key_blob, hw_enforced, sw_enforced,
102                 cert_chain);
103         }
104     }
105 
LoadKey(KeymasterKeyBlob && key_material,const AuthorizationSet & additional_params,AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,UniquePtr<Key> * key)106     keymaster_error_t LoadKey(KeymasterKeyBlob&& key_material,
107                               const AuthorizationSet& additional_params,
108                               AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
109                               UniquePtr<Key>* key) const override {
110         keymaster_digest_t digest;
111         if (!additional_params.GetTagValue(TAG_DIGEST, &digest)) {
112             digest = KM_DIGEST_NONE;
113         }
114 
115         if (legacy_support_.RequiresSoftwareDigesting(digest,
116                                                       AuthProxy(hw_enforced, sw_enforced))) {
117             return software_digest_factory_.LoadKey(std::move(key_material), additional_params,
118                                                     std::move(hw_enforced), std::move(sw_enforced),
119                                                     key);
120         } else {
121             return passthrough_factory_.LoadKey(std::move(key_material), additional_params,
122                                                 std::move(hw_enforced), std::move(sw_enforced),
123                                                 key);
124         }
125     }
126 
GetOperationFactory(keymaster_purpose_t)127     OperationFactory* GetOperationFactory(keymaster_purpose_t /*purpose*/) const override {
128         // The passthrough operation factory must not be queried. To get the operation factory for
129         // a Key call key.key_factory()->GetOperationFactory()
130         assert(false);
131         return nullptr;
132     }
133 
134     // Informational methods.
SupportedImportFormats(size_t * format_count)135     const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const override {
136         *format_count = 0;
137         return nullptr;
138     }
SupportedExportFormats(size_t * format_count)139     const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const override {
140         *format_count = 0;
141         return nullptr;
142     }
143 
144   private:
145     KM1_SOFTDIGEST_FACTORY software_digest_factory_;
146     KeymasterPassthroughKeyFactory passthrough_factory_;
147     Keymaster1LegacySupport legacy_support_;
148 };
149 
150 template <>
151 keymaster_error_t Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::GenerateKey(
152     const AuthorizationSet& key_description,  //
153     UniquePtr<Key> attest_key,                //
154     const KeymasterBlob& issuer_subject,      //
155     KeymasterKeyBlob* key_blob,               //
156     AuthorizationSet* hw_enforced,            //
157     AuthorizationSet* sw_enforced,            //
158     CertificateChain* cert_chain) const;
159 
160 template <>
161 keymaster_error_t Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::LoadKey(
162     KeymasterKeyBlob&& key_material, const AuthorizationSet& additional_params,
163     AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, UniquePtr<Key>* key) const;
164 
165 template <>
166 keymaster_error_t Keymaster1ArbitrationFactory<RsaKeymaster1KeyFactory>::LoadKey(
167     KeymasterKeyBlob&& key_material, const AuthorizationSet& additional_params,
168     AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, UniquePtr<Key>* key) const;
169 
170 }  // namespace keymaster
171