1 /*
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
17 #include "aes_operation.h"
18
19 #include <stdio.h>
20
21 #include <new>
22
23 #include <UniquePtr.h>
24
25 #include <openssl/aes.h>
26 #include <openssl/err.h>
27 #include <openssl/rand.h>
28
29 #include <keymaster/logger.h>
30
31 #include "aes_key.h"
32 #include "openssl_err.h"
33
34 namespace keymaster {
35
36 static const size_t GCM_NONCE_SIZE = 12;
37 static const size_t GCM_MAX_TAG_LENGTH = 16;
38 static const size_t GCM_MIN_TAG_LENGTH = 12;
39
allows_padding(keymaster_block_mode_t block_mode)40 inline bool allows_padding(keymaster_block_mode_t block_mode) {
41 switch (block_mode) {
42 case KM_MODE_CTR:
43 case KM_MODE_GCM:
44 return false;
45 case KM_MODE_ECB:
46 case KM_MODE_CBC:
47 return true;
48 }
49 assert(false /* Can't get here */);
50 return false;
51 }
52
GetAndValidateGcmTagLength(const AuthorizationSet & begin_params,const AuthorizationSet & key_params,size_t * tag_length)53 static keymaster_error_t GetAndValidateGcmTagLength(const AuthorizationSet& begin_params,
54 const AuthorizationSet& key_params,
55 size_t* tag_length) {
56 uint32_t tag_length_bits;
57 if (!begin_params.GetTagValue(TAG_MAC_LENGTH, &tag_length_bits)) {
58 return KM_ERROR_MISSING_MAC_LENGTH;
59 }
60
61 uint32_t min_tag_length_bits;
62 if (!key_params.GetTagValue(TAG_MIN_MAC_LENGTH, &min_tag_length_bits)) {
63 LOG_E("AES GCM key must have KM_TAG_MIN_MAC_LENGTH", 0);
64 return KM_ERROR_INVALID_KEY_BLOB;
65 }
66
67 if (tag_length_bits % 8 != 0 || tag_length_bits > kMaxGcmTagLength ||
68 tag_length_bits < kMinGcmTagLength) {
69 return KM_ERROR_UNSUPPORTED_MAC_LENGTH;
70 }
71
72 if (tag_length_bits < min_tag_length_bits) {
73 return KM_ERROR_INVALID_MAC_LENGTH;
74 }
75
76 *tag_length = tag_length_bits / 8;
77 return KM_ERROR_OK;
78 }
79
CreateOperation(const Key & key,const AuthorizationSet & begin_params,keymaster_error_t * error)80 Operation* AesOperationFactory::CreateOperation(const Key& key,
81 const AuthorizationSet& begin_params,
82 keymaster_error_t* error) {
83 *error = KM_ERROR_OK;
84 const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
85
86 switch (symmetric_key->key_data_size()) {
87 case 16:
88 case 24:
89 case 32:
90 break;
91 default:
92 *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
93 return nullptr;
94 }
95
96 keymaster_block_mode_t block_mode;
97 if (!begin_params.GetTagValue(TAG_BLOCK_MODE, &block_mode)) {
98 LOG_E("%d block modes specified in begin params", begin_params.GetTagCount(TAG_BLOCK_MODE));
99 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
100 return nullptr;
101 } else if (!supported(block_mode)) {
102 LOG_E("Block mode %d not supported", block_mode);
103 *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
104 return nullptr;
105 } else if (!key.authorizations().Contains(TAG_BLOCK_MODE, block_mode)) {
106 LOG_E("Block mode %d was specified, but not authorized by key", block_mode);
107 *error = KM_ERROR_INCOMPATIBLE_BLOCK_MODE;
108 return nullptr;
109 }
110
111 size_t tag_length = 0;
112 if (block_mode == KM_MODE_GCM) {
113 *error = GetAndValidateGcmTagLength(begin_params, key.authorizations(), &tag_length);
114 if (*error != KM_ERROR_OK) {
115 return nullptr;
116 }
117 }
118
119 keymaster_padding_t padding;
120 if (!GetAndValidatePadding(begin_params, key, &padding, error)) {
121 return nullptr;
122 }
123 if (!allows_padding(block_mode) && padding != KM_PAD_NONE) {
124 LOG_E("Mode does not support padding", 0);
125 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
126 return nullptr;
127 }
128
129 bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
130
131 Operation* op = nullptr;
132 switch (purpose()) {
133 case KM_PURPOSE_ENCRYPT:
134 op = new (std::nothrow)
135 AesEvpEncryptOperation(block_mode, padding, caller_nonce, tag_length,
136 symmetric_key->key_data(), symmetric_key->key_data_size());
137 break;
138 case KM_PURPOSE_DECRYPT:
139 op = new (std::nothrow)
140 AesEvpDecryptOperation(block_mode, padding, tag_length, symmetric_key->key_data(),
141 symmetric_key->key_data_size());
142 break;
143 default:
144 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
145 return nullptr;
146 }
147
148 if (!op)
149 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
150 return op;
151 }
152
153 static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
154 KM_MODE_CTR, KM_MODE_GCM};
155
156 const keymaster_block_mode_t*
SupportedBlockModes(size_t * block_mode_count) const157 AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
158 *block_mode_count = array_length(supported_block_modes);
159 return supported_block_modes;
160 }
161
162 static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
163 const keymaster_padding_t*
SupportedPaddingModes(size_t * padding_mode_count) const164 AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
165 *padding_mode_count = array_length(supported_padding_modes);
166 return supported_padding_modes;
167 }
168
AesEvpOperation(keymaster_purpose_t purpose,keymaster_block_mode_t block_mode,keymaster_padding_t padding,bool caller_iv,size_t tag_length,const uint8_t * key,size_t key_size)169 AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
170 keymaster_padding_t padding, bool caller_iv, size_t tag_length,
171 const uint8_t* key, size_t key_size)
172 : Operation(purpose), block_mode_(block_mode), caller_iv_(caller_iv), tag_length_(tag_length),
173 data_started_(false), key_size_(key_size), padding_(padding) {
174 memcpy(key_, key, key_size_);
175 EVP_CIPHER_CTX_init(&ctx_);
176 }
177
~AesEvpOperation()178 AesEvpOperation::~AesEvpOperation() {
179 EVP_CIPHER_CTX_cleanup(&ctx_);
180 memset_s(aad_block_buf_.get(), AES_BLOCK_SIZE, 0);
181 }
182
Begin(const AuthorizationSet &,AuthorizationSet *)183 keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& /* input_params */,
184 AuthorizationSet* /* output_params */) {
185 if (block_mode_ == KM_MODE_GCM) {
186 aad_block_buf_length_ = 0;
187 aad_block_buf_.reset(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
188 if (!aad_block_buf_.get())
189 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
190 }
191
192 return InitializeCipher();
193 }
194
Update(const AuthorizationSet & additional_params,const Buffer & input,AuthorizationSet *,Buffer * output,size_t * input_consumed)195 keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& additional_params,
196 const Buffer& input,
197 AuthorizationSet* /* output_params */, Buffer* output,
198 size_t* input_consumed) {
199 keymaster_error_t error;
200 if (block_mode_ == KM_MODE_GCM)
201 if (!HandleAad(additional_params, input, &error))
202 return error;
203
204 if (!InternalUpdate(input.peek_read(), input.available_read(), output, &error))
205 return error;
206 *input_consumed = input.available_read();
207
208 return KM_ERROR_OK;
209 }
210
is_bad_decrypt(unsigned long error)211 inline bool is_bad_decrypt(unsigned long error) {
212 return (ERR_GET_LIB(error) == ERR_LIB_CIPHER && //
213 ERR_GET_REASON(error) == CIPHER_R_BAD_DECRYPT);
214 }
215
Finish(const AuthorizationSet &,const Buffer &,AuthorizationSet *,Buffer * output)216 keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
217 const Buffer& /* signature */,
218 AuthorizationSet* /* output_params */, Buffer* output) {
219 if (!output->reserve(AES_BLOCK_SIZE))
220 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
221
222 keymaster_error_t error;
223 if (block_mode_ == KM_MODE_GCM && aad_block_buf_length_ > 0 &&
224 !ProcessBufferedAadBlock(&error)) {
225 return error;
226 }
227
228 int output_written = -1;
229 if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
230 if (tag_length_ > 0)
231 return KM_ERROR_VERIFICATION_FAILED;
232 LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
233 return TranslateLastOpenSslError();
234 }
235
236 assert(output_written <= AES_BLOCK_SIZE);
237 if (!output->advance_write(output_written))
238 return KM_ERROR_UNKNOWN_ERROR;
239 return KM_ERROR_OK;
240 }
241
need_iv() const242 bool AesEvpOperation::need_iv() const {
243 switch (block_mode_) {
244 case KM_MODE_CBC:
245 case KM_MODE_CTR:
246 case KM_MODE_GCM:
247 return true;
248 case KM_MODE_ECB:
249 return false;
250 default:
251 // Shouldn't get here.
252 assert(false);
253 return false;
254 }
255 }
256
InitializeCipher()257 keymaster_error_t AesEvpOperation::InitializeCipher() {
258 const EVP_CIPHER* cipher;
259 switch (block_mode_) {
260 case KM_MODE_ECB:
261 switch (key_size_) {
262 case 16:
263 cipher = EVP_aes_128_ecb();
264 break;
265 case 24:
266 cipher = EVP_aes_192_ecb();
267 break;
268 case 32:
269 cipher = EVP_aes_256_ecb();
270 break;
271 default:
272 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
273 }
274 break;
275 case KM_MODE_CBC:
276 switch (key_size_) {
277 case 16:
278 cipher = EVP_aes_128_cbc();
279 break;
280 case 24:
281 cipher = EVP_aes_192_cbc();
282 break;
283 case 32:
284 cipher = EVP_aes_256_cbc();
285 break;
286 default:
287 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
288 }
289 break;
290 case KM_MODE_CTR:
291 switch (key_size_) {
292 case 16:
293 cipher = EVP_aes_128_ctr();
294 break;
295 case 24:
296 cipher = EVP_aes_192_ctr();
297 break;
298 case 32:
299 cipher = EVP_aes_256_ctr();
300 break;
301 default:
302 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
303 }
304 break;
305 case KM_MODE_GCM:
306 switch (key_size_) {
307 case 16:
308 cipher = EVP_aes_128_gcm();
309 break;
310 case 24:
311 cipher = EVP_aes_192_gcm();
312 break;
313 case 32:
314 cipher = EVP_aes_256_gcm();
315 break;
316 default:
317 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
318 }
319 break;
320 default:
321 return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
322 }
323
324 if (!EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode()))
325 return TranslateLastOpenSslError();
326
327 switch (padding_) {
328 case KM_PAD_NONE:
329 EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
330 break;
331 case KM_PAD_PKCS7:
332 // This is the default for OpenSSL EVP cipher operations.
333 break;
334 default:
335 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
336 }
337
338 if (block_mode_ == KM_MODE_GCM) {
339 aad_block_buf_length_ = 0;
340 aad_block_buf_.reset(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
341 if (!aad_block_buf_.get())
342 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
343 }
344
345 return KM_ERROR_OK;
346 }
347
GetIv(const AuthorizationSet & input_params)348 keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
349 keymaster_blob_t iv_blob;
350 if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
351 LOG_E("No IV provided", 0);
352 return KM_ERROR_INVALID_ARGUMENT;
353 }
354 if (block_mode_ != KM_MODE_GCM && iv_blob.data_length != AES_BLOCK_SIZE) {
355 LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
356 iv_blob.data_length);
357 return KM_ERROR_INVALID_NONCE;
358 }
359 if (block_mode_ == KM_MODE_GCM && iv_blob.data_length != GCM_NONCE_SIZE) {
360 LOG_E("Expected %d-byte nonce for AES-GCM operation, but got %d bytes", GCM_NONCE_SIZE,
361 iv_blob.data_length);
362 return KM_ERROR_INVALID_NONCE;
363 }
364 iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
365 if (!iv_.get())
366 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
367 iv_length_ = iv_blob.data_length;
368 return KM_ERROR_OK;
369 }
370
371 /*
372 * Process Incoming Associated Authentication Data.
373 *
374 * This method is more complex than might be expected, because the underlying library silently does
375 * the wrong thing when given partial AAD blocks, so we have to take care to process AAD in
376 * AES_BLOCK_SIZE increments, buffering (in aad_block_buf_) when given smaller amounts of data.
377 */
HandleAad(const AuthorizationSet & input_params,const Buffer & input,keymaster_error_t * error)378 bool AesEvpOperation::HandleAad(const AuthorizationSet& input_params, const Buffer& input,
379 keymaster_error_t* error) {
380 assert(tag_length_ > 0);
381 assert(error);
382
383 keymaster_blob_t aad;
384 if (input_params.GetTagValue(TAG_ASSOCIATED_DATA, &aad)) {
385 if (data_started_) {
386 *error = KM_ERROR_INVALID_TAG;
387 return false;
388 }
389
390 if (aad_block_buf_length_ > 0) {
391 FillBufferedAadBlock(&aad);
392 if (aad_block_buf_length_ == AES_BLOCK_SIZE && !ProcessBufferedAadBlock(error))
393 return false;
394 }
395
396 size_t blocks_to_process = aad.data_length / AES_BLOCK_SIZE;
397 if (blocks_to_process && !ProcessAadBlocks(aad.data, blocks_to_process, error))
398 return false;
399 aad.data += blocks_to_process * AES_BLOCK_SIZE;
400 aad.data_length -= blocks_to_process * AES_BLOCK_SIZE;
401
402 FillBufferedAadBlock(&aad);
403 assert(aad.data_length == 0);
404 }
405
406 if (input.available_read()) {
407 data_started_ = true;
408 // Data has begun, no more AAD is allowed. Process any buffered AAD.
409 if (aad_block_buf_length_ > 0 && !ProcessBufferedAadBlock(error))
410 return false;
411 }
412
413 return true;
414 }
415
ProcessBufferedAadBlock(keymaster_error_t * error)416 bool AesEvpOperation::ProcessBufferedAadBlock(keymaster_error_t* error) {
417 int output_written;
418 if (EVP_CipherUpdate(&ctx_, nullptr /* out */, &output_written, aad_block_buf_.get(),
419 aad_block_buf_length_)) {
420 aad_block_buf_length_ = 0;
421 return true;
422 }
423 *error = TranslateLastOpenSslError();
424 return false;
425 }
426
ProcessAadBlocks(const uint8_t * data,size_t blocks,keymaster_error_t * error)427 bool AesEvpOperation::ProcessAadBlocks(const uint8_t* data, size_t blocks,
428 keymaster_error_t* error) {
429 int output_written;
430 if (EVP_CipherUpdate(&ctx_, nullptr /* out */, &output_written, data, blocks * AES_BLOCK_SIZE))
431 return true;
432 *error = TranslateLastOpenSslError();
433 return false;
434 }
435
min(size_t a,size_t b)436 inline size_t min(size_t a, size_t b) {
437 return (a < b) ? a : b;
438 }
439
FillBufferedAadBlock(keymaster_blob_t * aad)440 void AesEvpOperation::FillBufferedAadBlock(keymaster_blob_t* aad) {
441 size_t to_buffer = min(AES_BLOCK_SIZE - aad_block_buf_length_, aad->data_length);
442 memcpy(aad_block_buf_.get() + aad_block_buf_length_, aad->data, to_buffer);
443 aad->data += to_buffer;
444 aad->data_length -= to_buffer;
445 aad_block_buf_length_ += to_buffer;
446 }
447
InternalUpdate(const uint8_t * input,size_t input_length,Buffer * output,keymaster_error_t * error)448 bool AesEvpOperation::InternalUpdate(const uint8_t* input, size_t input_length, Buffer* output,
449 keymaster_error_t* error) {
450 assert(output);
451 assert(error);
452
453 if (!input_length)
454 return true;
455
456 if (!output->reserve(input_length + AES_BLOCK_SIZE)) {
457 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
458 return false;
459 }
460
461 int output_written = -1;
462 if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input, input_length)) {
463 *error = TranslateLastOpenSslError();
464 return false;
465 }
466 return output->advance_write(output_written);
467 }
468
Begin(const AuthorizationSet & input_params,AuthorizationSet * output_params)469 keymaster_error_t AesEvpEncryptOperation::Begin(const AuthorizationSet& input_params,
470 AuthorizationSet* output_params) {
471 if (!output_params)
472 return KM_ERROR_OUTPUT_PARAMETER_NULL;
473
474 if (need_iv()) {
475 keymaster_error_t error = KM_ERROR_OK;
476 if (input_params.find(TAG_NONCE) == -1)
477 error = GenerateIv();
478 else if (caller_iv_)
479 error = GetIv(input_params);
480 else
481 error = KM_ERROR_CALLER_NONCE_PROHIBITED;
482
483 if (error == KM_ERROR_OK)
484 output_params->push_back(TAG_NONCE, iv_.get(), iv_length_);
485 else
486 return error;
487 }
488
489 return AesEvpOperation::Begin(input_params, output_params);
490 }
491
Finish(const AuthorizationSet & additional_params,const Buffer & signature,AuthorizationSet * output_params,Buffer * output)492 keymaster_error_t AesEvpEncryptOperation::Finish(const AuthorizationSet& additional_params,
493 const Buffer& signature,
494 AuthorizationSet* output_params, Buffer* output) {
495 if (!output->reserve(AES_BLOCK_SIZE + tag_length_))
496 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
497
498 keymaster_error_t error =
499 AesEvpOperation::Finish(additional_params, signature, output_params, output);
500 if (error != KM_ERROR_OK)
501 return error;
502
503 if (tag_length_ > 0) {
504 if (!output->reserve(output->available_read() + tag_length_))
505 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
506
507 if (!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, tag_length_, output->peek_write()))
508 return TranslateLastOpenSslError();
509 if (!output->advance_write(tag_length_))
510 return KM_ERROR_UNKNOWN_ERROR;
511 }
512
513 return KM_ERROR_OK;
514 }
515
GenerateIv()516 keymaster_error_t AesEvpEncryptOperation::GenerateIv() {
517 iv_length_ = (block_mode_ == KM_MODE_GCM) ? GCM_NONCE_SIZE : AES_BLOCK_SIZE;
518 iv_.reset(new (std::nothrow) uint8_t[iv_length_]);
519 if (!iv_.get())
520 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
521 if (RAND_bytes(iv_.get(), iv_length_) != 1)
522 return TranslateLastOpenSslError();
523 return KM_ERROR_OK;
524 }
525
Begin(const AuthorizationSet & input_params,AuthorizationSet * output_params)526 keymaster_error_t AesEvpDecryptOperation::Begin(const AuthorizationSet& input_params,
527 AuthorizationSet* output_params) {
528 if (need_iv()) {
529 keymaster_error_t error = GetIv(input_params);
530 if (error != KM_ERROR_OK)
531 return error;
532 }
533
534 if (tag_length_ > 0) {
535 tag_buf_length_ = 0;
536 tag_buf_.reset(new (std::nothrow) uint8_t[tag_length_]);
537 if (!tag_buf_.get())
538 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
539 }
540
541 return AesEvpOperation::Begin(input_params, output_params);
542 }
543
Update(const AuthorizationSet & additional_params,const Buffer & input,AuthorizationSet *,Buffer * output,size_t * input_consumed)544 keymaster_error_t AesEvpDecryptOperation::Update(const AuthorizationSet& additional_params,
545 const Buffer& input,
546 AuthorizationSet* /* output_params */,
547 Buffer* output, size_t* input_consumed) {
548 if (!output || !input_consumed)
549 return KM_ERROR_OUTPUT_PARAMETER_NULL;
550
551 // Barring error, we'll consume it all.
552 *input_consumed = input.available_read();
553
554 keymaster_error_t error;
555 if (block_mode_ == KM_MODE_GCM) {
556 if (!HandleAad(additional_params, input, &error))
557 return error;
558 return ProcessAllButTagLengthBytes(input, output);
559 }
560
561 if (!InternalUpdate(input.peek_read(), input.available_read(), output, &error))
562 return error;
563 return KM_ERROR_OK;
564 }
565
ProcessAllButTagLengthBytes(const Buffer & input,Buffer * output)566 keymaster_error_t AesEvpDecryptOperation::ProcessAllButTagLengthBytes(const Buffer& input,
567 Buffer* output) {
568 if (input.available_read() <= tag_buf_unused()) {
569 BufferCandidateTagData(input.peek_read(), input.available_read());
570 return KM_ERROR_OK;
571 }
572
573 const size_t data_available = tag_buf_length_ + input.available_read();
574
575 const size_t to_process = data_available - tag_length_;
576 const size_t to_process_from_tag_buf = min(to_process, tag_buf_length_);
577 const size_t to_process_from_input = to_process - to_process_from_tag_buf;
578
579 if (!output->reserve(to_process + AES_BLOCK_SIZE))
580 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
581
582 keymaster_error_t error;
583 if (!ProcessTagBufContentsAsData(to_process_from_tag_buf, output, &error))
584 return error;
585
586 if (!InternalUpdate(input.peek_read(), to_process_from_input, output, &error))
587 return error;
588
589 BufferCandidateTagData(input.peek_read() + to_process_from_input,
590 input.available_read() - to_process_from_input);
591 assert(tag_buf_unused() == 0);
592
593 return KM_ERROR_OK;
594 }
595
ProcessTagBufContentsAsData(size_t to_process,Buffer * output,keymaster_error_t * error)596 bool AesEvpDecryptOperation::ProcessTagBufContentsAsData(size_t to_process, Buffer* output,
597 keymaster_error_t* error) {
598 assert(to_process <= tag_buf_length_);
599 if (!InternalUpdate(tag_buf_.get(), to_process, output, error))
600 return false;
601 if (to_process < tag_buf_length_)
602 memmove(tag_buf_.get(), tag_buf_.get() + to_process, tag_buf_length_ - to_process);
603 tag_buf_length_ -= to_process;
604 return true;
605 }
606
BufferCandidateTagData(const uint8_t * data,size_t data_length)607 void AesEvpDecryptOperation::BufferCandidateTagData(const uint8_t* data, size_t data_length) {
608 assert(data_length <= tag_length_ - tag_buf_length_);
609 memcpy(tag_buf_.get() + tag_buf_length_, data, data_length);
610 tag_buf_length_ += data_length;
611 }
612
Finish(const AuthorizationSet & additional_params,const Buffer & signature,AuthorizationSet * output_params,Buffer * output)613 keymaster_error_t AesEvpDecryptOperation::Finish(const AuthorizationSet& additional_params,
614 const Buffer& signature,
615 AuthorizationSet* output_params, Buffer* output) {
616 if (tag_buf_length_ < tag_length_)
617 return KM_ERROR_INVALID_INPUT_LENGTH;
618 else if (tag_length_ > 0 &&
619 !EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_TAG, tag_length_, tag_buf_.get()))
620 return TranslateLastOpenSslError();
621
622 return AesEvpOperation::Finish(additional_params, signature, output_params, output);
623 }
624
Abort()625 keymaster_error_t AesEvpOperation::Abort() {
626 return KM_ERROR_OK;
627 }
628
629 } // namespace keymaster
630