diff options
Diffstat (limited to 'src/core/tsi/alts')
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 \ */ |