blob: 1e210a31f2c03fdd03ce64ad7a15a2b86fa853da [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 Willden3ad5f052015-05-08 14:05:13 -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 Willdenf0f68b92014-12-30 16:03:28 -070070 if (!key.authorizations().GetTagValue(TAG_BLOCK_MODE, &block_mode) || !supported(block_mode))
71 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
72
73 keymaster_padding_t padding = KM_PAD_NONE;
Shawn Willden3ad5f052015-05-08 14:05:13 -060074 begin_params.GetTagValue(TAG_PADDING, &padding);
75 if (!key.authorizations().GetTagValue(TAG_PADDING, &padding)) {
76 LOG_E("Padding mode %d was specified, but not authorized by key", padding);
77 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
78 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070079
Shawn Willden7a62f5e2015-03-10 12:59:20 -060080 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
81
Shawn Willdenf0f68b92014-12-30 16:03:28 -070082 if (*error != KM_ERROR_OK)
Shawn Willden3ad5f052015-05-08 14:05:13 -060083 return nullptr;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070084
85 switch (block_mode) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -070086 case KM_MODE_ECB:
87 case KM_MODE_CBC:
Shawn Willden7a62f5e2015-03-10 12:59:20 -060088 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Thai Duong20d725d2015-03-24 17:49:58 -070089 case KM_MODE_CTR:
90 if (padding != KM_PAD_NONE) {
Shawn Willden3ad5f052015-05-08 14:05:13 -060091 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
92 return nullptr;
Thai Duong20d725d2015-03-24 17:49:58 -070093 }
94 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070095 default:
Shawn Willden63ac0432014-12-29 14:07:08 -070096 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
Shawn Willden3ad5f052015-05-08 14:05:13 -060097 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070098 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070099}
100
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700101Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
102 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600103 keymaster_padding_t padding, bool caller_iv,
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700104 keymaster_error_t* error) {
105 Operation* op = NULL;
106 switch (purpose()) {
107 case KM_PURPOSE_ENCRYPT:
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600108 op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
109 key.key_data_size());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700110 break;
111 case KM_PURPOSE_DECRYPT:
112 op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
113 break;
114 default:
115 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
116 return NULL;
117 }
118
119 if (!op)
120 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
121 return op;
122}
123
Shawn Willdenc47c88f2015-04-07 17:23:27 -0600124static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
125 KM_MODE_CTR};
Shawn Willden63ac0432014-12-29 14:07:08 -0700126
127const keymaster_block_mode_t*
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700128AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700129 *block_mode_count = array_length(supported_block_modes);
130 return supported_block_modes;
131}
132
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700133static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
134const keymaster_padding_t*
135AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
136 *padding_mode_count = array_length(supported_padding_modes);
137 return supported_padding_modes;
138}
Shawn Willden63ac0432014-12-29 14:07:08 -0700139
140/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700141 * Concrete factory for AES encryption operations.
Shawn Willden63ac0432014-12-29 14:07:08 -0700142 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700143class AesEncryptionOperationFactory : public AesOperationFactory {
144 keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
145};
146static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
147
148/**
149 * Concrete factory for AES decryption operations.
150 */
151class AesDecryptionOperationFactory : public AesOperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -0700152 keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
153};
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700154static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
Shawn Willden63ac0432014-12-29 14:07:08 -0700155
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700156AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600157 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
158 size_t key_size)
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700159 : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600160 caller_iv_(caller_iv) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700161 memcpy(key_, key, key_size_);
162 EVP_CIPHER_CTX_init(&ctx_);
163}
164
165AesEvpOperation::~AesEvpOperation() {
166 EVP_CIPHER_CTX_cleanup(&ctx_);
167}
168
169keymaster_error_t AesEvpOperation::InitializeCipher() {
170 const EVP_CIPHER* cipher;
171 switch (block_mode_) {
172 case KM_MODE_ECB:
173 switch (key_size_) {
174 case 16:
175 cipher = EVP_aes_128_ecb();
176 break;
177 case 24:
178 cipher = EVP_aes_192_ecb();
179 break;
180 case 32:
181 cipher = EVP_aes_256_ecb();
182 break;
183 default:
184 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
185 }
186 break;
187 case KM_MODE_CBC:
188 switch (key_size_) {
189 case 16:
190 cipher = EVP_aes_128_cbc();
191 break;
192 case 24:
193 cipher = EVP_aes_192_cbc();
194 break;
195 case 32:
196 cipher = EVP_aes_256_cbc();
197 break;
198 default:
199 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
200 }
201 break;
Thai Duong20d725d2015-03-24 17:49:58 -0700202 case KM_MODE_CTR:
203 switch (key_size_) {
204 case 16:
205 cipher = EVP_aes_128_ctr();
206 break;
207 case 24:
208 cipher = EVP_aes_192_ctr();
209 break;
210 case 32:
211 cipher = EVP_aes_256_ctr();
212 break;
213 default:
214 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
215 }
216 break;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700217 default:
218 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
219 }
220
221 int init_result =
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600222 EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700223
224 if (!init_result)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600225 return TranslateLastOpenSslError();
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700226
227 switch (padding_) {
228 case KM_PAD_NONE:
229 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
230 break;
231 case KM_PAD_PKCS7:
232 // This is the default for OpenSSL EVP cipher operations.
233 break;
234 default:
235 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
236 }
237
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700238 return KM_ERROR_OK;
239}
240
241bool AesEvpOperation::need_iv() const {
242 switch (block_mode_) {
243 case KM_MODE_CBC:
Thai Duong20d725d2015-03-24 17:49:58 -0700244 case KM_MODE_CTR:
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700245 return true;
246 case KM_MODE_ECB:
247 return false;
248 default:
249 // Shouldn't get here.
250 assert(false);
251 return false;
252 }
253}
254
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600255keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
256 AuthorizationSet* output_params) {
257 if (!output_params)
258 return KM_ERROR_OUTPUT_PARAMETER_NULL;
259
260 keymaster_error_t error = KM_ERROR_OK;
261 if (need_iv()) {
262 switch (purpose()) {
263 case KM_PURPOSE_ENCRYPT:
Shawn Willden67706352015-04-28 00:43:19 -0600264 if (input_params.find(TAG_NONCE) == -1)
265 error = GenerateIv();
266 else if (caller_iv_)
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600267 error = GetIv(input_params);
Shawn Willden67706352015-04-28 00:43:19 -0600268 else
269 error = KM_ERROR_CALLER_NONCE_PROHIBITED;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600270
271 if (error == KM_ERROR_OK)
272 output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
273 break;
274
275 case KM_PURPOSE_DECRYPT:
276 error = GetIv(input_params);
277 break;
278 default:
279 return KM_ERROR_UNSUPPORTED_PURPOSE;
280 }
281 }
282
283 if (error == KM_ERROR_OK)
284 error = InitializeCipher();
285
286 return error;
287}
288
289keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
290 keymaster_blob_t iv_blob;
291 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
292 LOG_E("No IV provided", 0);
293 return KM_ERROR_INVALID_ARGUMENT;
294 }
295 if (iv_blob.data_length != AES_BLOCK_SIZE) {
296 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
297 iv_blob.data_length);
Thai Duong20d725d2015-03-24 17:49:58 -0700298 return KM_ERROR_INVALID_NONCE;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600299 }
300 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
Shawn Willden92b69a32015-03-14 11:07:36 -0600301 if (!iv_.get())
302 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700303 return KM_ERROR_OK;
304}
305
Shawn Willden67706352015-04-28 00:43:19 -0600306keymaster_error_t AesEvpOperation::GenerateIv() {
307 iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
308 if (!iv_.get())
309 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden34454982015-04-29 23:22:37 -0600310 if (RAND_bytes(iv_.get(), AES_BLOCK_SIZE) != 1)
Shawn Willden67706352015-04-28 00:43:19 -0600311 return TranslateLastOpenSslError();
312 return KM_ERROR_OK;
313}
314
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700315inline size_t min(size_t a, size_t b) {
316 if (a < b)
317 return a;
318 return b;
319}
320
321keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
322 const Buffer& input, Buffer* output,
323 size_t* input_consumed) {
324 output->reserve(input.available_read() + AES_BLOCK_SIZE);
325
326 const uint8_t* input_pos = input.peek_read();
327 const uint8_t* input_end = input_pos + input.available_read();
328
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700329 int output_written = -1;
330 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
331 input_end - input_pos))
332 return TranslateLastOpenSslError();
333
334 assert(output_written >= 0);
335 assert(output_written <= (int)output->available_write());
336 output->advance_write(output_written);
337 *input_consumed = input.available_read();
338 return KM_ERROR_OK;
339}
340
341keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
342 const Buffer& /* signature */, Buffer* output) {
343 output->reserve(AES_BLOCK_SIZE);
344
345 int output_written = -1;
346 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
347 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
348 return TranslateLastOpenSslError();
349 }
350
351 assert(output_written <= AES_BLOCK_SIZE);
352 output->advance_write(output_written);
353 return KM_ERROR_OK;
354}
355
356keymaster_error_t AesEvpOperation::Abort() {
357 return KM_ERROR_OK;
358}
359
Shawn Willden907c3012014-12-08 15:51:55 -0700360} // namespace keymaster