blob: aab185c320ec3e8ab064a5e16d144b4c42baef90 [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 Willden7a62f5e2015-03-10 12:59:20 -060046 virtual Operation* CreateOcbOperation(const SymmetricKey& key, bool caller_nonce,
47 keymaster_error_t* error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070048 virtual Operation* CreateEvpOperation(const SymmetricKey& key,
49 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -060050 keymaster_padding_t padding, bool caller_iv,
51 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070052};
53
Shawn Willdenf0f68b92014-12-30 16:03:28 -070054Operation* AesOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070055 *error = KM_ERROR_OK;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070056 const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070057
58 switch (symmetric_key->key_data_size()) {
59 case 16:
60 case 24:
61 case 32:
62 break;
63 default:
64 *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
65 return NULL;
66 }
67
Shawn Willden63ac0432014-12-29 14:07:08 -070068 keymaster_block_mode_t block_mode;
Shawn Willdenf0f68b92014-12-30 16:03:28 -070069 if (!key.authorizations().GetTagValue(TAG_BLOCK_MODE, &block_mode) || !supported(block_mode))
70 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
71
72 keymaster_padding_t padding = KM_PAD_NONE;
73 key.authorizations().GetTagValue(TAG_PADDING, &padding);
74
Shawn Willden7a62f5e2015-03-10 12:59:20 -060075 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
76
Shawn Willdenf0f68b92014-12-30 16:03:28 -070077 if (*error != KM_ERROR_OK)
78 return NULL;
79
80 switch (block_mode) {
81 case KM_MODE_OCB:
82 if (padding != KM_PAD_NONE) {
83 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
84 return NULL;
85 }
Shawn Willden7a62f5e2015-03-10 12:59:20 -060086 return CreateOcbOperation(*symmetric_key, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070087 case KM_MODE_ECB:
88 case KM_MODE_CBC:
Shawn Willden7a62f5e2015-03-10 12:59:20 -060089 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Thai Duong20d725d2015-03-24 17:49:58 -070090 case KM_MODE_CTR:
91 if (padding != KM_PAD_NONE) {
92 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
93 return NULL;
94 }
95 return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
Shawn Willdenf0f68b92014-12-30 16:03:28 -070096 default:
Shawn Willden63ac0432014-12-29 14:07:08 -070097 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
98 return NULL;
99 }
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700100}
101
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600102Operation* AesOperationFactory::CreateOcbOperation(const SymmetricKey& key, bool caller_nonce,
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700103 keymaster_error_t* error) {
104 *error = KM_ERROR_OK;
Shawn Willden63ac0432014-12-29 14:07:08 -0700105
106 uint32_t chunk_length;
107 if (!key.authorizations().GetTagValue(TAG_CHUNK_LENGTH, &chunk_length) ||
108 chunk_length > AeadModeOperation::MAX_CHUNK_LENGTH)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600109 *error = KM_ERROR_UNSUPPORTED_CHUNK_LENGTH;
Shawn Willden63ac0432014-12-29 14:07:08 -0700110
111 uint32_t tag_length;
112 if (!key.authorizations().GetTagValue(TAG_MAC_LENGTH, &tag_length) ||
113 tag_length > AeadModeOperation::MAX_TAG_LENGTH)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600114 *error = KM_ERROR_UNSUPPORTED_MAC_LENGTH;
Shawn Willden63ac0432014-12-29 14:07:08 -0700115
116 keymaster_padding_t padding;
117 if (key.authorizations().GetTagValue(TAG_PADDING, &padding) && padding != KM_PAD_NONE)
118 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
119
Shawn Willden63ac0432014-12-29 14:07:08 -0700120 if (*error != KM_ERROR_OK)
121 return NULL;
122
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700123 Operation* op = new AesOcbOperation(purpose(), key.key_data(), key.key_data_size(),
Shawn Willdendfa1c032015-02-07 00:39:01 -0700124 chunk_length, tag_length, caller_nonce);
Shawn Willden63ac0432014-12-29 14:07:08 -0700125 if (!op)
126 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
127 return op;
128}
129
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700130Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
131 keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600132 keymaster_padding_t padding, bool caller_iv,
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700133 keymaster_error_t* error) {
134 Operation* op = NULL;
135 switch (purpose()) {
136 case KM_PURPOSE_ENCRYPT:
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600137 op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
138 key.key_data_size());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700139 break;
140 case KM_PURPOSE_DECRYPT:
141 op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
142 break;
143 default:
144 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
145 return NULL;
146 }
147
148 if (!op)
149 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
150 return op;
151}
152
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600153static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_OCB, KM_MODE_ECB,
Thai Duong20d725d2015-03-24 17:49:58 -0700154 KM_MODE_CBC, KM_MODE_CTR};
Shawn Willden63ac0432014-12-29 14:07:08 -0700155
156const keymaster_block_mode_t*
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700157AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700158 *block_mode_count = array_length(supported_block_modes);
159 return supported_block_modes;
160}
161
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700162static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
163const keymaster_padding_t*
164AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
165 *padding_mode_count = array_length(supported_padding_modes);
166 return supported_padding_modes;
167}
Shawn Willden63ac0432014-12-29 14:07:08 -0700168
169/**
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700170 * Concrete factory for AES encryption operations.
Shawn Willden63ac0432014-12-29 14:07:08 -0700171 */
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700172class AesEncryptionOperationFactory : public AesOperationFactory {
173 keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
174};
175static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
176
177/**
178 * Concrete factory for AES decryption operations.
179 */
180class AesDecryptionOperationFactory : public AesOperationFactory {
Shawn Willden63ac0432014-12-29 14:07:08 -0700181 keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
182};
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700183static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
Shawn Willden63ac0432014-12-29 14:07:08 -0700184
Shawn Willden6dde87c2014-12-11 14:08:48 -0700185keymaster_error_t AesOcbOperation::Initialize(uint8_t* key, size_t key_size, size_t nonce_length,
186 size_t tag_length) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700187 if (tag_length > MAX_TAG_LENGTH || nonce_length > MAX_NONCE_LENGTH)
Shawn Willden6dde87c2014-12-11 14:08:48 -0700188 return KM_ERROR_INVALID_KEY_BLOB;
Shawn Willden907c3012014-12-08 15:51:55 -0700189
Shawn Willden6dde87c2014-12-11 14:08:48 -0700190 if (ae_init(ctx(), key, key_size, nonce_length, tag_length) != AE_SUCCESS) {
191 memset_s(ctx(), 0, ae_ctx_sizeof());
Shawn Willden907c3012014-12-08 15:51:55 -0700192 return KM_ERROR_UNKNOWN_ERROR;
193 }
Shawn Willden907c3012014-12-08 15:51:55 -0700194 return KM_ERROR_OK;
195}
196
Shawn Willden6dde87c2014-12-11 14:08:48 -0700197keymaster_error_t AesOcbOperation::EncryptChunk(const uint8_t* nonce, size_t /* nonce_length */,
198 size_t tag_length,
199 const keymaster_blob_t additional_data,
200 uint8_t* chunk, size_t chunk_size, Buffer* output) {
201 if (!ctx())
202 return KM_ERROR_UNKNOWN_ERROR;
203 uint8_t __attribute__((aligned(16))) tag[MAX_TAG_LENGTH];
Shawn Willden907c3012014-12-08 15:51:55 -0700204
Shawn Willden6dde87c2014-12-11 14:08:48 -0700205 // Encrypt chunk in place.
206 int ae_err = ae_encrypt(ctx(), nonce, chunk, chunk_size, additional_data.data,
207 additional_data.data_length, chunk, tag, AE_FINALIZE);
Shawn Willden907c3012014-12-08 15:51:55 -0700208
Shawn Willden907c3012014-12-08 15:51:55 -0700209 if (ae_err < 0)
210 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden6dde87c2014-12-11 14:08:48 -0700211 assert(ae_err == (int)buffered_data_length());
Shawn Willden907c3012014-12-08 15:51:55 -0700212
Shawn Willden6dde87c2014-12-11 14:08:48 -0700213 output->write(chunk, buffered_data_length());
214 output->write(tag, tag_length);
Shawn Willden907c3012014-12-08 15:51:55 -0700215
216 return KM_ERROR_OK;
217}
218
Shawn Willden6dde87c2014-12-11 14:08:48 -0700219keymaster_error_t AesOcbOperation::DecryptChunk(const uint8_t* nonce, size_t /* nonce_length */,
220 const uint8_t* tag, size_t /* tag_length */,
221 const keymaster_blob_t additional_data,
222 uint8_t* chunk, size_t chunk_size, Buffer* output) {
223 if (!ctx())
224 return KM_ERROR_UNKNOWN_ERROR;
225
226 // Decrypt chunk in place
227 int ae_err = ae_decrypt(ctx(), nonce, chunk, chunk_size, additional_data.data,
228 additional_data.data_length, chunk, tag, AE_FINALIZE);
229 if (ae_err == AE_INVALID)
230 return KM_ERROR_VERIFICATION_FAILED;
231 else if (ae_err < 0)
232 return KM_ERROR_UNKNOWN_ERROR;
233 assert(ae_err == (int)buffered_data_length());
234 output->write(chunk, chunk_size);
235
236 return KM_ERROR_OK;
Shawn Willden907c3012014-12-08 15:51:55 -0700237}
238
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700239AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600240 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
241 size_t key_size)
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700242 : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600243 caller_iv_(caller_iv) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700244 memcpy(key_, key, key_size_);
245 EVP_CIPHER_CTX_init(&ctx_);
246}
247
248AesEvpOperation::~AesEvpOperation() {
249 EVP_CIPHER_CTX_cleanup(&ctx_);
250}
251
252keymaster_error_t AesEvpOperation::InitializeCipher() {
253 const EVP_CIPHER* cipher;
254 switch (block_mode_) {
255 case KM_MODE_ECB:
256 switch (key_size_) {
257 case 16:
258 cipher = EVP_aes_128_ecb();
259 break;
260 case 24:
261 cipher = EVP_aes_192_ecb();
262 break;
263 case 32:
264 cipher = EVP_aes_256_ecb();
265 break;
266 default:
267 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
268 }
269 break;
270 case KM_MODE_CBC:
271 switch (key_size_) {
272 case 16:
273 cipher = EVP_aes_128_cbc();
274 break;
275 case 24:
276 cipher = EVP_aes_192_cbc();
277 break;
278 case 32:
279 cipher = EVP_aes_256_cbc();
280 break;
281 default:
282 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
283 }
284 break;
Thai Duong20d725d2015-03-24 17:49:58 -0700285 case KM_MODE_CTR:
286 switch (key_size_) {
287 case 16:
288 cipher = EVP_aes_128_ctr();
289 break;
290 case 24:
291 cipher = EVP_aes_192_ctr();
292 break;
293 case 32:
294 cipher = EVP_aes_256_ctr();
295 break;
296 default:
297 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
298 }
299 break;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700300 default:
301 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
302 }
303
304 int init_result =
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600305 EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700306
307 if (!init_result)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600308 return TranslateLastOpenSslError();
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700309
310 switch (padding_) {
311 case KM_PAD_NONE:
312 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
313 break;
314 case KM_PAD_PKCS7:
315 // This is the default for OpenSSL EVP cipher operations.
316 break;
317 default:
318 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
319 }
320
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700321 return KM_ERROR_OK;
322}
323
324bool AesEvpOperation::need_iv() const {
325 switch (block_mode_) {
326 case KM_MODE_CBC:
Thai Duong20d725d2015-03-24 17:49:58 -0700327 case KM_MODE_CTR:
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700328 return true;
329 case KM_MODE_ECB:
330 return false;
331 default:
332 // Shouldn't get here.
333 assert(false);
334 return false;
335 }
336}
337
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600338keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
339 AuthorizationSet* output_params) {
340 if (!output_params)
341 return KM_ERROR_OUTPUT_PARAMETER_NULL;
342
343 keymaster_error_t error = KM_ERROR_OK;
344 if (need_iv()) {
345 switch (purpose()) {
346 case KM_PURPOSE_ENCRYPT:
347 if (caller_iv_)
348 error = GetIv(input_params);
349 else {
350 iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
351 if (!iv_.get())
352 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
353 if (!RAND_bytes(iv_.get(), AES_BLOCK_SIZE))
354 error = TranslateLastOpenSslError();
355 }
356
357 if (error == KM_ERROR_OK)
358 output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
359 break;
360
361 case KM_PURPOSE_DECRYPT:
362 error = GetIv(input_params);
363 break;
364 default:
365 return KM_ERROR_UNSUPPORTED_PURPOSE;
366 }
367 }
368
369 if (error == KM_ERROR_OK)
370 error = InitializeCipher();
371
372 return error;
373}
374
375keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
376 keymaster_blob_t iv_blob;
377 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
378 LOG_E("No IV provided", 0);
379 return KM_ERROR_INVALID_ARGUMENT;
380 }
381 if (iv_blob.data_length != AES_BLOCK_SIZE) {
382 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
383 iv_blob.data_length);
Thai Duong20d725d2015-03-24 17:49:58 -0700384 return KM_ERROR_INVALID_NONCE;
Shawn Willden7a62f5e2015-03-10 12:59:20 -0600385 }
386 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
Shawn Willden92b69a32015-03-14 11:07:36 -0600387 if (!iv_.get())
388 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700389 return KM_ERROR_OK;
390}
391
392inline size_t min(size_t a, size_t b) {
393 if (a < b)
394 return a;
395 return b;
396}
397
398keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
399 const Buffer& input, Buffer* output,
400 size_t* input_consumed) {
401 output->reserve(input.available_read() + AES_BLOCK_SIZE);
402
403 const uint8_t* input_pos = input.peek_read();
404 const uint8_t* input_end = input_pos + input.available_read();
405
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700406 int output_written = -1;
407 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
408 input_end - input_pos))
409 return TranslateLastOpenSslError();
410
411 assert(output_written >= 0);
412 assert(output_written <= (int)output->available_write());
413 output->advance_write(output_written);
414 *input_consumed = input.available_read();
415 return KM_ERROR_OK;
416}
417
418keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
419 const Buffer& /* signature */, Buffer* output) {
420 output->reserve(AES_BLOCK_SIZE);
421
422 int output_written = -1;
423 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
424 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
425 return TranslateLastOpenSslError();
426 }
427
428 assert(output_written <= AES_BLOCK_SIZE);
429 output->advance_write(output_written);
430 return KM_ERROR_OK;
431}
432
433keymaster_error_t AesEvpOperation::Abort() {
434 return KM_ERROR_OK;
435}
436
Shawn Willden907c3012014-12-08 15:51:55 -0700437} // namespace keymaster