diff options
author | ncteisen <ncteisen@gmail.com> | 2018-03-07 10:17:15 -0800 |
---|---|---|
committer | ncteisen <ncteisen@gmail.com> | 2018-03-07 10:17:15 -0800 |
commit | 0c6024b94dc2a8aa9d851d8bc5d3a96e97802a55 (patch) | |
tree | 48f83f5393a4c66fb944d5317ee8639b8ba00bca /src/core/tsi/alts/frame_protector/alts_crypter.h | |
parent | d2365d615aa0b8c18d88997ff26ae145844a4d4e (diff) | |
parent | 4135ef7012ecac32f03a8a1ca76f20098fcd016c (diff) |
Merge branch 'master' of https://github.com/grpc/grpc into channel-tracing
Diffstat (limited to 'src/core/tsi/alts/frame_protector/alts_crypter.h')
-rw-r--r-- | src/core/tsi/alts/frame_protector/alts_crypter.h | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/core/tsi/alts/frame_protector/alts_crypter.h b/src/core/tsi/alts/frame_protector/alts_crypter.h new file mode 100644 index 0000000000..3140778f4f --- /dev/null +++ b/src/core/tsi/alts/frame_protector/alts_crypter.h @@ -0,0 +1,255 @@ +/* + * + * 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 */ |