blob: e768b089830472ac35827f53a1089f2e2b75cc7c [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 Willden567a4a02014-12-31 12:14:46 -070039 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070040 virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070041 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const;
Shawn Willden63ac0432014-12-29 14:07:08 -070042
43 virtual keymaster_purpose_t purpose() const = 0;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070044
45 private:
Shawn Willdenf0f68b92014-12-30 16:03:28 -070046 virtual Operation* CreateEvpOperation(const SymmetricKey& key,
47 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -060048 keymaster_padding_t padding, bool caller_iv,
49 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070050};
51
Shawn Willdenf0f68b92014-12-30 16:03:28 -070052Operation* AesOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070053 *error = KM_ERROR_OK;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070054 const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070055
56 switch (symmetric_key->key_data_size()) {
57 case 16:
58 case 24:
59 case 32:
60 break;
61 default:
62 *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
63 return NULL;
64 }
65
Shawn Willden63ac0432014-12-29 14:07:08 -070066 keymaster_block_mode_t block_mode;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070067 if (!key.authorizations().GetTagValue(TAG_BLOCK_MODE, &block_mode) || !supported(block_mode))
68 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
69
70 keymaster_padding_t padding = KM_PAD_NONE;
71 key.authorizations().GetTagValue(TAG_PADDING, &padding);
72
Shawn Willden7a62f5e2015-03-10 12:59:20 -060073 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
74
Shawn Willdenf0f68b92014-12-30 16:03:28 -070075 if (*error != KM_ERROR_OK)
76 return NULL;
77
78 switch (block_mode) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -070079 case KM_MODE_ECB:
80 case KM_MODE_CBC:
Shawn Willden7a62f5e2015-03-10 12:59:20 -060081 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Thai Duong20d725d2015-03-24 17:49:58 -070082 case KM_MODE_CTR:
83 if (padding != KM_PAD_NONE) {
84 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
85 return NULL;
86 }
87 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070088 default:
Shawn Willden63ac0432014-12-29 14:07:08 -070089 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
90 return NULL;
91 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -070092}
93
Shawn Willdenf0f68b92014-12-30 16:03:28 -070094Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
95 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -060096 keymaster_padding_t padding, bool caller_iv,
Shawn Willdenf0f68b92014-12-30 16:03:28 -070097 keymaster_error_t* error) {
98 Operation* op = NULL;
99 switch (purpose()) {
100 case KM_PURPOSE_ENCRYPT:
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600101 op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
102 key.key_data_size());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700103 break;
104 case KM_PURPOSE_DECRYPT:
105 op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
106 break;
107 default:
108 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
109 return NULL;
110 }
111
112 if (!op)
113 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
114 return op;
115}
116
Shawn Willdenc47c88f2015-04-07 17:23:27 -0600117static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
118 KM_MODE_CTR};
Shawn Willden63ac0432014-12-29 14:07:08 -0700119
120const keymaster_block_mode_t*
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700121AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700122 *block_mode_count = array_length(supported_block_modes);
123 return supported_block_modes;
124}
125
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700126static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
127const keymaster_padding_t*
128AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
129 *padding_mode_count = array_length(supported_padding_modes);
130 return supported_padding_modes;
131}
Shawn Willden63ac0432014-12-29 14:07:08 -0700132
133/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700134 * Concrete factory for AES encryption operations.
Shawn Willden63ac0432014-12-29 14:07:08 -0700135 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700136class AesEncryptionOperationFactory : public AesOperationFactory {
137 keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
138};
139static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
140
141/**
142 * Concrete factory for AES decryption operations.
143 */
144class AesDecryptionOperationFactory : public AesOperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -0700145 keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
146};
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700147static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
Shawn Willden63ac0432014-12-29 14:07:08 -0700148
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700149AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600150 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
151 size_t key_size)
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700152 : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600153 caller_iv_(caller_iv) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700154 memcpy(key_, key, key_size_);
155 EVP_CIPHER_CTX_init(&ctx_);
156}
157
158AesEvpOperation::~AesEvpOperation() {
159 EVP_CIPHER_CTX_cleanup(&ctx_);
160}
161
162keymaster_error_t AesEvpOperation::InitializeCipher() {
163 const EVP_CIPHER* cipher;
164 switch (block_mode_) {
165 case KM_MODE_ECB:
166 switch (key_size_) {
167 case 16:
168 cipher = EVP_aes_128_ecb();
169 break;
170 case 24:
171 cipher = EVP_aes_192_ecb();
172 break;
173 case 32:
174 cipher = EVP_aes_256_ecb();
175 break;
176 default:
177 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
178 }
179 break;
180 case KM_MODE_CBC:
181 switch (key_size_) {
182 case 16:
183 cipher = EVP_aes_128_cbc();
184 break;
185 case 24:
186 cipher = EVP_aes_192_cbc();
187 break;
188 case 32:
189 cipher = EVP_aes_256_cbc();
190 break;
191 default:
192 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
193 }
194 break;
Thai Duong20d725d2015-03-24 17:49:58 -0700195 case KM_MODE_CTR:
196 switch (key_size_) {
197 case 16:
198 cipher = EVP_aes_128_ctr();
199 break;
200 case 24:
201 cipher = EVP_aes_192_ctr();
202 break;
203 case 32:
204 cipher = EVP_aes_256_ctr();
205 break;
206 default:
207 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
208 }
209 break;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700210 default:
211 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
212 }
213
214 int init_result =
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600215 EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700216
217 if (!init_result)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600218 return TranslateLastOpenSslError();
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700219
220 switch (padding_) {
221 case KM_PAD_NONE:
222 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
223 break;
224 case KM_PAD_PKCS7:
225 // This is the default for OpenSSL EVP cipher operations.
226 break;
227 default:
228 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
229 }
230
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700231 return KM_ERROR_OK;
232}
233
234bool AesEvpOperation::need_iv() const {
235 switch (block_mode_) {
236 case KM_MODE_CBC:
Thai Duong20d725d2015-03-24 17:49:58 -0700237 case KM_MODE_CTR:
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700238 return true;
239 case KM_MODE_ECB:
240 return false;
241 default:
242 // Shouldn't get here.
243 assert(false);
244 return false;
245 }
246}
247
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600248keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
249 AuthorizationSet* output_params) {
250 if (!output_params)
251 return KM_ERROR_OUTPUT_PARAMETER_NULL;
252
253 keymaster_error_t error = KM_ERROR_OK;
254 if (need_iv()) {
255 switch (purpose()) {
256 case KM_PURPOSE_ENCRYPT:
257 if (caller_iv_)
258 error = GetIv(input_params);
259 else {
260 iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
261 if (!iv_.get())
262 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
263 if (!RAND_bytes(iv_.get(), AES_BLOCK_SIZE))
264 error = TranslateLastOpenSslError();
265 }
266
267 if (error == KM_ERROR_OK)
268 output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
269 break;
270
271 case KM_PURPOSE_DECRYPT:
272 error = GetIv(input_params);
273 break;
274 default:
275 return KM_ERROR_UNSUPPORTED_PURPOSE;
276 }
277 }
278
279 if (error == KM_ERROR_OK)
280 error = InitializeCipher();
281
282 return error;
283}
284
285keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
286 keymaster_blob_t iv_blob;
287 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
288 LOG_E("No IV provided", 0);
289 return KM_ERROR_INVALID_ARGUMENT;
290 }
291 if (iv_blob.data_length != AES_BLOCK_SIZE) {
292 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
293 iv_blob.data_length);
Thai Duong20d725d2015-03-24 17:49:58 -0700294 return KM_ERROR_INVALID_NONCE;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600295 }
296 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
Shawn Willden92b69a32015-03-14 11:07:36 -0600297 if (!iv_.get())
298 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700299 return KM_ERROR_OK;
300}
301
302inline size_t min(size_t a, size_t b) {
303 if (a < b)
304 return a;
305 return b;
306}
307
308keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
309 const Buffer& input, Buffer* output,
310 size_t* input_consumed) {
311 output->reserve(input.available_read() + AES_BLOCK_SIZE);
312
313 const uint8_t* input_pos = input.peek_read();
314 const uint8_t* input_end = input_pos + input.available_read();
315
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700316 int output_written = -1;
317 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
318 input_end - input_pos))
319 return TranslateLastOpenSslError();
320
321 assert(output_written >= 0);
322 assert(output_written <= (int)output->available_write());
323 output->advance_write(output_written);
324 *input_consumed = input.available_read();
325 return KM_ERROR_OK;
326}
327
328keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
329 const Buffer& /* signature */, Buffer* output) {
330 output->reserve(AES_BLOCK_SIZE);
331
332 int output_written = -1;
333 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
334 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
335 return TranslateLastOpenSslError();
336 }
337
338 assert(output_written <= AES_BLOCK_SIZE);
339 output->advance_write(output_written);
340 return KM_ERROR_OK;
341}
342
343keymaster_error_t AesEvpOperation::Abort() {
344 return KM_ERROR_OK;
345}
346
Shawn Willden907c3012014-12-08 15:51:55 -0700347} // namespace keymaster