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