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 <keymaster/ec_key_factory.h>
18 
19 #include <openssl/evp.h>
20 
21 #include <keymaster/keymaster_context.h>
22 
23 #include "ec_key.h"
24 #include "ecdsa_operation.h"
25 #include "openssl_err.h"
26 
27 namespace keymaster {
28 
29 static EcdsaSignOperationFactory sign_factory;
30 static EcdsaVerifyOperationFactory verify_factory;
31 
GetOperationFactory(keymaster_purpose_t purpose) const32 OperationFactory* EcKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
33     switch (purpose) {
34     case KM_PURPOSE_SIGN:
35         return &sign_factory;
36     case KM_PURPOSE_VERIFY:
37         return &verify_factory;
38     default:
39         return nullptr;
40     }
41 }
42 
GenerateKey(const AuthorizationSet & key_description,KeymasterKeyBlob * key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced) const43 keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_description,
44                                             KeymasterKeyBlob* key_blob,
45                                             AuthorizationSet* hw_enforced,
46                                             AuthorizationSet* sw_enforced) const {
47     if (!key_blob || !hw_enforced || !sw_enforced)
48         return KM_ERROR_OUTPUT_PARAMETER_NULL;
49 
50     AuthorizationSet authorizations(key_description);
51 
52     uint32_t key_size;
53     if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) {
54         LOG_E("%s", "No key size specified for EC key generation");
55         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
56     }
57 
58     UniquePtr<EC_KEY, EC_Delete> ec_key(EC_KEY_new());
59     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
60     if (ec_key.get() == NULL || pkey.get() == NULL)
61         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
62 
63     UniquePtr<EC_GROUP, EC_GROUP_Delete> group(choose_group(key_size));
64     if (group.get() == NULL) {
65         LOG_E("Unable to get EC group for key of size %d", key_size);
66         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
67     }
68 
69 #if !defined(OPENSSL_IS_BORINGSSL)
70     EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
71     EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
72 #endif
73 
74     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
75         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
76         return TranslateLastOpenSslError();
77     }
78 
79     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1)
80         return TranslateLastOpenSslError();
81 
82     KeymasterKeyBlob key_material;
83     keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
84     if (error != KM_ERROR_OK)
85         return error;
86 
87     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob,
88                                    hw_enforced, sw_enforced);
89 }
90 
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) const91 keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_description,
92                                           keymaster_key_format_t input_key_material_format,
93                                           const KeymasterKeyBlob& input_key_material,
94                                           KeymasterKeyBlob* output_key_blob,
95                                           AuthorizationSet* hw_enforced,
96                                           AuthorizationSet* sw_enforced) const {
97     if (!output_key_blob || !hw_enforced || !sw_enforced)
98         return KM_ERROR_OUTPUT_PARAMETER_NULL;
99 
100     AuthorizationSet authorizations;
101     uint32_t key_size;
102     keymaster_error_t error = UpdateImportKeyDescription(
103         key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
104     if (error != KM_ERROR_OK)
105         return error;
106 
107     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
108                                    output_key_blob, hw_enforced, sw_enforced);
109 }
110 
UpdateImportKeyDescription(const AuthorizationSet & key_description,keymaster_key_format_t key_format,const KeymasterKeyBlob & key_material,AuthorizationSet * updated_description,uint32_t * key_size_bits) const111 keymaster_error_t EcKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
112                                                            keymaster_key_format_t key_format,
113                                                            const KeymasterKeyBlob& key_material,
114                                                            AuthorizationSet* updated_description,
115                                                            uint32_t* key_size_bits) const {
116     if (!updated_description || !key_size_bits)
117         return KM_ERROR_OUTPUT_PARAMETER_NULL;
118 
119     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey;
120     keymaster_error_t error =
121         KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
122     if (error != KM_ERROR_OK)
123         return error;
124 
125     UniquePtr<EC_KEY, EC_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
126     if (!ec_key.get())
127         return TranslateLastOpenSslError();
128 
129     updated_description->Reinitialize(key_description);
130 
131     size_t extracted_key_size_bits;
132     error = get_group_size(*EC_KEY_get0_group(ec_key.get()), &extracted_key_size_bits);
133     if (error != KM_ERROR_OK)
134         return error;
135 
136     *key_size_bits = extracted_key_size_bits;
137     if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size_bits))
138         updated_description->push_back(TAG_KEY_SIZE, extracted_key_size_bits);
139     if (*key_size_bits != extracted_key_size_bits)
140         return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
141 
142     keymaster_algorithm_t algorithm = KM_ALGORITHM_EC;
143     if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm))
144         updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
145     if (algorithm != KM_ALGORITHM_EC)
146         return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
147 
148     return KM_ERROR_OK;
149 }
150 
151 /* static */
choose_group(size_t key_size_bits)152 EC_GROUP* EcKeyFactory::choose_group(size_t key_size_bits) {
153     switch (key_size_bits) {
154     case 224:
155         return EC_GROUP_new_by_curve_name(NID_secp224r1);
156         break;
157     case 256:
158         return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
159         break;
160     case 384:
161         return EC_GROUP_new_by_curve_name(NID_secp384r1);
162         break;
163     case 521:
164         return EC_GROUP_new_by_curve_name(NID_secp521r1);
165         break;
166     default:
167         return NULL;
168         break;
169     }
170 }
171 /* static */
get_group_size(const EC_GROUP & group,size_t * key_size_bits)172 keymaster_error_t EcKeyFactory::get_group_size(const EC_GROUP& group, size_t* key_size_bits) {
173     switch (EC_GROUP_get_curve_name(&group)) {
174     case NID_secp224r1:
175         *key_size_bits = 224;
176         break;
177     case NID_X9_62_prime256v1:
178         *key_size_bits = 256;
179         break;
180     case NID_secp384r1:
181         *key_size_bits = 384;
182         break;
183     case NID_secp521r1:
184         *key_size_bits = 521;
185         break;
186     default:
187         return KM_ERROR_UNSUPPORTED_EC_FIELD;
188     }
189     return KM_ERROR_OK;
190 }
191 
CreateEmptyKey(const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,UniquePtr<AsymmetricKey> * key) const192 keymaster_error_t EcKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
193                                                const AuthorizationSet& sw_enforced,
194                                                UniquePtr<AsymmetricKey>* key) const {
195     keymaster_error_t error;
196     key->reset(new (std::nothrow) EcKey(hw_enforced, sw_enforced, &error));
197     if (!key->get())
198         error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
199     return error;
200 }
201 
202 }  // namespace keymaster
203