aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/tsi/alts
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/tsi/alts')
-rw-r--r--src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc11
-rw-r--r--src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc48
-rw-r--r--src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h4
-rw-r--r--src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc23
-rw-r--r--src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h9
5 files changed, 79 insertions, 16 deletions
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
index 9676085380..1df1021bb1 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
@@ -127,7 +127,8 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector(
tsi_result ok = alts_zero_copy_grpc_protector_create(
reinterpret_cast<const uint8_t*>(result->key_data),
kAltsAes128GcmRekeyKeyLength, /*is_rekey=*/true, result->is_client,
- /*is_integrity_only=*/false, max_output_protected_frame_size, protector);
+ /*is_integrity_only=*/false, /*enable_extra_copy=*/false,
+ max_output_protected_frame_size, protector);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
}
@@ -461,6 +462,14 @@ void alts_tsi_handshaker_handle_response(alts_tsi_handshaker* handshaker,
set_unused_bytes(result, &handshaker->recv_bytes, resp->bytes_consumed);
}
grpc_status_code code = static_cast<grpc_status_code>(resp->status.code);
+ if (code != GRPC_STATUS_OK) {
+ grpc_slice* details = static_cast<grpc_slice*>(resp->status.details.arg);
+ if (details != nullptr) {
+ char* error_details = grpc_slice_to_c_string(*details);
+ gpr_log(GPR_ERROR, "Error from handshaker service:%s", error_details);
+ gpr_free(error_details);
+ }
+ }
grpc_gcp_handshaker_resp_destroy(resp);
cb(alts_tsi_utils_convert_to_tsi_result(code), user_data, bytes_to_send,
bytes_to_send_size, result);
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
index 7ba03eb7f0..352561d469 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
@@ -23,6 +23,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <string.h>
+
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
@@ -30,12 +32,49 @@
/* Main struct for alts_grpc_integrity_only_record_protocol. */
typedef struct alts_grpc_integrity_only_record_protocol {
alts_grpc_record_protocol base;
+ bool enable_extra_copy;
grpc_slice_buffer data_sb;
unsigned char* tag_buf;
} alts_grpc_integrity_only_record_protocol;
/* --- alts_grpc_record_protocol methods implementation. --- */
+static tsi_result alts_grpc_integrity_only_extra_copy_protect(
+ alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
+ grpc_slice_buffer* protected_slices) {
+ /* Allocates memory for protected frame and copies data. */
+ size_t data_length = unprotected_slices->length;
+ size_t protected_frame_size =
+ unprotected_slices->length + rp->header_length + rp->tag_length;
+ grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
+ uint8_t* data = GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
+ for (size_t i = 0; i < unprotected_slices->count; i++) {
+ memcpy(data, GRPC_SLICE_START_PTR(unprotected_slices->slices[i]),
+ GRPC_SLICE_LENGTH(unprotected_slices->slices[i]));
+ data += GRPC_SLICE_LENGTH(unprotected_slices->slices[i]);
+ }
+ /* Calls alts_iovec_record_protocol protect. */
+ char* error_details = nullptr;
+ iovec_t header_iovec = {GRPC_SLICE_START_PTR(protected_slice),
+ rp->header_length};
+ iovec_t tag_iovec = {
+ GRPC_SLICE_START_PTR(protected_slice) + rp->header_length + data_length,
+ rp->tag_length};
+ rp->iovec_buf[0].iov_base =
+ GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
+ rp->iovec_buf[0].iov_len = data_length;
+ grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
+ rp->iovec_rp, rp->iovec_buf, 1, header_iovec, tag_iovec, &error_details);
+ if (status != GRPC_STATUS_OK) {
+ gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
+ gpr_free(error_details);
+ return TSI_INTERNAL_ERROR;
+ }
+ grpc_slice_buffer_add(protected_slices, protected_slice);
+ grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
+ return TSI_OK;
+}
+
static tsi_result alts_grpc_integrity_only_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
@@ -46,6 +85,12 @@ static tsi_result alts_grpc_integrity_only_protect(
"Invalid nullptr arguments to alts_grpc_record_protocol protect.");
return TSI_INVALID_ARGUMENT;
}
+ alts_grpc_integrity_only_record_protocol* integrity_only_record_protocol =
+ reinterpret_cast<alts_grpc_integrity_only_record_protocol*>(rp);
+ if (integrity_only_record_protocol->enable_extra_copy) {
+ return alts_grpc_integrity_only_extra_copy_protect(rp, unprotected_slices,
+ protected_slices);
+ }
/* Allocates memory for header and tag slices. */
grpc_slice header_slice = GRPC_SLICE_MALLOC(rp->header_length);
grpc_slice tag_slice = GRPC_SLICE_MALLOC(rp->tag_length);
@@ -152,7 +197,7 @@ static const alts_grpc_record_protocol_vtable
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
- bool is_protect, alts_grpc_record_protocol** rp) {
+ bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp) {
if (crypter == nullptr || rp == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol create.");
@@ -169,6 +214,7 @@ tsi_result alts_grpc_integrity_only_record_protocol_create(
gpr_free(impl);
return result;
}
+ impl->enable_extra_copy = enable_extra_copy;
/* Initializes slice buffer for data_sb. */
grpc_slice_buffer_init(&impl->data_sb);
/* Allocates tag buffer. */
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
index 8d68b27e07..5456d34fad 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
@@ -38,6 +38,8 @@
* be used at the client or server side.
* - is_protect: a flag indicating if the alts_grpc_record_protocol instance
* will be used for protect or unprotect.
+ *- enable_extra_copy: a flag indicating if the instance uses one-copy instead
+ * of zero-copy in the protect operation.
* - rp: an alts_grpc_record_protocol instance to be returned from
* the method.
*
@@ -46,7 +48,7 @@
*/
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
- bool is_protect, alts_grpc_record_protocol** rp);
+ bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H \
*/
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
index 608213745e..58aba9b747 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
@@ -110,7 +110,7 @@ static bool read_frame_size(const grpc_slice_buffer* sb,
*/
static tsi_result create_alts_grpc_record_protocol(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
- bool is_integrity_only, bool is_protect,
+ bool is_integrity_only, bool is_protect, bool enable_extra_copy,
alts_grpc_record_protocol** record_protocol) {
if (key == nullptr || record_protocol == nullptr) {
return TSI_INVALID_ARGUMENT;
@@ -130,13 +130,13 @@ static tsi_result create_alts_grpc_record_protocol(
: kAltsRecordProtocolFrameLimit;
/* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
*/
- tsi_result result =
- is_integrity_only
- ? alts_grpc_integrity_only_record_protocol_create(
- crypter, overflow_limit, is_client, is_protect, record_protocol)
- : alts_grpc_privacy_integrity_record_protocol_create(
- crypter, overflow_limit, is_client, is_protect,
- record_protocol);
+ tsi_result result = is_integrity_only
+ ? alts_grpc_integrity_only_record_protocol_create(
+ crypter, overflow_limit, is_client, is_protect,
+ enable_extra_copy, record_protocol)
+ : alts_grpc_privacy_integrity_record_protocol_create(
+ crypter, overflow_limit, is_client, is_protect,
+ record_protocol);
if (result != TSI_OK) {
gsec_aead_crypter_destroy(crypter);
return result;
@@ -241,7 +241,8 @@ static const tsi_zero_copy_grpc_protector_vtable
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
- bool is_integrity_only, size_t* max_protected_frame_size,
+ bool is_integrity_only, bool enable_extra_copy,
+ size_t* max_protected_frame_size,
tsi_zero_copy_grpc_protector** protector) {
if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
protector == nullptr) {
@@ -257,11 +258,11 @@ tsi_result alts_zero_copy_grpc_protector_create(
/* Creates alts_grpc_record_protocol objects. */
tsi_result status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
- /*is_protect=*/true, &impl->record_protocol);
+ /*is_protect=*/true, enable_extra_copy, &impl->record_protocol);
if (status == TSI_OK) {
status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
- /*is_protect=*/false, &impl->unrecord_protocol);
+ /*is_protect=*/false, enable_extra_copy, &impl->unrecord_protocol);
if (status == TSI_OK) {
/* Sets maximum frame size. */
size_t max_protected_frame_size_to_set = kDefaultFrameLength;
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
index 71e953cfc1..515c27ea05 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
@@ -35,6 +35,11 @@
* server side.
* - is_integrity_only: a flag indicating if the protector instance will be
* used for integrity-only or privacy-integrity mode.
+ * - enable_extra_copy: a flag indicating if the protector instance does one
+ * extra memory copy during the protect operation for integrity_only mode.
+ * For the unprotect operation, it is still zero-copy. If application intends
+ * to modify the data buffer after the protect operation, we can turn on this
+ * mode to avoid integrity check failure.
* - max_protected_frame_size: an in/out parameter indicating max frame size
* to be used by the protector. If it is nullptr, the default frame size will
* be used. Otherwise, the provided frame size will be adjusted (if not
@@ -45,8 +50,8 @@
*/
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
- bool is_integrity_only, size_t* max_protected_frame_size,
- tsi_zero_copy_grpc_protector** protector);
+ bool is_integrity_only, bool enable_extra_copy,
+ size_t* max_protected_frame_size, tsi_zero_copy_grpc_protector** protector);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H \
*/