An entrypoint to perform AES encryption on a given expression string. In contrast to AesDecryptImpl(), it does not support ECB modes. For other details, see the comment at AesDecryptImpl().
| 546 | // to AesDecryptImpl(), it does not support ECB modes. For other details, see the |
| 547 | // comment at AesDecryptImpl(). |
| 548 | StringVal StringFunctions::AesEncryptImpl(FunctionContext* ctx, const StringVal& expr, |
| 549 | const StringVal& key, const StringVal& mode, const StringVal& iv) { |
| 550 | if (expr.is_null) { |
| 551 | return StringVal::null(); |
| 552 | } |
| 553 | EncryptionKey encryption_key; |
| 554 | Status status = InitializeEncryptionKey(ctx, expr, key, mode, iv, true, |
| 555 | &encryption_key); |
| 556 | if (!status.ok()) { |
| 557 | ctx->SetError(status.msg().msg().data()); |
| 558 | return StringVal::null(); |
| 559 | } |
| 560 | |
| 561 | // Calculate expected output length |
| 562 | int expected_out_len = expr.len; |
| 563 | |
| 564 | // Append space for gcm_tag in case of GCM mode |
| 565 | if (encryption_key.IsGcmMode()) { |
| 566 | expected_out_len += AES_BLOCK_SIZE; |
| 567 | } |
| 568 | |
| 569 | // Allocate buffer for output |
| 570 | StringVal result = StringVal(ctx, expected_out_len); |
| 571 | // Encrypt the input |
| 572 | int64_t out_len = 0; |
| 573 | status = encryption_key.Encrypt(expr.ptr, expr.len, result.ptr, |
| 574 | &out_len); |
| 575 | if (!status.ok()) { |
| 576 | ctx->SetError("AES encryption failed."); |
| 577 | return StringVal::null(); |
| 578 | } |
| 579 | // Append gcm_tag to encrypted buffer |
| 580 | if (encryption_key.IsGcmMode()) { |
| 581 | encryption_key.GetGcmTag(result.ptr + out_len); |
| 582 | out_len += AES_BLOCK_SIZE; |
| 583 | } |
| 584 | // Ensure expected output length matches actual output length |
| 585 | DCHECK_EQ(expected_out_len, out_len); |
| 586 | return result; |
| 587 | } |
| 588 | } |