blob: 9aa979e8400552755a29ceab4b0a2c102e3eb24f [file] [log] [blame]
Shawn Willden907c3012014-12-08 15:51:55 -07001/*
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 Willden6dde87c2014-12-11 14:08:48 -070017#include <stdio.h>
18
Shawn Willden907c3012014-12-08 15:51:55 -070019#include <openssl/aes.h>
Shawn Willdenf0f68b92014-12-30 16:03:28 -070020#include <openssl/err.h>
Shawn Willden907c3012014-12-08 15:51:55 -070021#include <openssl/rand.h>
22
Shawn Willden567a4a02014-12-31 12:14:46 -070023#include <keymaster/logger.h>
24
Shawn Willden63ac0432014-12-29 14:07:08 -070025#include "aes_key.h"
Shawn Willden907c3012014-12-08 15:51:55 -070026#include "aes_operation.h"
Shawn Willdenf0f68b92014-12-30 16:03:28 -070027#include "openssl_err.h"
Shawn Willden907c3012014-12-08 15:51:55 -070028
29namespace keymaster {
30
Shawn Willden63ac0432014-12-29 14:07:08 -070031/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -070032 * Abstract base for AES operation factories. This class does all of the work to create
33 * AES operations.
Shawn Willden63ac0432014-12-29 14:07:08 -070034 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -070035class AesOperationFactory : public OperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -070036 public:
37 virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_AES, purpose()); }
38
Shawn Willden3ed6d062015-04-15 13:39:38 -060039 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
40 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070041 virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070042 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const;
Shawn Willden63ac0432014-12-29 14:07:08 -070043
44 virtual keymaster_purpose_t purpose() const = 0;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070045
46 private:
Shawn Willdenf0f68b92014-12-30 16:03:28 -070047 virtual Operation* CreateEvpOperation(const SymmetricKey& key,
48 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -060049 keymaster_padding_t padding, bool caller_iv,
50 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070051};
52
Shawn Willden3ed6d062015-04-15 13:39:38 -060053Operation* AesOperationFactory::CreateOperation(const Key& key,
Shawn Willden31e063f2015-05-08 14:31:22 -060054 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060055 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070056 *error = KM_ERROR_OK;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070057 const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070058
59 switch (symmetric_key->key_data_size()) {
60 case 16:
61 case 24:
62 case 32:
63 break;
64 default:
65 *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
Shawn Willden3ad5f052015-05-08 14:05:13 -060066 return nullptr;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070067 }
68
Shawn Willden63ac0432014-12-29 14:07:08 -070069 keymaster_block_mode_t block_mode;
Shawn Willden31e063f2015-05-08 14:31:22 -060070 if (!begin_params.GetTagValue(TAG_BLOCK_MODE, &block_mode)) {
71 LOG_E("%d block modes specified in begin params", begin_params.GetTagCount(TAG_BLOCK_MODE));
Shawn Willdenf0f68b92014-12-30 16:03:28 -070072 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
Shawn Willden31e063f2015-05-08 14:31:22 -060073 return nullptr;
74 } else if (!supported(block_mode)) {
75 LOG_E("Block mode %d not supported", block_mode);
76 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
77 return nullptr;
78 } else if (!key.authorizations().Contains(TAG_BLOCK_MODE, block_mode)) {
79 LOG_E("Block mode %d was specified, but not authorized by key", block_mode);
80 *error = KM_ERROR_INCOMPATIBLE_BLOCK_MODE;
81 return nullptr;
82 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070083
84 keymaster_padding_t padding = KM_PAD_NONE;
Shawn Willden3ad5f052015-05-08 14:05:13 -060085 begin_params.GetTagValue(TAG_PADDING, &padding);
86 if (!key.authorizations().GetTagValue(TAG_PADDING, &padding)) {
87 LOG_E("Padding mode %d was specified, but not authorized by key", padding);
88 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
89 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070090
Shawn Willden7a62f5e2015-03-10 12:59:20 -060091 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
92
Shawn Willdenf0f68b92014-12-30 16:03:28 -070093 if (*error != KM_ERROR_OK)
Shawn Willden3ad5f052015-05-08 14:05:13 -060094 return nullptr;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070095
96 switch (block_mode) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -070097 case KM_MODE_ECB:
98 case KM_MODE_CBC:
Shawn Willden7a62f5e2015-03-10 12:59:20 -060099 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Thai Duong20d725d2015-03-24 17:49:58 -0700100 case KM_MODE_CTR:
101 if (padding != KM_PAD_NONE) {
Shawn Willden3ad5f052015-05-08 14:05:13 -0600102 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
103 return nullptr;
Thai Duong20d725d2015-03-24 17:49:58 -0700104 }
105 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700106 default:
Shawn Willden63ac0432014-12-29 14:07:08 -0700107 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
Shawn Willden3ad5f052015-05-08 14:05:13 -0600108 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -0700109 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700110}
111
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700112Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
113 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600114 keymaster_padding_t padding, bool caller_iv,
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700115 keymaster_error_t* error) {
116 Operation* op = NULL;
117 switch (purpose()) {
118 case KM_PURPOSE_ENCRYPT:
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600119 op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
120 key.key_data_size());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700121 break;
122 case KM_PURPOSE_DECRYPT:
123 op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
124 break;
125 default:
126 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
127 return NULL;
128 }
129
130 if (!op)
131 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
132 return op;
133}
134
Shawn Willdenc47c88f2015-04-07 17:23:27 -0600135static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
136 KM_MODE_CTR};
Shawn Willden63ac0432014-12-29 14:07:08 -0700137
138const keymaster_block_mode_t*
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700139AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700140 *block_mode_count = array_length(supported_block_modes);
141 return supported_block_modes;
142}
143
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700144static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
145const keymaster_padding_t*
146AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
147 *padding_mode_count = array_length(supported_padding_modes);
148 return supported_padding_modes;
149}
Shawn Willden63ac0432014-12-29 14:07:08 -0700150
151/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700152 * Concrete factory for AES encryption operations.
Shawn Willden63ac0432014-12-29 14:07:08 -0700153 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700154class AesEncryptionOperationFactory : public AesOperationFactory {
155 keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
156};
157static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
158
159/**
160 * Concrete factory for AES decryption operations.
161 */
162class AesDecryptionOperationFactory : public AesOperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -0700163 keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
164};
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700165static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
Shawn Willden63ac0432014-12-29 14:07:08 -0700166
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700167AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600168 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
169 size_t key_size)
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700170 : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600171 caller_iv_(caller_iv) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700172 memcpy(key_, key, key_size_);
173 EVP_CIPHER_CTX_init(&ctx_);
174}
175
176AesEvpOperation::~AesEvpOperation() {
177 EVP_CIPHER_CTX_cleanup(&ctx_);
178}
179
180keymaster_error_t AesEvpOperation::InitializeCipher() {
181 const EVP_CIPHER* cipher;
182 switch (block_mode_) {
183 case KM_MODE_ECB:
184 switch (key_size_) {
185 case 16:
186 cipher = EVP_aes_128_ecb();
187 break;
188 case 24:
189 cipher = EVP_aes_192_ecb();
190 break;
191 case 32:
192 cipher = EVP_aes_256_ecb();
193 break;
194 default:
195 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
196 }
197 break;
198 case KM_MODE_CBC:
199 switch (key_size_) {
200 case 16:
201 cipher = EVP_aes_128_cbc();
202 break;
203 case 24:
204 cipher = EVP_aes_192_cbc();
205 break;
206 case 32:
207 cipher = EVP_aes_256_cbc();
208 break;
209 default:
210 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
211 }
212 break;
Thai Duong20d725d2015-03-24 17:49:58 -0700213 case KM_MODE_CTR:
214 switch (key_size_) {
215 case 16:
216 cipher = EVP_aes_128_ctr();
217 break;
218 case 24:
219 cipher = EVP_aes_192_ctr();
220 break;
221 case 32:
222 cipher = EVP_aes_256_ctr();
223 break;
224 default:
225 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
226 }
227 break;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700228 default:
229 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
230 }
231
232 int init_result =
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600233 EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700234
235 if (!init_result)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600236 return TranslateLastOpenSslError();
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700237
238 switch (padding_) {
239 case KM_PAD_NONE:
240 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
241 break;
242 case KM_PAD_PKCS7:
243 // This is the default for OpenSSL EVP cipher operations.
244 break;
245 default:
246 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
247 }
248
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700249 return KM_ERROR_OK;
250}
251
252bool AesEvpOperation::need_iv() const {
253 switch (block_mode_) {
254 case KM_MODE_CBC:
Thai Duong20d725d2015-03-24 17:49:58 -0700255 case KM_MODE_CTR:
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700256 return true;
257 case KM_MODE_ECB:
258 return false;
259 default:
260 // Shouldn't get here.
261 assert(false);
262 return false;
263 }
264}
265
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600266keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
267 AuthorizationSet* output_params) {
268 if (!output_params)
269 return KM_ERROR_OUTPUT_PARAMETER_NULL;
270
271 keymaster_error_t error = KM_ERROR_OK;
272 if (need_iv()) {
273 switch (purpose()) {
274 case KM_PURPOSE_ENCRYPT:
Shawn Willden67706352015-04-28 00:43:19 -0600275 if (input_params.find(TAG_NONCE) == -1)
276 error = GenerateIv();
277 else if (caller_iv_)
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600278 error = GetIv(input_params);
Shawn Willden67706352015-04-28 00:43:19 -0600279 else
280 error = KM_ERROR_CALLER_NONCE_PROHIBITED;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600281
282 if (error == KM_ERROR_OK)
283 output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
284 break;
285
286 case KM_PURPOSE_DECRYPT:
287 error = GetIv(input_params);
288 break;
289 default:
290 return KM_ERROR_UNSUPPORTED_PURPOSE;
291 }
292 }
293
294 if (error == KM_ERROR_OK)
295 error = InitializeCipher();
296
297 return error;
298}
299
300keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
301 keymaster_blob_t iv_blob;
302 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
303 LOG_E("No IV provided", 0);
304 return KM_ERROR_INVALID_ARGUMENT;
305 }
306 if (iv_blob.data_length != AES_BLOCK_SIZE) {
307 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
308 iv_blob.data_length);
Thai Duong20d725d2015-03-24 17:49:58 -0700309 return KM_ERROR_INVALID_NONCE;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600310 }
311 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
Shawn Willden92b69a32015-03-14 11:07:36 -0600312 if (!iv_.get())
313 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700314 return KM_ERROR_OK;
315}
316
Shawn Willden67706352015-04-28 00:43:19 -0600317keymaster_error_t AesEvpOperation::GenerateIv() {
318 iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
319 if (!iv_.get())
320 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden34454982015-04-29 23:22:37 -0600321 if (RAND_bytes(iv_.get(), AES_BLOCK_SIZE) != 1)
Shawn Willden67706352015-04-28 00:43:19 -0600322 return TranslateLastOpenSslError();
323 return KM_ERROR_OK;
324}
325
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700326inline size_t min(size_t a, size_t b) {
327 if (a < b)
328 return a;
329 return b;
330}
331
332keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
333 const Buffer& input, Buffer* output,
334 size_t* input_consumed) {
335 output->reserve(input.available_read() + AES_BLOCK_SIZE);
336
337 const uint8_t* input_pos = input.peek_read();
338 const uint8_t* input_end = input_pos + input.available_read();
339
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700340 int output_written = -1;
341 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
342 input_end - input_pos))
343 return TranslateLastOpenSslError();
344
345 assert(output_written >= 0);
346 assert(output_written <= (int)output->available_write());
347 output->advance_write(output_written);
348 *input_consumed = input.available_read();
349 return KM_ERROR_OK;
350}
351
352keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
353 const Buffer& /* signature */, Buffer* output) {
354 output->reserve(AES_BLOCK_SIZE);
355
356 int output_written = -1;
357 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
358 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
359 return TranslateLastOpenSslError();
360 }
361
362 assert(output_written <= AES_BLOCK_SIZE);
363 output->advance_write(output_written);
364 return KM_ERROR_OK;
365}
366
367keymaster_error_t AesEvpOperation::Abort() {
368 return KM_ERROR_OK;
369}
370
Shawn Willden907c3012014-12-08 15:51:55 -0700371} // namespace keymaster