blob: a75d9aea682d1c7baef22fde397c15f7ac75c4a9 [file] [log] [blame]
Shawn Willden0a4df7e2014-08-28 16:09:05 -06001/*
2 * Copyright 2014 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
Shawn Willden63ac0432014-12-29 14:07:08 -070017#include "rsa_operation.h"
18
Shawn Willden4200f212014-12-02 07:01:21 -070019#include <limits.h>
20
21#include <openssl/err.h>
Shawn Willden0a4df7e2014-08-28 16:09:05 -060022
Shawn Willden0a4df7e2014-08-28 16:09:05 -060023#include "openssl_utils.h"
Shawn Willden63ac0432014-12-29 14:07:08 -070024#include "rsa_key.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060025
26namespace keymaster {
27
Shawn Willden63ac0432014-12-29 14:07:08 -070028/**
29 * Abstract base for all RSA operation factories. This class exists mainly to centralize some code
30 * common to all RSA operation factories.
31 */
32class RsaOperationFactory : public OperationFactory {
33 public:
34 virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_RSA, purpose()); }
35 virtual keymaster_purpose_t purpose() const = 0;
36
37 protected:
38 bool GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
39 keymaster_error_t* error) const;
40 bool GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
41 keymaster_error_t* error) const;
42 static RSA* GetRsaKey(const Key& key, keymaster_error_t* error);
43};
44
45bool RsaOperationFactory::GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
46 keymaster_error_t* error) const {
47 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
48 if (!key.authorizations().GetTagValue(TAG_PADDING, padding))
49 return false;
50
51 size_t padding_count;
52 const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
53 for (size_t i = 0; i < padding_count; ++i) {
54 if (*padding == supported_paddings[i]) {
55 *error = KM_ERROR_OK;
56 return true;
57 }
58 }
59 return false;
60}
61
62bool RsaOperationFactory::GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
63 keymaster_error_t* error) const {
64 *error = KM_ERROR_UNSUPPORTED_DIGEST;
65 if (!key.authorizations().GetTagValue(TAG_DIGEST, digest))
66 return false;
67
68 size_t digest_count;
69 const keymaster_digest_t* supported_digests = SupportedDigests(&digest_count);
70 for (size_t i = 0; i < digest_count; ++i) {
71 if (*digest == supported_digests[i]) {
72 *error = KM_ERROR_OK;
73 return true;
74 }
75 }
76 return false;
77}
78
79/* static */
80RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
81 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
82 assert(rsa_key);
83 if (!rsa_key || !rsa_key->key()) {
84 *error = KM_ERROR_UNKNOWN_ERROR;
85 return NULL;
86 }
Shawn Willden28eed512015-02-25 19:16:36 -070087 RSA_up_ref(rsa_key->key());
88 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070089}
90
91static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE};
92static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE};
93
94/**
95 * Abstract base for RSA operations that digest their input (signing and verification). This class
96 * does most of the work of creation of RSA digesting operations, delegating only the actual
97 * operation instantiation.
98 */
99class RsaDigestingOperationFactory : public RsaOperationFactory {
100 public:
101 virtual Operation* CreateOperation(const Key& key, const Logger& logger,
102 keymaster_error_t* error);
103
104 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
105 *digest_count = array_length(supported_digests);
106 return supported_digests;
107 }
108
109 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
110 *padding_mode_count = array_length(supported_sig_padding);
111 return supported_sig_padding;
112 }
113
114 private:
115 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
116 keymaster_padding_t padding, RSA* key) = 0;
117};
118
119Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, const Logger& logger,
120 keymaster_error_t* error) {
121 keymaster_padding_t padding;
122 keymaster_digest_t digest;
123 RSA* rsa;
124 if (!GetAndValidateDigest(key, &digest, error) ||
125 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
126 return NULL;
127
128 Operation* op = InstantiateOperation(logger, digest, padding, rsa);
129 if (!op)
130 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
131 return op;
132}
133
134static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
135 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
136
137/**
138 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
139 * creating such operations, delegating only the actual operation instantiation.
140 */
141class RsaCryptingOperationFactory : public RsaOperationFactory {
142 public:
143 virtual Operation* CreateOperation(const Key& key, const Logger& logger,
144 keymaster_error_t* error);
145
146 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
147 *padding_mode_count = array_length(supported_crypt_padding);
148 return supported_crypt_padding;
149 }
150
151 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
152 *digest_count = 0;
153 return NULL;
154 }
155
156 private:
157 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
158 RSA* key) = 0;
159};
160
161Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, const Logger& logger,
162 keymaster_error_t* error) {
163 keymaster_padding_t padding;
164 RSA* rsa;
165 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
166 return NULL;
167
168 Operation* op = InstantiateOperation(logger, padding, rsa);
169 if (!op)
170 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
171 return op;
172}
173
174/**
175 * Concrete factory for RSA signing operations.
176 */
177class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
178 public:
179 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
180 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
181 keymaster_padding_t padding, RSA* key) {
182 return new RsaSignOperation(logger, digest, padding, key);
183 }
184};
185static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
186
187/**
188 * Concrete factory for RSA signing operations.
189 */
190class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
191 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
192 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
193 keymaster_padding_t padding, RSA* key) {
194 return new RsaVerifyOperation(logger, digest, padding, key);
195 }
196};
197static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
198
199/**
200 * Concrete factory for RSA signing operations.
201 */
202class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
203 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
204 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
205 RSA* key) {
206 return new RsaEncryptOperation(logger, padding, key);
207 }
208};
209static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
210
211/**
212 * Concrete factory for RSA signing operations.
213 */
214class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
215 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
216 virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
217 RSA* key) {
218 return new RsaDecryptOperation(logger, padding, key);
219 }
220};
221
222static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
223
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600224struct RSA_Delete {
225 void operator()(RSA* p) const { RSA_free(p); }
226};
227
228RsaOperation::~RsaOperation() {
229 if (rsa_key_ != NULL)
230 RSA_free(rsa_key_);
231}
232
Shawn Willden6bfbff02015-02-06 19:48:24 -0700233keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
234 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700235 size_t* input_consumed) {
236 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600237 switch (purpose()) {
238 default:
239 return KM_ERROR_UNIMPLEMENTED;
240 case KM_PURPOSE_SIGN:
241 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700242 case KM_PURPOSE_ENCRYPT:
243 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700244 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600245 }
246}
247
Shawn Willdenb7361132014-12-08 08:15:14 -0700248keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
249 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600250 if (!data_.reserve(data_.available_read() + input.available_read()) ||
251 !data_.write(input.peek_read(), input.available_read()))
252 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700253 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600254 return KM_ERROR_OK;
255}
256
Shawn Willden6bfbff02015-02-06 19:48:24 -0700257keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
258 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700259 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600260 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600261 int bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
262 output->peek_write(), rsa_key_, RSA_NO_PADDING);
263 if (bytes_encrypted < 0)
264 return KM_ERROR_UNKNOWN_ERROR;
265 assert(bytes_encrypted == RSA_size(rsa_key_));
266 output->advance_write(bytes_encrypted);
267 return KM_ERROR_OK;
268}
269
Shawn Willden6bfbff02015-02-06 19:48:24 -0700270keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
271 const Buffer& signature, Buffer* /* output */) {
Adam Langleyf2aefdf2014-09-26 11:16:10 -0700272#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willden4200f212014-12-02 07:01:21 -0700273 size_t message_size = data_.available_read();
Adam Langleyf2aefdf2014-09-26 11:16:10 -0700274#else
Shawn Willden4200f212014-12-02 07:01:21 -0700275 if (data_.available_read() > INT_MAX)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600276 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden4200f212014-12-02 07:01:21 -0700277 int message_size = (int)data_.available_read();
Adam Langleyf2aefdf2014-09-26 11:16:10 -0700278#endif
279
Shawn Willden4200f212014-12-02 07:01:21 -0700280 if (message_size != RSA_size(rsa_key_))
281 return KM_ERROR_INVALID_INPUT_LENGTH;
282
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600283 if (data_.available_read() != signature.available_read())
284 return KM_ERROR_VERIFICATION_FAILED;
285
286 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[RSA_size(rsa_key_)]);
287 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
288 decrypted_data.get(), rsa_key_, RSA_NO_PADDING);
289 if (bytes_decrypted < 0)
290 return KM_ERROR_UNKNOWN_ERROR;
291 assert(bytes_decrypted == RSA_size(rsa_key_));
292
293 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) == 0)
294 return KM_ERROR_OK;
295 return KM_ERROR_VERIFICATION_FAILED;
296}
297
Shawn Willden4200f212014-12-02 07:01:21 -0700298const int OAEP_PADDING_OVERHEAD = 41;
299const int PKCS1_PADDING_OVERHEAD = 11;
300
Shawn Willden6bfbff02015-02-06 19:48:24 -0700301keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
302 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700303 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700304 int openssl_padding;
305
306#if defined(OPENSSL_IS_BORINGSSL)
307 size_t message_size = data_.available_read();
308#else
309 if (data_.available_read() > INT_MAX)
310 return KM_ERROR_INVALID_INPUT_LENGTH;
311 int message_size = (int)data_.available_read();
312#endif
313
314 switch (padding_) {
315 case KM_PAD_RSA_OAEP:
316 openssl_padding = RSA_PKCS1_OAEP_PADDING;
317 if (message_size >= RSA_size(rsa_key_) - OAEP_PADDING_OVERHEAD) {
318 logger().error("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
319 data_.available_read(), RSA_size(rsa_key_));
320 return KM_ERROR_INVALID_INPUT_LENGTH;
321 }
322 break;
323 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
324 openssl_padding = RSA_PKCS1_PADDING;
325 if (message_size >= RSA_size(rsa_key_) - PKCS1_PADDING_OVERHEAD) {
326 logger().error("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
327 data_.available_read(), RSA_size(rsa_key_));
328 return KM_ERROR_INVALID_INPUT_LENGTH;
329 }
330 break;
331 default:
332 logger().error("Padding mode %d not supported", padding_);
333 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
334 }
335
336 output->Reinitialize(RSA_size(rsa_key_));
337 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
338 output->peek_write(), rsa_key_, openssl_padding);
339
340 if (bytes_encrypted < 0) {
341 logger().error("Error %d encrypting data with RSA", ERR_get_error());
342 return KM_ERROR_UNKNOWN_ERROR;
343 }
344 assert(bytes_encrypted == RSA_size(rsa_key_));
345 output->advance_write(bytes_encrypted);
346
347 return KM_ERROR_OK;
348}
349
Shawn Willden6bfbff02015-02-06 19:48:24 -0700350keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
351 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700352 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700353 int openssl_padding;
354 switch (padding_) {
355 case KM_PAD_RSA_OAEP:
356 openssl_padding = RSA_PKCS1_OAEP_PADDING;
357 break;
358 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
359 openssl_padding = RSA_PKCS1_PADDING;
360 break;
361 default:
362 logger().error("Padding mode %d not supported", padding_);
363 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
364 }
365
366 output->Reinitialize(RSA_size(rsa_key_));
367 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
368 output->peek_write(), rsa_key_, openssl_padding);
369
370 if (bytes_decrypted < 0) {
371 logger().error("Error %d decrypting data with RSA", ERR_get_error());
372 return KM_ERROR_UNKNOWN_ERROR;
373 }
374 output->advance_write(bytes_decrypted);
375
376 return KM_ERROR_OK;
377}
378
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600379} // namespace keymaster