blob: a0fa78238c3a13d1ad8d7a1aa08e21a27cea6b61 [file] [log] [blame]
Shawn Willden398c1582015-05-28 00:04:06 -06001/*
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/rsa_key_factory.h>
18
19#include <keymaster/keymaster_context.h>
20
21#include "openssl_err.h"
22#include "openssl_utils.h"
23#include "rsa_key.h"
24#include "rsa_operation.h"
25
26#if defined(OPENSSL_IS_BORINGSSL)
27typedef size_t openssl_size_t;
28#else
29typedef int openssl_size_t;
30#endif
31
32namespace keymaster {
33
34static RsaSigningOperationFactory sign_factory;
35static RsaVerificationOperationFactory verify_factory;
36static RsaEncryptionOperationFactory encrypt_factory;
37static RsaDecryptionOperationFactory decrypt_factory;
38
39OperationFactory* RsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
40 switch (purpose) {
41 case KM_PURPOSE_SIGN:
42 return &sign_factory;
43 case KM_PURPOSE_VERIFY:
44 return &verify_factory;
45 case KM_PURPOSE_ENCRYPT:
46 return &encrypt_factory;
47 case KM_PURPOSE_DECRYPT:
48 return &decrypt_factory;
49 default:
50 return nullptr;
51 }
52}
53
54keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description,
55 KeymasterKeyBlob* key_blob,
56 AuthorizationSet* hw_enforced,
57 AuthorizationSet* sw_enforced) const {
58 if (!key_blob || !hw_enforced || !sw_enforced)
59 return KM_ERROR_OUTPUT_PARAMETER_NULL;
60
61 AuthorizationSet authorizations(key_description);
62
63 uint64_t public_exponent;
64 if (!authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
65 LOG_E("%s", "No public exponent specified for RSA key generation");
66 return KM_ERROR_INVALID_ARGUMENT;
67 }
68
69 uint32_t key_size;
70 if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) {
71 LOG_E("%s", "No key size specified for RSA key generation");
72 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
73 }
74
75 UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new());
76 UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(RSA_new());
77 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
78 if (exponent.get() == NULL || rsa_key.get() == NULL || pkey.get() == NULL)
79 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
80
81 if (!BN_set_word(exponent.get(), public_exponent) ||
82 !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */))
83 return TranslateLastOpenSslError();
84
85 if (EVP_PKEY_set1_RSA(pkey.get(), rsa_key.get()) != 1)
86 return TranslateLastOpenSslError();
87
88 KeymasterKeyBlob key_material;
89 keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
90 if (error != KM_ERROR_OK)
91 return error;
92
93 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob,
94 hw_enforced, sw_enforced);
95}
96
97keymaster_error_t RsaKeyFactory::ImportKey(const AuthorizationSet& key_description,
98 keymaster_key_format_t input_key_material_format,
99 const KeymasterKeyBlob& input_key_material,
100 KeymasterKeyBlob* output_key_blob,
101 AuthorizationSet* hw_enforced,
102 AuthorizationSet* sw_enforced) const {
103 if (!output_key_blob || !hw_enforced || !sw_enforced)
104 return KM_ERROR_OUTPUT_PARAMETER_NULL;
105
106 AuthorizationSet authorizations;
107 uint64_t public_exponent;
108 uint32_t key_size;
109 keymaster_error_t error =
110 UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
111 &authorizations, &public_exponent, &key_size);
112 if (error != KM_ERROR_OK)
113 return error;
114 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
115 output_key_blob, hw_enforced, sw_enforced);
116}
117
118keymaster_error_t RsaKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
119 keymaster_key_format_t key_format,
120 const KeymasterKeyBlob& key_material,
121 AuthorizationSet* updated_description,
122 uint64_t* public_exponent,
123 uint32_t* key_size) const {
124 if (!updated_description || !public_exponent || !key_size)
125 return KM_ERROR_OUTPUT_PARAMETER_NULL;
126
127 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey;
128 keymaster_error_t error =
129 KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
130 if (error != KM_ERROR_OK)
131 return error;
132
133 UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
134 if (!rsa_key.get())
135 return TranslateLastOpenSslError();
136
137 updated_description->Reinitialize(key_description);
138
139 *public_exponent = BN_get_word(rsa_key->e);
140 if (*public_exponent == 0xffffffffL)
141 return KM_ERROR_INVALID_KEY_BLOB;
142 if (!updated_description->GetTagValue(TAG_RSA_PUBLIC_EXPONENT, public_exponent))
143 updated_description->push_back(TAG_RSA_PUBLIC_EXPONENT, *public_exponent);
144 if (*public_exponent != BN_get_word(rsa_key->e))
145 return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
146
147 *key_size = RSA_size(rsa_key.get()) * 8;
148 if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size))
149 updated_description->push_back(TAG_KEY_SIZE, *key_size);
150 if (RSA_size(rsa_key.get()) * 8 != (openssl_size_t)*key_size)
151 return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
152
153 keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
154 if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm))
155 updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
156 if (algorithm != KM_ALGORITHM_RSA)
157 return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
158
159 return KM_ERROR_OK;
160}
161
162keymaster_error_t RsaKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
163 const AuthorizationSet& sw_enforced,
164 UniquePtr<AsymmetricKey>* key) const {
165 keymaster_error_t error;
166 key->reset(new RsaKey(hw_enforced, sw_enforced, &error));
167 if (!key->get())
168 error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
169 return error;
170}
171
172} // namespace keymaster