• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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