blob: 11dbdccad000f69d9e4e9d1cedf1301c2df0f985 [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 Willden898f5642015-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 Willden898f5642015-04-15 13:39:38 -060053Operation* AesOperationFactory::CreateOperation(const Key& key,
54 const AuthorizationSet& /* begin_params */,
55 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;
66 return NULL;
67 }
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;
74 key.authorizations().GetTagValue(TAG_PADDING, &padding);
75
Shawn Willden7a62f5e2015-03-10 12:59:20 -060076 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
77
Shawn Willdenf0f68b92014-12-30 16:03:28 -070078 if (*error != KM_ERROR_OK)
79 return NULL;
80
81 switch (block_mode) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -070082 case KM_MODE_ECB:
83 case KM_MODE_CBC:
Shawn Willden7a62f5e2015-03-10 12:59:20 -060084 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Thai Duong20d725d2015-03-24 17:49:58 -070085 case KM_MODE_CTR:
86 if (padding != KM_PAD_NONE) {
87 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
88 return NULL;
89 }
90 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070091 default:
Shawn Willden63ac0432014-12-29 14:07:08 -070092 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
93 return NULL;
94 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070095}
96
Shawn Willdenf0f68b92014-12-30 16:03:28 -070097Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
98 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -060099 keymaster_padding_t padding, bool caller_iv,
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700100 keymaster_error_t* error) {
101 Operation* op = NULL;
102 switch (purpose()) {
103 case KM_PURPOSE_ENCRYPT:
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600104 op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
105 key.key_data_size());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700106 break;
107 case KM_PURPOSE_DECRYPT:
108 op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
109 break;
110 default:
111 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
112 return NULL;
113 }
114
115 if (!op)
116 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
117 return op;
118}
119
Shawn Willdenc47c88f2015-04-07 17:23:27 -0600120static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
121 KM_MODE_CTR};
Shawn Willden63ac0432014-12-29 14:07:08 -0700122
123const keymaster_block_mode_t*
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700124AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700125 *block_mode_count = array_length(supported_block_modes);
126 return supported_block_modes;
127}
128
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700129static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
130const keymaster_padding_t*
131AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
132 *padding_mode_count = array_length(supported_padding_modes);
133 return supported_padding_modes;
134}
Shawn Willden63ac0432014-12-29 14:07:08 -0700135
136/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700137 * Concrete factory for AES encryption operations.
Shawn Willden63ac0432014-12-29 14:07:08 -0700138 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700139class AesEncryptionOperationFactory : public AesOperationFactory {
140 keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
141};
142static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
143
144/**
145 * Concrete factory for AES decryption operations.
146 */
147class AesDecryptionOperationFactory : public AesOperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -0700148 keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
149};
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700150static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
Shawn Willden63ac0432014-12-29 14:07:08 -0700151
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700152AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600153 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
154 size_t key_size)
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700155 : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600156 caller_iv_(caller_iv) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700157 memcpy(key_, key, key_size_);
158 EVP_CIPHER_CTX_init(&ctx_);
159}
160
161AesEvpOperation::~AesEvpOperation() {
162 EVP_CIPHER_CTX_cleanup(&ctx_);
163}
164
165keymaster_error_t AesEvpOperation::InitializeCipher() {
166 const EVP_CIPHER* cipher;
167 switch (block_mode_) {
168 case KM_MODE_ECB:
169 switch (key_size_) {
170 case 16:
171 cipher = EVP_aes_128_ecb();
172 break;
173 case 24:
174 cipher = EVP_aes_192_ecb();
175 break;
176 case 32:
177 cipher = EVP_aes_256_ecb();
178 break;
179 default:
180 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
181 }
182 break;
183 case KM_MODE_CBC:
184 switch (key_size_) {
185 case 16:
186 cipher = EVP_aes_128_cbc();
187 break;
188 case 24:
189 cipher = EVP_aes_192_cbc();
190 break;
191 case 32:
192 cipher = EVP_aes_256_cbc();
193 break;
194 default:
195 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
196 }
197 break;
Thai Duong20d725d2015-03-24 17:49:58 -0700198 case KM_MODE_CTR:
199 switch (key_size_) {
200 case 16:
201 cipher = EVP_aes_128_ctr();
202 break;
203 case 24:
204 cipher = EVP_aes_192_ctr();
205 break;
206 case 32:
207 cipher = EVP_aes_256_ctr();
208 break;
209 default:
210 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
211 }
212 break;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700213 default:
214 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
215 }
216
217 int init_result =
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600218 EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700219
220 if (!init_result)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600221 return TranslateLastOpenSslError();
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700222
223 switch (padding_) {
224 case KM_PAD_NONE:
225 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
226 break;
227 case KM_PAD_PKCS7:
228 // This is the default for OpenSSL EVP cipher operations.
229 break;
230 default:
231 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
232 }
233
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700234 return KM_ERROR_OK;
235}
236
237bool AesEvpOperation::need_iv() const {
238 switch (block_mode_) {
239 case KM_MODE_CBC:
Thai Duong20d725d2015-03-24 17:49:58 -0700240 case KM_MODE_CTR:
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700241 return true;
242 case KM_MODE_ECB:
243 return false;
244 default:
245 // Shouldn't get here.
246 assert(false);
247 return false;
248 }
249}
250
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600251keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
252 AuthorizationSet* output_params) {
253 if (!output_params)
254 return KM_ERROR_OUTPUT_PARAMETER_NULL;
255
256 keymaster_error_t error = KM_ERROR_OK;
257 if (need_iv()) {
258 switch (purpose()) {
259 case KM_PURPOSE_ENCRYPT:
Shawn Willden969aa382015-04-15 17:05:53 -0700260 if (caller_iv_ && input_params.GetTagCount(TAG_NONCE) == 1)
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600261 error = GetIv(input_params);
262 else {
263 iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
264 if (!iv_.get())
265 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
266 if (!RAND_bytes(iv_.get(), AES_BLOCK_SIZE))
267 error = TranslateLastOpenSslError();
268 }
269
270 if (error == KM_ERROR_OK)
271 output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
272 break;
273
274 case KM_PURPOSE_DECRYPT:
275 error = GetIv(input_params);
276 break;
277 default:
278 return KM_ERROR_UNSUPPORTED_PURPOSE;
279 }
280 }
281
282 if (error == KM_ERROR_OK)
283 error = InitializeCipher();
284
285 return error;
286}
287
288keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
289 keymaster_blob_t iv_blob;
290 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
291 LOG_E("No IV provided", 0);
292 return KM_ERROR_INVALID_ARGUMENT;
293 }
294 if (iv_blob.data_length != AES_BLOCK_SIZE) {
295 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
296 iv_blob.data_length);
Thai Duong20d725d2015-03-24 17:49:58 -0700297 return KM_ERROR_INVALID_NONCE;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600298 }
299 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
Shawn Willden92b69a32015-03-14 11:07:36 -0600300 if (!iv_.get())
301 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700302 return KM_ERROR_OK;
303}
304
305inline size_t min(size_t a, size_t b) {
306 if (a < b)
307 return a;
308 return b;
309}
310
311keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
312 const Buffer& input, Buffer* output,
313 size_t* input_consumed) {
314 output->reserve(input.available_read() + AES_BLOCK_SIZE);
315
316 const uint8_t* input_pos = input.peek_read();
317 const uint8_t* input_end = input_pos + input.available_read();
318
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700319 int output_written = -1;
320 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
321 input_end - input_pos))
322 return TranslateLastOpenSslError();
323
324 assert(output_written >= 0);
325 assert(output_written <= (int)output->available_write());
326 output->advance_write(output_written);
327 *input_consumed = input.available_read();
328 return KM_ERROR_OK;
329}
330
331keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
332 const Buffer& /* signature */, Buffer* output) {
333 output->reserve(AES_BLOCK_SIZE);
334
335 int output_written = -1;
336 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
337 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
338 return TranslateLastOpenSslError();
339 }
340
341 assert(output_written <= AES_BLOCK_SIZE);
342 output->advance_write(output_written);
343 return KM_ERROR_OK;
344}
345
346keymaster_error_t AesEvpOperation::Abort() {
347 return KM_ERROR_OK;
348}
349
Shawn Willden907c3012014-12-08 15:51:55 -0700350} // namespace keymaster