An entrypoint to perform AES decryption on a given expression string. GCM mode expects expression, key, AES mode and iv vector. CTR and CFB modes expect expression, key, AES mode and iv vector. ECB mode expects expression, key, AES mode. If 'mode' is NULL, a default mode will be chosen at runtime. If the mode passed by the user is not supported by Impala or by the OpenSSL library used internally
| 503 | // block-by-block basis, where the previous ciphertext block is encrypted and then XORed |
| 504 | // with the plaintext to produce the next ciphertext block. |
| 505 | StringVal StringFunctions::AesDecryptImpl(FunctionContext* ctx, const StringVal& expr, |
| 506 | const StringVal& key, const StringVal& mode, const StringVal& iv) { |
| 507 | if (expr.is_null) { |
| 508 | return StringVal::null(); |
| 509 | } |
| 510 | EncryptionKey encryption_key; |
| 511 | Status status = InitializeEncryptionKey(ctx, expr, key, mode, iv, false, |
| 512 | &encryption_key); |
| 513 | if (!status.ok()) { |
| 514 | ctx->SetError(status.msg().msg().data()); |
| 515 | return StringVal::null(); |
| 516 | } |
| 517 | int64_t len = expr.len; |
| 518 | |
| 519 | // Remove spaces and set value of gcm_tag in case of GCM mode |
| 520 | if (encryption_key.IsGcmMode()) { |
| 521 | if (len < AES_BLOCK_SIZE) { |
| 522 | ctx->SetError("AES GCM input too short to contain a tag"); |
| 523 | return StringVal::null(); |
| 524 | } |
| 525 | len -= AES_BLOCK_SIZE; |
| 526 | encryption_key.SetGcmTag(expr.ptr + len); |
| 527 | } |
| 528 | |
| 529 | StringVal result = StringVal(ctx, len); |
| 530 | |
| 531 | // Decrypt the input |
| 532 | int64_t out_len = 0; |
| 533 | status = encryption_key.Decrypt(expr.ptr, len, result.ptr, &out_len); |
| 534 | if (!status.ok()) { |
| 535 | ctx->SetError("AES decryption failed"); |
| 536 | return StringVal::null(); |
| 537 | } |
| 538 | const int64_t len_diff = result.len - out_len; |
| 539 | DCHECK(len_diff == 0 || (encryption_key.IsEcbMode() && 0 < len_diff && |
| 540 | len_diff <= AES_BLOCK_SIZE)); |
| 541 | result.len = out_len; |
| 542 | return result; |
| 543 | } |
| 544 | |
| 545 | // An entrypoint to perform AES encryption on a given expression string. In contrast |
| 546 | // to AesDecryptImpl(), it does not support ECB modes. For other details, see the |