Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / tsi / alts / zero_copy_frame_protector / alts_grpc_privacy_integrity_record_protocol.cc
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h"
22
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
25
26 #include "src/core/lib/slice/slice_internal.h"
27 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
28 #include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
29
30 /* Privacy-integrity alts_grpc_record_protocol object uses the same struct
31  * defined in alts_grpc_record_protocol_common.h.  */
32
33 /* --- alts_grpc_record_protocol methods implementation. --- */
34
35 static tsi_result alts_grpc_privacy_integrity_protect(
36     alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
37     grpc_slice_buffer* protected_slices) {
38   /* Input sanity check.  */
39   if (rp == nullptr || unprotected_slices == nullptr ||
40       protected_slices == nullptr) {
41     gpr_log(GPR_ERROR,
42             "Invalid nullptr arguments to alts_grpc_record_protocol protect.");
43     return TSI_INVALID_ARGUMENT;
44   }
45   /* Allocates memory for output frame. In privacy-integrity protect, the
46    * protected frame is stored in a newly allocated buffer.  */
47   size_t protected_frame_size =
48       unprotected_slices->length + rp->header_length +
49       alts_iovec_record_protocol_get_tag_length(rp->iovec_rp);
50   grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
51   iovec_t protected_iovec = {GRPC_SLICE_START_PTR(protected_slice),
52                              GRPC_SLICE_LENGTH(protected_slice)};
53   /* Calls alts_iovec_record_protocol protect.  */
54   char* error_details = nullptr;
55   alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
56                                                           unprotected_slices);
57   grpc_status_code status =
58       alts_iovec_record_protocol_privacy_integrity_protect(
59           rp->iovec_rp, rp->iovec_buf, unprotected_slices->count,
60           protected_iovec, &error_details);
61   if (status != GRPC_STATUS_OK) {
62     gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
63     gpr_free(error_details);
64     grpc_slice_unref_internal(protected_slice);
65     return TSI_INTERNAL_ERROR;
66   }
67   grpc_slice_buffer_add(protected_slices, protected_slice);
68   grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
69   return TSI_OK;
70 }
71
72 static tsi_result alts_grpc_privacy_integrity_unprotect(
73     alts_grpc_record_protocol* rp, grpc_slice_buffer* protected_slices,
74     grpc_slice_buffer* unprotected_slices) {
75   /* Input sanity check.  */
76   if (rp == nullptr || protected_slices == nullptr ||
77       unprotected_slices == nullptr) {
78     gpr_log(
79         GPR_ERROR,
80         "Invalid nullptr arguments to alts_grpc_record_protocol unprotect.");
81     return TSI_INVALID_ARGUMENT;
82   }
83   /* Allocates memory for output frame. In privacy-integrity unprotect, the
84    * unprotected data are stored in a newly allocated buffer.  */
85   if (protected_slices->length < rp->header_length + rp->tag_length) {
86     gpr_log(GPR_ERROR, "Protected slices do not have sufficient data.");
87     return TSI_INVALID_ARGUMENT;
88   }
89   size_t unprotected_frame_size =
90       protected_slices->length - rp->header_length - rp->tag_length;
91   grpc_slice unprotected_slice = GRPC_SLICE_MALLOC(unprotected_frame_size);
92   iovec_t unprotected_iovec = {GRPC_SLICE_START_PTR(unprotected_slice),
93                                GRPC_SLICE_LENGTH(unprotected_slice)};
94   /* Strips frame header from protected slices.  */
95   grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
96   grpc_slice_buffer_move_first(protected_slices, rp->header_length,
97                                &rp->header_sb);
98   iovec_t header_iovec = alts_grpc_record_protocol_get_header_iovec(rp);
99   /* Calls alts_iovec_record_protocol unprotect.  */
100   char* error_details = nullptr;
101   alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp, protected_slices);
102   grpc_status_code status =
103       alts_iovec_record_protocol_privacy_integrity_unprotect(
104           rp->iovec_rp, header_iovec, rp->iovec_buf, protected_slices->count,
105           unprotected_iovec, &error_details);
106   if (status != GRPC_STATUS_OK) {
107     gpr_log(GPR_ERROR, "Failed to unprotect, %s", error_details);
108     gpr_free(error_details);
109     grpc_slice_unref_internal(unprotected_slice);
110     return TSI_INTERNAL_ERROR;
111   }
112   grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb);
113   grpc_slice_buffer_reset_and_unref_internal(protected_slices);
114   grpc_slice_buffer_add(unprotected_slices, unprotected_slice);
115   return TSI_OK;
116 }
117
118 static const alts_grpc_record_protocol_vtable
119     alts_grpc_privacy_integrity_record_protocol_vtable = {
120         alts_grpc_privacy_integrity_protect,
121         alts_grpc_privacy_integrity_unprotect, nullptr};
122
123 tsi_result alts_grpc_privacy_integrity_record_protocol_create(
124     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
125     bool is_protect, alts_grpc_record_protocol** rp) {
126   if (crypter == nullptr || rp == nullptr) {
127     gpr_log(GPR_ERROR,
128             "Invalid nullptr arguments to alts_grpc_record_protocol create.");
129     return TSI_INVALID_ARGUMENT;
130   }
131   auto* impl = static_cast<alts_grpc_record_protocol*>(
132       gpr_zalloc(sizeof(alts_grpc_record_protocol)));
133   /* Calls alts_grpc_record_protocol init.  */
134   tsi_result result =
135       alts_grpc_record_protocol_init(impl, crypter, overflow_size, is_client,
136                                      /*is_integrity_only=*/false, is_protect);
137   if (result != TSI_OK) {
138     gpr_free(impl);
139     return result;
140   }
141   impl->vtable = &alts_grpc_privacy_integrity_record_protocol_vtable;
142   *rp = impl;
143   return TSI_OK;
144 }