| /* |
| * |
| * 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. |
| * |
| */ |
| |
| #ifndef GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H |
| #define GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H |
| |
| #include <grpc/support/port_platform.h> |
| |
| #include <stdbool.h> |
| #include <string.h> |
| |
| #include <grpc/grpc.h> |
| |
| #include "src/core/tsi/alts/crypt/gsec.h" |
| |
| /** |
| * An alts_crypter interface for an ALTS record protocol providing |
| * seal/unseal functionality. The interface is thread-compatible. |
| */ |
| |
| typedef struct alts_crypter alts_crypter; |
| |
| /** |
| * A typical usage of the interface would be |
| *------------------------------------------------------------------------------ |
| * // Perform a seal operation. We assume the gsec_aead_crypter instance - |
| * // client_aead_crypter is created beforehand with a 16-byte key and 12-byte |
| * // nonce length. |
| * |
| * alts_crypter* client = nullptr; |
| * char* client_error_in_creation = nullptr; |
| * unsigned char* data = nullptr; |
| * grpc_status_code client_status = |
| * alts_seal_crypter_create(client_aead_crypter, 1, 5, &client, |
| * &client_error_in_creation); |
| * if (client_status == GRPC_STATUS_OK) { |
| * size_t data_size = 100; |
| * size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(client); |
| * size_t data_allocated_size = data_size + num_overhead_bytes; |
| * data = gpr_malloc(data_allocated_size); |
| * char* client_error_in_seal = nullptr; |
| * // Client performs a seal operation. |
| * client_status = alts_crypter_process_in_place(client, data, |
| * data_allocated_size, |
| * &data_size, |
| * &client_error_in_seal); |
| * if (client_status != GRPC_STATUS_OK) { |
| * fprintf(stderr, "seal operation failed with error code:" |
| * "%d, message: %s\n", client_status, |
| * client_error_in_seal); |
| * } |
| * gpr_free(client_error_in_seal); |
| * } else { |
| * fprintf(stderr, "alts_crypter instance creation failed with error" |
| * "code: %d, message: %s\n", client_status, |
| * client_error_in_creation); |
| * } |
| * |
| * ... |
| * |
| * gpr_free(client_error_in_creation); |
| * alts_crypter_destroy(client); |
| * |
| * ... |
| * |
| * // Perform an unseal operation. We assume the gsec_aead_crypter instance - |
| * // server_aead_crypter is created beforehand with a 16-byte key and 12-byte |
| * // nonce length. The key used in the creation of gsec_aead_crypter instances |
| * // at server and client sides should be identical. |
| * |
| * alts_crypter* server = nullptr; |
| * char* server_error_in_creation = nullptr; |
| * grpc_status_code server_status = |
| * alts_unseal_crypter_create(server_aead_crypter, 0, 5, &server, |
| * &server_error_in_creation); |
| * if (server_status == GRPC_STATUS_OK) { |
| * size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server); |
| * size_t data_size = 100 + num_overhead_bytes; |
| * size_t data_allocated_size = data_size; |
| * char* server_error_in_unseal = nullptr; |
| * // Server performs an unseal operation. |
| * server_status = alts_crypter_process_in_place(server, data, |
| * data_allocated_size, |
| * &data_size, |
| * &server_error_in_unseal); |
| * if (server_status != GRPC_STATUS_OK) { |
| * fprintf(stderr, "unseal operation failed with error code:" |
| * "%d, message: %s\n", server_status, |
| * server_error_in_unseal); |
| * } |
| * gpr_free(server_error_in_unseal); |
| * } else { |
| * fprintf(stderr, "alts_crypter instance creation failed with error" |
| * "code: %d, message: %s\n", server_status, |
| * server_error_in_creation); |
| * } |
| * |
| * ... |
| * |
| * gpr_free(data); |
| * gpr_free(server_error_in_creation); |
| * alts_crypter_destroy(server); |
| * |
| * ... |
| *------------------------------------------------------------------------------ |
| */ |
| |
| /* V-table for alts_crypter operations */ |
| typedef struct alts_crypter_vtable { |
| size_t (*num_overhead_bytes)(const alts_crypter* crypter); |
| grpc_status_code (*process_in_place)(alts_crypter* crypter, |
| unsigned char* data, |
| size_t data_allocated_size, |
| size_t data_size, size_t* output_size, |
| char** error_details); |
| void (*destruct)(alts_crypter* crypter); |
| } alts_crypter_vtable; |
| |
| /* Main struct for alts_crypter interface */ |
| struct alts_crypter { |
| const alts_crypter_vtable* vtable; |
| }; |
| |
| /** |
| * This method gets the number of overhead bytes needed for sealing data that |
| * is the difference in size between the protected and raw data. The counter |
| * value used in a seal or unseal operation is locally maintained (not sent or |
| * received from the other peer) and therefore, will not be counted as part of |
| * overhead bytes. |
| * |
| * - crypter: an alts_crypter instance. |
| * |
| * On success, the method returns the number of overhead bytes. Otherwise, it |
| * returns zero. |
| * |
| */ |
| size_t alts_crypter_num_overhead_bytes(const alts_crypter* crypter); |
| |
| /** |
| * This method performs either a seal or an unseal operation depending on the |
| * alts_crypter instance - crypter passed to the method. If the crypter is |
| * an instance implementing a seal operation, the method will perform a seal |
| * operation. That is, it seals raw data and stores the result in-place, and the |
| * memory allocated for data must be at least data_length + |
| * alts_crypter_num_overhead_bytes(). If the crypter is an instance |
| * implementing an unseal operation, the method will perform an unseal |
| * operation. That is, it unseals protected data and stores the result in-place. |
| * The size of unsealed data will be data_length - |
| * alts_crypter_num_overhead_bytes(). Integrity tag will be verified during |
| * the unseal operation, and if verification fails, the data will be wiped. |
| * The counters used in both seal and unseal operations are managed internally. |
| * |
| * - crypter: an alts_crypter instance. |
| * - data: if the method performs a seal operation, the data represents raw data |
| * that needs to be sealed. It also plays the role of buffer to hold the |
| * protected data as a result of seal. If the method performs an unseal |
| * operation, the data represents protected data that needs to be unsealed. It |
| * also plays the role of buffer to hold raw data as a result of unseal. |
| * - data_allocated_size: the size of data buffer. The parameter is used to |
| * check whether the result of either seal or unseal can be safely written to |
| * the data buffer. |
| * - data_size: if the method performs a seal operation, data_size |
| * represents the size of raw data that needs to be sealed, and if the method |
| * performs an unseal operation, data_size represents the size of protected |
| * data that needs to be unsealed. |
| * - output_size: size of data written to the data buffer after a seal or an |
| * unseal operation. |
| * - error_details: a buffer containing an error message if the method does not |
| * function correctly. It is legal to pass nullptr into error_details and |
| * otherwise, the parameter should be freed with gpr_free. |
| * |
| * On success, the method returns GRPC_STATUS_OK. Otherwise, |
| * it returns an error status code along with its details specified in |
| * error_details (if error_details is not nullptr). |
| */ |
| grpc_status_code alts_crypter_process_in_place( |
| alts_crypter* crypter, unsigned char* data, size_t data_allocated_size, |
| size_t data_size, size_t* output_size, char** error_details); |
| |
| /** |
| * This method creates an alts_crypter instance to be used to perform a seal |
| * operation, given a gsec_aead_crypter instance and a flag indicating if the |
| * created instance will be used at the client or server side. It takes |
| * ownership of gsec_aead_crypter instance. |
| * |
| * - gc: a gsec_aead_crypter instance used to perform AEAD encryption. |
| * - is_client: a flag indicating if the alts_crypter instance will be |
| * used at the client (is_client = true) or server (is_client = |
| * false) side. |
| * - overflow_size: overflow size of counter in bytes. |
| * - crypter: an alts_crypter instance to be returned from the method. |
| * - error_details: a buffer containing an error message if the method does |
| * not function correctly. It is legal to pass nullptr into error_details, and |
| * otherwise, the parameter should be freed with gpr_free. |
| * |
| * On success of creation, the method returns GRPC_STATUS_OK. |
| * Otherwise, it returns an error status code along with its details specified |
| * in error_details (if error_details is not nullptr). |
| */ |
| grpc_status_code alts_seal_crypter_create(gsec_aead_crypter* gc, bool is_client, |
| size_t overflow_size, |
| alts_crypter** crypter, |
| char** error_details); |
| |
| /** |
| * This method creates an alts_crypter instance used to perform an unseal |
| * operation, given a gsec_aead_crypter instance and a flag indicating if the |
| * created instance will be used at the client or server side. It takes |
| * ownership of gsec_aead_crypter instance. |
| * |
| * - gc: a gsec_aead_crypter instance used to perform AEAD decryption. |
| * - is_client: a flag indicating if the alts_crypter instance will be |
| * used at the client (is_client = true) or server (is_client = |
| * false) side. |
| * - overflow_size: overflow size of counter in bytes. |
| * - crypter: an alts_crypter instance to be returned from the method. |
| * - error_details: a buffer containing an error message if the method does |
| * not function correctly. It is legal to pass nullptr into error_details, and |
| * otherwise, the parameter should be freed with gpr_free. |
| * |
| * On success of creation, the method returns GRPC_STATUS_OK. |
| * Otherwise, it returns an error status code along with its details specified |
| * in error_details (if error_details is not nullptr). |
| */ |
| grpc_status_code alts_unseal_crypter_create(gsec_aead_crypter* gc, |
| bool is_client, |
| size_t overflow_size, |
| alts_crypter** crypter, |
| char** error_details); |
| |
| /** |
| * This method destroys an alts_crypter instance by de-allocating all of its |
| * occupied memory. A gsec_aead_crypter instance passed in at alts_crypter |
| * instance creation time will be destroyed in this method. |
| * |
| * - crypter: an alts_crypter instance. |
| */ |
| void alts_crypter_destroy(alts_crypter* crypter); |
| |
| #endif /* GRPC_CORE_TSI_ALTS_FRAME_PROTECTOR_ALTS_CRYPTER_H */ |