1 /*
2  * Copyright 2015 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 #include "rsa_keymaster0_key.h"
18 
19 #include <memory>
20 
21 #define LOG_TAG "RsaKeymaster0Key"
22 #include <cutils/log.h>
23 
24 #include <keymaster/android_keymaster_utils.h>
25 #include <keymaster/logger.h>
26 #include <keymaster/soft_keymaster_context.h>
27 
28 #include "keymaster0_engine.h"
29 #include "openssl_utils.h"
30 
31 using std::unique_ptr;
32 
33 namespace keymaster {
34 
RsaKeymaster0KeyFactory(const SoftKeymasterContext * context,const Keymaster0Engine * engine)35 RsaKeymaster0KeyFactory::RsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
36                                                  const Keymaster0Engine* engine)
37     : RsaKeyFactory(context), engine_(engine), soft_context_(context) {}
38 
GenerateKey(const AuthorizationSet & key_description,KeymasterKeyBlob * key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced) const39 keymaster_error_t RsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
40                                                        KeymasterKeyBlob* key_blob,
41                                                        AuthorizationSet* hw_enforced,
42                                                        AuthorizationSet* sw_enforced) const {
43     if (!key_blob || !hw_enforced || !sw_enforced)
44         return KM_ERROR_OUTPUT_PARAMETER_NULL;
45 
46     if (!engine_)
47         return super::GenerateKey(key_description, key_blob, hw_enforced, sw_enforced);
48 
49     uint64_t public_exponent;
50     if (!key_description.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
51         LOG_E("%s", "No public exponent specified for RSA key generation");
52         return KM_ERROR_INVALID_ARGUMENT;
53     }
54 
55     uint32_t key_size;
56     if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
57         LOG_E("%s", "No key size specified for RSA key generation");
58         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
59     }
60 
61     KeymasterKeyBlob key_material;
62     if (!engine_->GenerateRsaKey(public_exponent, key_size, &key_material))
63         return KM_ERROR_UNKNOWN_ERROR;
64 
65     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
66     // context_->CreateKeyBlob doesn't put them in sw_enforced.
67     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
68     hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
69     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
70     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
71 
72     return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
73                                    hw_enforced, sw_enforced);
74 }
75 
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) const76 keymaster_error_t RsaKeymaster0KeyFactory::ImportKey(
77     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
78     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
79     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
80     if (!output_key_blob || !hw_enforced || !sw_enforced)
81         return KM_ERROR_OUTPUT_PARAMETER_NULL;
82 
83     if (!engine_)
84         return super::ImportKey(key_description, input_key_material_format, input_key_material,
85                                 output_key_blob, hw_enforced, sw_enforced);
86 
87     AuthorizationSet authorizations;
88     uint64_t public_exponent;
89     uint32_t key_size;
90     keymaster_error_t error =
91         UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
92                                    &authorizations, &public_exponent, &key_size);
93     if (error != KM_ERROR_OK)
94         return error;
95 
96     KeymasterKeyBlob imported_hw_key;
97     if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key))
98         return KM_ERROR_UNKNOWN_ERROR;
99 
100     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
101     // context_->CreateKeyBlob doesn't put them in sw_enforced.
102     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
103     hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
104     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
105     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
106 
107     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
108                                    output_key_blob, hw_enforced, sw_enforced);
109 }
110 
LoadKey(const KeymasterKeyBlob & key_material,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,UniquePtr<Key> * key) const111 keymaster_error_t RsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
112                                                    const AuthorizationSet& hw_enforced,
113                                                    const AuthorizationSet& sw_enforced,
114                                                    UniquePtr<Key>* key) const {
115     if (!key)
116         return KM_ERROR_OUTPUT_PARAMETER_NULL;
117 
118     if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
119         return super::LoadKey(key_material, hw_enforced, sw_enforced, key);
120 
121     unique_ptr<RSA, RSA_Delete> rsa(engine_->BlobToRsaKey(key_material));
122     if (!rsa)
123         return KM_ERROR_UNKNOWN_ERROR;
124 
125     keymaster_error_t error;
126     key->reset(new (std::nothrow)
127                    RsaKeymaster0Key(rsa.release(), hw_enforced, sw_enforced, engine_, &error));
128     if (!key->get())
129         error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
130 
131     if (error != KM_ERROR_OK)
132         return error;
133 
134     return KM_ERROR_OK;
135 }
136 
RsaKeymaster0Key(RSA * rsa_key,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,const Keymaster0Engine * engine,keymaster_error_t * error)137 RsaKeymaster0Key::RsaKeymaster0Key(RSA* rsa_key, const AuthorizationSet& hw_enforced,
138                                    const AuthorizationSet& sw_enforced,
139                                    const Keymaster0Engine* engine, keymaster_error_t* error)
140     : RsaKey(rsa_key, hw_enforced, sw_enforced, error), engine_(engine) {}
141 
key_material(UniquePtr<uint8_t[]> * material,size_t * size) const142 keymaster_error_t RsaKeymaster0Key::key_material(UniquePtr<uint8_t[]>* material,
143                                                  size_t* size) const {
144     if (!engine_)
145         return super::key_material(material, size);
146 
147     const keymaster_key_blob_t* blob = engine_->RsaKeyToBlob(key());
148     if (!blob)
149         return KM_ERROR_UNKNOWN_ERROR;
150 
151     *size = blob->key_material_size;
152     material->reset(dup_buffer(blob->key_material, *size));
153     if (!material->get())
154         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
155     return KM_ERROR_OK;
156 }
157 
158 }  // namespace keymaster
159