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