alts_zero_copy_grpc_protector.cc
Go to the documentation of this file.
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 
20 
22 
23 #include <string.h>
24 
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 
37 
38 constexpr size_t kMinFrameLength = 1024;
39 constexpr size_t kDefaultFrameLength = 16 * 1024;
40 constexpr size_t kMaxFrameLength = 16 * 1024 * 1024;
41 
60 
67 static bool read_frame_size(const grpc_slice_buffer* sb,
68  uint32_t* total_frame_size) {
69  if (sb == nullptr || sb->length < kZeroCopyFrameLengthFieldSize) {
70  return false;
71  }
72  uint8_t frame_size_buffer[kZeroCopyFrameLengthFieldSize];
73  uint8_t* buf = frame_size_buffer;
74  /* Copies the first 4 bytes to a temporary buffer. */
75  size_t remaining = kZeroCopyFrameLengthFieldSize;
76  for (size_t i = 0; i < sb->count; i++) {
77  size_t slice_length = GRPC_SLICE_LENGTH(sb->slices[i]);
78  if (remaining <= slice_length) {
79  memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), remaining);
80  remaining = 0;
81  break;
82  } else {
83  memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), slice_length);
84  buf += slice_length;
85  remaining -= slice_length;
86  }
87  }
88  GPR_ASSERT(remaining == 0);
89  /* Gets little-endian frame size. */
90  uint32_t frame_size = (static_cast<uint32_t>(frame_size_buffer[3]) << 24) |
91  (static_cast<uint32_t>(frame_size_buffer[2]) << 16) |
92  (static_cast<uint32_t>(frame_size_buffer[1]) << 8) |
93  static_cast<uint32_t>(frame_size_buffer[0]);
94  if (frame_size > kMaxFrameLength) {
95  gpr_log(GPR_ERROR, "Frame size is larger than maximum frame size");
96  return false;
97  }
98  /* Returns frame size including frame length field. */
99  *total_frame_size =
100  static_cast<uint32_t>(frame_size + kZeroCopyFrameLengthFieldSize);
101  return true;
102 }
103 
112  const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
113  bool is_integrity_only, bool is_protect, bool enable_extra_copy,
114  alts_grpc_record_protocol** record_protocol) {
115  if (key == nullptr || record_protocol == nullptr) {
116  return TSI_INVALID_ARGUMENT;
117  }
119  gsec_aead_crypter* crypter = nullptr;
120  char* error_details = nullptr;
122  kAesGcmTagLength, is_rekey,
123  &crypter, &error_details);
124  if (status != GRPC_STATUS_OK) {
125  gpr_log(GPR_ERROR, "Failed to create AEAD crypter, %s", error_details);
126  gpr_free(error_details);
127  return TSI_INTERNAL_ERROR;
128  }
129  size_t overflow_limit = is_rekey ? kAltsRecordProtocolRekeyFrameLimit
131  /* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
132  */
133  tsi_result result = is_integrity_only
135  crypter, overflow_limit, is_client, is_protect,
136  enable_extra_copy, record_protocol)
138  crypter, overflow_limit, is_client, is_protect,
139  record_protocol);
140  if (result != TSI_OK) {
141  gsec_aead_crypter_destroy(crypter);
142  return result;
143  }
144  return TSI_OK;
145 }
146 
147 /* --- tsi_zero_copy_grpc_protector methods implementation. --- */
148 
150  tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices,
151  grpc_slice_buffer* protected_slices) {
152  if (self == nullptr || unprotected_slices == nullptr ||
153  protected_slices == nullptr) {
154  gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect.");
155  return TSI_INVALID_ARGUMENT;
156  }
157  alts_zero_copy_grpc_protector* protector =
158  reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
159  /* Calls alts_grpc_record_protocol protect repeatly. */
160  while (unprotected_slices->length > protector->max_unprotected_data_size) {
161  grpc_slice_buffer_move_first(unprotected_slices,
162  protector->max_unprotected_data_size,
163  &protector->unprotected_staging_sb);
165  protector->record_protocol, &protector->unprotected_staging_sb,
166  protected_slices);
167  if (status != TSI_OK) {
168  return status;
169  }
170  }
172  protector->record_protocol, unprotected_slices, protected_slices);
173 }
174 
176  tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices,
177  grpc_slice_buffer* unprotected_slices, int* min_progress_size) {
178  if (self == nullptr || unprotected_slices == nullptr ||
179  protected_slices == nullptr) {
181  "Invalid nullptr arguments to zero-copy grpc unprotect.");
182  return TSI_INVALID_ARGUMENT;
183  }
184  alts_zero_copy_grpc_protector* protector =
185  reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
186  grpc_slice_buffer_move_into(protected_slices, &protector->protected_sb);
187  /* Keep unprotecting each frame if possible. */
188  while (protector->protected_sb.length >= kZeroCopyFrameLengthFieldSize) {
189  if (protector->parsed_frame_size == 0) {
190  /* We have not parsed frame size yet. Parses frame size. */
191  if (!read_frame_size(&protector->protected_sb,
192  &protector->parsed_frame_size)) {
194  return TSI_DATA_CORRUPTED;
195  }
196  }
197  if (protector->protected_sb.length < protector->parsed_frame_size) break;
198  /* At this point, protected_sb contains at least one frame of data. */
200  if (protector->protected_sb.length == protector->parsed_frame_size) {
202  &protector->protected_sb,
203  unprotected_slices);
204  } else {
206  protector->parsed_frame_size,
207  &protector->protected_staging_sb);
209  protector->unrecord_protocol, &protector->protected_staging_sb,
210  unprotected_slices);
211  }
212  protector->parsed_frame_size = 0;
213  if (status != TSI_OK) {
215  return status;
216  }
217  }
218  if (min_progress_size != nullptr) {
220  *min_progress_size =
221  protector->parsed_frame_size - protector->protected_sb.length;
222  } else {
223  *min_progress_size = 1;
224  }
225  }
226  return TSI_OK;
227 }
228 
231  if (self == nullptr) {
232  return;
233  }
234  alts_zero_copy_grpc_protector* protector =
235  reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
241  gpr_free(protector);
242 }
243 
245  tsi_zero_copy_grpc_protector* self, size_t* max_frame_size) {
246  if (self == nullptr || max_frame_size == nullptr) return TSI_INVALID_ARGUMENT;
247  alts_zero_copy_grpc_protector* protector =
248  reinterpret_cast<alts_zero_copy_grpc_protector*>(self);
249  *max_frame_size = protector->max_protected_frame_size;
250  return TSI_OK;
251 }
252 
259 
261  const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
262  bool is_integrity_only, bool enable_extra_copy,
263  size_t* max_protected_frame_size,
264  tsi_zero_copy_grpc_protector** protector) {
265  if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
266  protector == nullptr) {
267  gpr_log(
268  GPR_ERROR,
269  "Invalid nullptr arguments to alts_zero_copy_grpc_protector create.");
270  return TSI_INVALID_ARGUMENT;
271  }
272  /* Creates alts_zero_copy_protector. */
274  static_cast<alts_zero_copy_grpc_protector*>(
276  /* Creates alts_grpc_record_protocol objects. */
278  key, key_size, is_rekey, is_client, is_integrity_only,
279  /*is_protect=*/true, enable_extra_copy, &impl->record_protocol);
280  if (status == TSI_OK) {
282  key, key_size, is_rekey, is_client, is_integrity_only,
283  /*is_protect=*/false, enable_extra_copy, &impl->unrecord_protocol);
284  if (status == TSI_OK) {
285  /* Sets maximum frame size. */
286  size_t max_protected_frame_size_to_set = kDefaultFrameLength;
287  if (max_protected_frame_size != nullptr) {
288  *max_protected_frame_size =
289  std::min(*max_protected_frame_size, kMaxFrameLength);
290  *max_protected_frame_size =
291  std::max(*max_protected_frame_size, kMinFrameLength);
292  max_protected_frame_size_to_set = *max_protected_frame_size;
293  }
294  impl->max_protected_frame_size = max_protected_frame_size_to_set;
297  impl->record_protocol, max_protected_frame_size_to_set);
299  /* Allocates internal slice buffers. */
303  impl->parsed_frame_size = 0;
305  *protector = &impl->base;
306  return TSI_OK;
307  }
308  }
309 
310  /* Cleanup if create failed. */
313  gpr_free(impl);
314  return TSI_INTERNAL_ERROR;
315 }
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
grpc_slice_buffer_move_into
GPRAPI void grpc_slice_buffer_move_into(grpc_slice_buffer *src, grpc_slice_buffer *dst)
Definition: slice/slice_buffer.cc:291
alts_zero_copy_grpc_protector::unrecord_protocol
alts_grpc_record_protocol * unrecord_protocol
Definition: alts_zero_copy_grpc_protector.cc:52
alts_zero_copy_grpc_protector_max_frame_size
static tsi_result alts_zero_copy_grpc_protector_max_frame_size(tsi_zero_copy_grpc_protector *self, size_t *max_frame_size)
Definition: alts_zero_copy_grpc_protector.cc:244
log.h
alts_zero_copy_grpc_protector::protected_staging_sb
grpc_slice_buffer protected_staging_sb
Definition: alts_zero_copy_grpc_protector.cc:57
alts_zero_copy_grpc_protector::unprotected_staging_sb
grpc_slice_buffer unprotected_staging_sb
Definition: alts_zero_copy_grpc_protector.cc:55
TSI_INTERNAL_ERROR
@ TSI_INTERNAL_ERROR
Definition: transport_security_interface.h:39
tsi_zero_copy_grpc_protector::vtable
const tsi_zero_copy_grpc_protector_vtable * vtable
Definition: transport_security_grpc.h:80
create_alts_grpc_record_protocol
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 enable_extra_copy, alts_grpc_record_protocol **record_protocol)
Definition: alts_zero_copy_grpc_protector.cc:111
alts_grpc_record_protocol_destroy
void alts_grpc_record_protocol_destroy(alts_grpc_record_protocol *self)
Definition: alts_grpc_record_protocol_common.cc:151
string.h
alts_grpc_record_protocol
Definition: alts_grpc_record_protocol_common.h:47
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
grpc_slice_buffer::slices
grpc_slice * slices
Definition: include/grpc/impl/codegen/slice.h:89
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
useful.h
grpc_status_code
grpc_status_code
Definition: include/grpc/impl/codegen/status.h:28
alts_zero_copy_grpc_protector::parsed_frame_size
uint32_t parsed_frame_size
Definition: alts_zero_copy_grpc_protector.cc:58
alts_zero_copy_grpc_protector_destroy
static void alts_zero_copy_grpc_protector_destroy(tsi_zero_copy_grpc_protector *self)
Definition: alts_zero_copy_grpc_protector.cc:229
status
absl::Status status
Definition: rls.cc:251
alts_zero_copy_grpc_protector::record_protocol
alts_grpc_record_protocol * record_protocol
Definition: alts_zero_copy_grpc_protector.cc:51
alts_zero_copy_grpc_protector
Definition: alts_zero_copy_grpc_protector.cc:49
alts_grpc_record_protocol_max_unprotected_data_size
size_t alts_grpc_record_protocol_max_unprotected_data_size(const alts_grpc_record_protocol *self, size_t max_protected_frame_size)
Definition: alts_grpc_record_protocol_common.cc:167
gsec_aes_gcm_aead_crypter_create
grpc_status_code gsec_aes_gcm_aead_crypter_create(const uint8_t *key, size_t key_length, size_t nonce_length, size_t tag_length, bool rekey, gsec_aead_crypter **crypter, char **error_details)
Definition: aes_gcm.cc:633
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
alts_zero_copy_grpc_protector
struct alts_zero_copy_grpc_protector alts_zero_copy_grpc_protector
alts_iovec_record_protocol.h
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
alts_grpc_integrity_only_record_protocol_create
tsi_result alts_grpc_integrity_only_record_protocol_create(gsec_aead_crypter *crypter, size_t overflow_size, bool is_client, bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol **rp)
Definition: alts_grpc_integrity_only_record_protocol.cc:198
TSI_OK
@ TSI_OK
Definition: transport_security_interface.h:32
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
kAesGcmNonceLength
const size_t kAesGcmNonceLength
Definition: gsec.h:47
GRPC_STATUS_OK
@ GRPC_STATUS_OK
Definition: include/grpc/impl/codegen/status.h:30
read_frame_size
static bool read_frame_size(const grpc_slice_buffer *sb, uint32_t *total_frame_size)
Definition: alts_zero_copy_grpc_protector.cc:67
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
alts_grpc_privacy_integrity_record_protocol.h
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
gsec.h
grpc_slice_buffer::count
size_t count
Definition: include/grpc/impl/codegen/slice.h:91
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
alts_zero_copy_grpc_protector_protect
static tsi_result alts_zero_copy_grpc_protector_protect(tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *unprotected_slices, grpc_slice_buffer *protected_slices)
Definition: alts_zero_copy_grpc_protector.cc:149
alts_grpc_record_protocol_protect
tsi_result alts_grpc_record_protocol_protect(alts_grpc_record_protocol *self, grpc_slice_buffer *unprotected_slices, grpc_slice_buffer *protected_slices)
Definition: alts_grpc_record_protocol_common.cc:123
tsi_result
tsi_result
Definition: transport_security_interface.h:31
grpc_slice_buffer::length
size_t length
Definition: include/grpc/impl/codegen/slice.h:96
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
kMinFrameLength
constexpr size_t kMinFrameLength
Definition: alts_zero_copy_grpc_protector.cc:38
alts_zero_copy_grpc_protector_create
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, bool enable_extra_copy, size_t *max_protected_frame_size, tsi_zero_copy_grpc_protector **protector)
Definition: alts_zero_copy_grpc_protector.cc:260
alts_zero_copy_grpc_protector::max_unprotected_data_size
size_t max_unprotected_data_size
Definition: alts_zero_copy_grpc_protector.cc:54
slice_internal.h
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
min
#define min(a, b)
Definition: qsort.h:83
alts_zero_copy_grpc_protector_vtable
static const tsi_zero_copy_grpc_protector_vtable alts_zero_copy_grpc_protector_vtable
Definition: alts_zero_copy_grpc_protector.cc:254
grpc_slice_buffer_init
GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:116
alts_grpc_privacy_integrity_record_protocol_create
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)
Definition: alts_grpc_privacy_integrity_record_protocol.cc:123
kAltsRecordProtocolRekeyFrameLimit
constexpr size_t kAltsRecordProtocolRekeyFrameLimit
Definition: alts_frame_protector.cc:42
GRPC_SLICE_LENGTH
#define GRPC_SLICE_LENGTH(slice)
Definition: include/grpc/impl/codegen/slice.h:104
alts_zero_copy_grpc_protector.h
TSI_DATA_CORRUPTED
@ TSI_DATA_CORRUPTED
Definition: transport_security_interface.h:40
key
const char * key
Definition: hpack_parser_table.cc:164
alts_grpc_record_protocol.h
kMaxFrameLength
constexpr size_t kMaxFrameLength
Definition: alts_zero_copy_grpc_protector.cc:40
alloc.h
TSI_INVALID_ARGUMENT
@ TSI_INVALID_ARGUMENT
Definition: transport_security_interface.h:34
exec_ctx.h
grpc_slice_buffer_move_first
GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n, grpc_slice_buffer *dst)
Definition: slice/slice_buffer.cc:348
tsi_zero_copy_grpc_protector_vtable
Definition: transport_security_grpc.h:67
grpc_slice_buffer_destroy_internal
void grpc_slice_buffer_destroy_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:123
gsec_aead_crypter
Definition: gsec.h:178
alts_zero_copy_grpc_protector::max_protected_frame_size
size_t max_protected_frame_size
Definition: alts_zero_copy_grpc_protector.cc:53
kDefaultFrameLength
constexpr size_t kDefaultFrameLength
Definition: alts_zero_copy_grpc_protector.cc:39
alts_zero_copy_grpc_protector::base
tsi_zero_copy_grpc_protector base
Definition: alts_zero_copy_grpc_protector.cc:50
gsec_aead_crypter_destroy
void gsec_aead_crypter_destroy(gsec_aead_crypter *crypter)
Definition: gsec.cc:183
grpc_slice_buffer
Definition: include/grpc/impl/codegen/slice.h:83
tsi_zero_copy_grpc_protector
Definition: transport_security_grpc.h:79
kAltsRecordProtocolFrameLimit
constexpr size_t kAltsRecordProtocolFrameLimit
Definition: alts_frame_protector.cc:43
alts_zero_copy_grpc_protector_unprotect
static tsi_result alts_zero_copy_grpc_protector_unprotect(tsi_zero_copy_grpc_protector *self, grpc_slice_buffer *protected_slices, grpc_slice_buffer *unprotected_slices, int *min_progress_size)
Definition: alts_zero_copy_grpc_protector.cc:175
alts_grpc_integrity_only_record_protocol.h
kZeroCopyFrameLengthFieldSize
constexpr size_t kZeroCopyFrameLengthFieldSize
Definition: alts_iovec_record_protocol.h:29
alts_zero_copy_grpc_protector::protected_sb
grpc_slice_buffer protected_sb
Definition: alts_zero_copy_grpc_protector.cc:56
alts_grpc_record_protocol_unprotect
tsi_result alts_grpc_record_protocol_unprotect(alts_grpc_record_protocol *self, grpc_slice_buffer *protected_slices, grpc_slice_buffer *unprotected_slices)
Definition: alts_grpc_record_protocol_common.cc:137
grpc_slice_buffer_reset_and_unref_internal
void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:238
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
kAesGcmTagLength
const size_t kAesGcmTagLength
Definition: gsec.h:48
transport_security_grpc.h
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:41