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