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