MCPcopy Create free account
hub / github.com/apache/impala / EncryptInternal

Method EncryptInternal

be/src/util/openssl-util.cc:462–563  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

460}
461
462Status EncryptionKey::EncryptInternal(
463 bool encrypt, const uint8_t* data, int64_t len, uint8_t* out, int64_t* out_len) {
464 DCHECK(initialized_);
465 DCHECK_GE(len, 0);
466 if (IsEcbMode()) {
467 if ((encrypt && len > numeric_limits<int>::max() - AES_BLOCK_SIZE)
468 || (!encrypt && len > numeric_limits<int>::max())) {
469 return Status("Input buffer length exceeds the supported length for ECB mode.");
470 }
471 }
472
473 const char* err_context = encrypt ? "encrypting" : "decrypting";
474 // Create and initialize the context for encryption.
475 // If it is ECB mode then padding will be enabled
476 // for this ctx, otherwise it will be disabled.
477 bool padding_enabled = IsEcbMode();
478 int padding_flag = padding_enabled ? 1 : 0;
479 ScopedEVPCipherCtx ctx(padding_flag);
480
481 // Start encryption/decryption. We use a 128/256-bit AES key and support GCM, CTR
482 // CFB and ECB for encryption and decryption. When the cipher block mode is either
483 // GCM, CTR or CFB(stream cipher), it supports arbitrary length ciphertexts - it
484 // doesn't have to be a multiple of 16 bytes. While for ECB decryption,
485 // the length has to be multiples of 16. Additionally, CTR mode is
486 // well-optimized (instruction level parallelism) with hardware acceleration
487 // on x86 and PowerPC.
488
489 // In the first initialization, only evpCipher is initialized, and in the second
490 // initialization, the key and IV vector are set. This approach is necessary because a
491 // variable-length IV vector is used. Therefore, in GCM mode, the IV length must be
492 // initialized before setting the IV vector.
493 const EVP_CIPHER* evpCipher = GetCipher();
494 DCHECK(evpCipher != nullptr);
495 int success = encrypt ?
496 EVP_EncryptInit_ex(ctx.ctx, evpCipher, nullptr, nullptr, nullptr):
497 EVP_DecryptInit_ex(ctx.ctx, evpCipher, nullptr, nullptr, nullptr);
498 if (success != 1) {
499 return OpenSSLErr(encrypt ? "EVP_EncryptInit_ex" : "EVP_DecryptInit_ex", err_context);
500 }
501
502 if (IsGcmMode()) {
503 // Set iv_vector for GCM mode.
504 if (EVP_CIPHER_CTX_ctrl(ctx.ctx, EVP_CTRL_GCM_SET_IVLEN, iv_length_, nullptr)!= 1) {
505 return OpenSSLErr("EVP_CIPHER_CTX_ctrl", err_context);
506 }
507 }
508 // setting iv after changing iv len, see https://github.com/openssl/openssl/pull/22590
509 success = encrypt ? EVP_EncryptInit_ex(ctx.ctx, nullptr, nullptr, key_, iv_):
510 EVP_DecryptInit_ex(ctx.ctx, nullptr, nullptr, key_, iv_);
511 if (success != 1) {
512 return OpenSSLErr(encrypt ? "EVP_EncryptInit_ex" : "EVP_DecryptInit_ex", err_context);
513 }
514
515 // The OpenSSL encryption APIs use INT for buffer lengths. To support larger buffers,
516 // larger buffers need to be chunked into smaller parts.
517 int64_t output_offset = 0;
518 int64_t input_offset = 0;
519 while (input_offset < len) {

Callers

nothing calls this directly

Calls 4

maxFunction · 0.85
OpenSSLErrFunction · 0.85
OKFunction · 0.85
StatusClass · 0.70

Tested by

no test coverage detected