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 #ifndef GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H
20 #define GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <stdbool.h>
25 
26 #include "src/core/tsi/alts/crypt/gsec.h"
27 
28 constexpr size_t kZeroCopyFrameMessageType = 0x06;
29 constexpr size_t kZeroCopyFrameLengthFieldSize = 4;
30 constexpr size_t kZeroCopyFrameMessageTypeFieldSize = 4;
31 constexpr size_t kZeroCopyFrameHeaderSize =
32     kZeroCopyFrameLengthFieldSize + kZeroCopyFrameMessageTypeFieldSize;
33 
34 // Limit k on number of frames such that at most 2^(8 * k) frames can be sent.
35 constexpr size_t kAltsRecordProtocolRekeyFrameLimit = 8;
36 constexpr size_t kAltsRecordProtocolFrameLimit = 5;
37 
38 /* An implementation of alts record protocol. The API is thread-compatible. */
39 
40 typedef struct iovec iovec_t;
41 
42 typedef struct alts_iovec_record_protocol alts_iovec_record_protocol;
43 
44 /**
45  * This method gets the length of record protocol frame header.
46  */
47 size_t alts_iovec_record_protocol_get_header_length();
48 
49 /**
50  * This method gets the length of record protocol frame tag.
51  *
52  * - rp: an alts_iovec_record_protocol instance.
53  *
54  * On success, the method returns the length of record protocol frame tag.
55  * Otherwise, it returns zero.
56  */
57 size_t alts_iovec_record_protocol_get_tag_length(
58     const alts_iovec_record_protocol* rp);
59 
60 /**
61  * This method returns maximum allowed unprotected data size, given maximum
62  * protected frame size.
63  *
64  * - rp: an alts_iovec_record_protocol instance.
65  * - max_protected_frame_size: maximum protected frame size.
66  *
67  * On success, the method returns the maximum allowed unprotected data size.
68  * Otherwise, it returns zero.
69  */
70 size_t alts_iovec_record_protocol_max_unprotected_data_size(
71     const alts_iovec_record_protocol* rp, size_t max_protected_frame_size);
72 
73 /**
74  * This method performs integrity-only protect operation on a
75  * alts_iovec_record_protocol instance, i.e., compute frame header and tag. The
76  * caller needs to allocate the memory for header and tag prior to calling this
77  * method.
78  *
79  * - rp: an alts_iovec_record_protocol instance.
80  * - unprotected_vec: an iovec array containing unprotected data.
81  * - unprotected_vec_length: the array length of unprotected_vec.
82  * - header: an iovec containing the output frame header.
83  * - tag: an iovec containing the output frame tag.
84  * - error_details: a buffer containing an error message if the method does not
85  *   function correctly. It is OK to pass nullptr into error_details.
86  *
87  * On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
88  * error status code along with its details specified in error_details (if
89  * error_details is not nullptr).
90  */
91 grpc_status_code alts_iovec_record_protocol_integrity_only_protect(
92     alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
93     size_t unprotected_vec_length, iovec_t header, iovec_t tag,
94     char** error_details);
95 
96 /**
97  * This method performs integrity-only unprotect operation on a
98  * alts_iovec_record_protocol instance, i.e., verify frame header and tag.
99  *
100  * - rp: an alts_iovec_record_protocol instance.
101  * - protected_vec: an iovec array containing protected data.
102  * - protected_vec_length: the array length of protected_vec.
103  * - header: an iovec containing the frame header.
104  * - tag: an iovec containing the frame tag.
105  * - error_details: a buffer containing an error message if the method does not
106  *   function correctly. It is OK to pass nullptr into error_details.
107  *
108  * On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
109  * error status code along with its details specified in error_details (if
110  * error_details is not nullptr).
111  */
112 grpc_status_code alts_iovec_record_protocol_integrity_only_unprotect(
113     alts_iovec_record_protocol* rp, const iovec_t* protected_vec,
114     size_t protected_vec_length, iovec_t header, iovec_t tag,
115     char** error_details);
116 
117 /**
118  * This method performs privacy-integrity protect operation on a
119  * alts_iovec_record_protocol instance, i.e., compute a protected frame. The
120  * caller needs to allocate the memory for the protected frame prior to calling
121  * this method.
122  *
123  * - rp: an alts_iovec_record_protocol instance.
124  * - unprotected_vec: an iovec array containing unprotected data.
125  * - unprotected_vec_length: the array length of unprotected_vec.
126  * - protected_frame: an iovec containing the output protected frame.
127  * - error_details: a buffer containing an error message if the method does not
128  *   function correctly. It is OK to pass nullptr into error_details.
129  *
130  * On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
131  * error status code along with its details specified in error_details (if
132  * error_details is not nullptr).
133  */
134 grpc_status_code alts_iovec_record_protocol_privacy_integrity_protect(
135     alts_iovec_record_protocol* rp, const iovec_t* unprotected_vec,
136     size_t unprotected_vec_length, iovec_t protected_frame,
137     char** error_details);
138 
139 /**
140  * This method performs privacy-integrity unprotect operation on a
141  * alts_iovec_record_protocol instance given a full protected frame, i.e.,
142  * compute the unprotected data. The caller needs to allocated the memory for
143  * the unprotected data prior to calling this method.
144  *
145  * - rp: an alts_iovec_record_protocol instance.
146  * - header: an iovec containing the frame header.
147  * - protected_vec: an iovec array containing protected data including the tag.
148  * - protected_vec_length: the array length of protected_vec.
149  * - unprotected_data: an iovec containing the output unprotected data.
150  * - error_details: a buffer containing an error message if the method does not
151  *   function correctly. It is OK to pass nullptr into error_details.
152  *
153  * On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
154  * error status code along with its details specified in error_details (if
155  * error_details is not nullptr).
156  */
157 grpc_status_code alts_iovec_record_protocol_privacy_integrity_unprotect(
158     alts_iovec_record_protocol* rp, iovec_t header,
159     const iovec_t* protected_vec, size_t protected_vec_length,
160     iovec_t unprotected_data, char** error_details);
161 
162 /**
163  * This method creates an alts_iovec_record_protocol instance, given a
164  * gsec_aead_crypter instance, a flag indicating if the created instance will be
165  * used at the client or server side, and a flag indicating if the created
166  * instance will be used for integrity-only mode or privacy-integrity mode. The
167  * ownership of gsec_aead_crypter instance is transferred to this new object.
168  *
169  * - crypter: a gsec_aead_crypter instance used to perform AEAD decryption.
170  * - overflow_size: overflow size of counter in bytes.
171  * - is_client: a flag indicating if the alts_iovec_record_protocol instance
172  *   will be used at the client or server side.
173  * - is_integrity_only: a flag indicating if the alts_iovec_record_protocol
174  *   instance will be used for integrity-only or privacy-integrity mode.
175  * - is_protect: a flag indicating if the alts_grpc_record_protocol instance
176  *   will be used for protect or unprotect.
177  * - rp: an alts_iovec_record_protocol instance to be returned from
178  *   the method.
179  * - error_details: a buffer containing an error message if the method does not
180  *   function correctly. It is OK to pass nullptr into error_details.
181  *
182  * On success, the method returns GRPC_STATUS_OK. Otherwise, it returns an
183  * error status code along with its details specified in error_details (if
184  * error_details is not nullptr).
185  */
186 grpc_status_code alts_iovec_record_protocol_create(
187     gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
188     bool is_integrity_only, bool is_protect, alts_iovec_record_protocol** rp,
189     char** error_details);
190 
191 /**
192  * This method destroys an alts_iovec_record_protocol instance by de-allocating
193  * all of its occupied memory. A gsec_aead_crypter instance passed in at
194  * gsec_alts_crypter instance creation time will be destroyed in this method.
195  */
196 void alts_iovec_record_protocol_destroy(alts_iovec_record_protocol* rp);
197 
198 #endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_IOVEC_RECORD_PROTOCOL_H \
199         */
200