aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc')
-rw-r--r--src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
new file mode 100644
index 0000000000..d4fd88d1e2
--- /dev/null
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.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"
+
+/* Privacy-integrity alts_grpc_record_protocol object uses the same struct
+ * defined in alts_grpc_record_protocol_common.h. */
+
+/* --- alts_grpc_record_protocol methods implementation. --- */
+
+static tsi_result alts_grpc_privacy_integrity_protect(
+ alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
+ grpc_slice_buffer* protected_slices) {
+ /* Input sanity check. */
+ if (rp == nullptr || unprotected_slices == nullptr ||
+ protected_slices == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to alts_grpc_record_protocol protect.");
+ return TSI_INVALID_ARGUMENT;
+ }
+ /* Allocates memory for output frame. In privacy-integrity protect, the
+ * protected frame is stored in a newly allocated buffer. */
+ size_t protected_frame_size =
+ unprotected_slices->length + rp->header_length +
+ alts_iovec_record_protocol_get_tag_length(rp->iovec_rp);
+ grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
+ iovec_t protected_iovec = {GRPC_SLICE_START_PTR(protected_slice),
+ GRPC_SLICE_LENGTH(protected_slice)};
+ /* Calls alts_iovec_record_protocol protect. */
+ char* error_details = nullptr;
+ alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
+ unprotected_slices);
+ grpc_status_code status =
+ alts_iovec_record_protocol_privacy_integrity_protect(
+ rp->iovec_rp, rp->iovec_buf, unprotected_slices->count,
+ protected_iovec, &error_details);
+ if (status != GRPC_STATUS_OK) {
+ gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
+ gpr_free(error_details);
+ grpc_slice_unref(protected_slice);
+ 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_privacy_integrity_unprotect(
+ alts_grpc_record_protocol* rp, grpc_slice_buffer* protected_slices,
+ grpc_slice_buffer* unprotected_slices) {
+ /* Input sanity check. */
+ if (rp == nullptr || protected_slices == nullptr ||
+ unprotected_slices == nullptr) {
+ gpr_log(
+ GPR_ERROR,
+ "Invalid nullptr arguments to alts_grpc_record_protocol unprotect.");
+ return TSI_INVALID_ARGUMENT;
+ }
+ /* Allocates memory for output frame. In privacy-integrity unprotect, the
+ * unprotected data are stored in a newly allocated buffer. */
+ if (protected_slices->length < rp->header_length + rp->tag_length) {
+ gpr_log(GPR_ERROR, "Protected slices do not have sufficient data.");
+ return TSI_INVALID_ARGUMENT;
+ }
+ size_t unprotected_frame_size =
+ protected_slices->length - rp->header_length - rp->tag_length;
+ grpc_slice unprotected_slice = GRPC_SLICE_MALLOC(unprotected_frame_size);
+ iovec_t unprotected_iovec = {GRPC_SLICE_START_PTR(unprotected_slice),
+ GRPC_SLICE_LENGTH(unprotected_slice)};
+ /* Strips frame header from protected slices. */
+ grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
+ grpc_slice_buffer_move_first(protected_slices, rp->header_length,
+ &rp->header_sb);
+ iovec_t header_iovec = alts_grpc_record_protocol_get_header_iovec(rp);
+ /* Calls alts_iovec_record_protocol unprotect. */
+ char* error_details = nullptr;
+ alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp, protected_slices);
+ grpc_status_code status =
+ alts_iovec_record_protocol_privacy_integrity_unprotect(
+ rp->iovec_rp, header_iovec, rp->iovec_buf, protected_slices->count,
+ unprotected_iovec, &error_details);
+ if (status != GRPC_STATUS_OK) {
+ gpr_log(GPR_ERROR, "Failed to unprotect, %s", error_details);
+ gpr_free(error_details);
+ grpc_slice_unref(unprotected_slice);
+ return TSI_INTERNAL_ERROR;
+ }
+ grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
+ grpc_slice_buffer_reset_and_unref_internal(protected_slices);
+ grpc_slice_buffer_add(unprotected_slices, unprotected_slice);
+ return TSI_OK;
+}
+
+static const alts_grpc_record_protocol_vtable
+ alts_grpc_privacy_integrity_record_protocol_vtable = {
+ alts_grpc_privacy_integrity_protect,
+ alts_grpc_privacy_integrity_unprotect, nullptr};
+
+tsi_result alts_grpc_privacy_integrity_record_protocol_create(
+ gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
+ bool is_protect, alts_grpc_record_protocol** rp) {
+ if (crypter == nullptr || rp == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to alts_grpc_record_protocol create.");
+ return TSI_INVALID_ARGUMENT;
+ }
+ auto* impl = static_cast<alts_grpc_record_protocol*>(
+ gpr_zalloc(sizeof(alts_grpc_record_protocol)));
+ /* Calls alts_grpc_record_protocol init. */
+ tsi_result result =
+ alts_grpc_record_protocol_init(impl, crypter, overflow_size, is_client,
+ /*is_integrity_only=*/false, is_protect);
+ if (result != TSI_OK) {
+ gpr_free(impl);
+ return result;
+ }
+ impl->vtable = &alts_grpc_privacy_integrity_record_protocol_vtable;
+ *rp = impl;
+ return TSI_OK;
+}