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